From 938609818fb459cca1825b8f964b52f9f38c2e74 Mon Sep 17 00:00:00 2001
From: byuu <byuu@byuu.org>
Date: Tue, 7 Dec 2004 01:12:32 +0000
Subject: [PATCH] Update to bsnes v002 ir9 release.

[No changelog available]
---
 bsnes/Makefile                  |   34 +
 bsnes/base.h                    |  332 ++++++++
 bsnes/bsnes.exe                 |  Bin 0 -> 233472 bytes
 bsnes/cc.bat                    |    2 +
 bsnes/clean.bat                 |    1 +
 bsnes/cpu/d65816.cpp            |  337 ++++++++
 bsnes/cpu/g65816.cpp            |  234 ++++++
 bsnes/cpu/g65816.h              |   69 ++
 bsnes/cpu/g65816_ops.cpp        |  161 ++++
 bsnes/cpu/g65816_ops_adc.cpp    |  345 ++++++++
 bsnes/cpu/g65816_ops_and.cpp    |  335 ++++++++
 bsnes/cpu/g65816_ops_cmp.cpp    |  321 ++++++++
 bsnes/cpu/g65816_ops_eor.cpp    |  335 ++++++++
 bsnes/cpu/g65816_ops_incdec.cpp |  355 +++++++++
 bsnes/cpu/g65816_ops_lda.cpp    |  335 ++++++++
 bsnes/cpu/g65816_ops_misc.cpp   | 1294 +++++++++++++++++++++++++++++++
 bsnes/cpu/g65816_ops_ora.cpp    |  335 ++++++++
 bsnes/cpu/g65816_ops_pc.cpp     |  223 ++++++
 bsnes/cpu/g65816_ops_sbc.cpp    |  345 ++++++++
 bsnes/cpu/g65816_ops_shift.cpp  |  595 ++++++++++++++
 bsnes/cpu/g65816_ops_sta.cpp    |  288 +++++++
 bsnes/cpu/g65816_ops_stack.cpp  |  243 ++++++
 bsnes/d65816.obj                |  Bin 0 -> 84902 bytes
 bsnes/demo.smc                  |  Bin 0 -> 131584 bytes
 bsnes/demo.srm                  |  Bin 0 -> 8192 bytes
 bsnes/demo_mode1.smc            |  Bin 0 -> 131584 bytes
 bsnes/demo_mode1.srm            |  Bin 0 -> 8192 bytes
 bsnes/demo_mode4.smc            |  Bin 0 -> 131584 bytes
 bsnes/demo_mode4.srm            |  Bin 0 -> 8192 bytes
 bsnes/g65816.obj                |  Bin 0 -> 289767 bytes
 bsnes/gui.obj                   |  Bin 0 -> 67128 bytes
 bsnes/libstr.obj                |  Bin 0 -> 38996 bytes
 bsnes/main.cpp                  |   97 +++
 bsnes/main.h                    |   34 +
 bsnes/main.obj                  |  Bin 0 -> 11653 bytes
 bsnes/mem/memory.cpp            |  516 ++++++++++++
 bsnes/memory.obj                |  Bin 0 -> 11196 bytes
 bsnes/misc/libstr.cpp           |  393 ++++++++++
 bsnes/misc/libstr_math.cpp      |  181 +++++
 bsnes/misc/libstr_replace.cpp   |   82 ++
 bsnes/misc/libstr_split.cpp     |   41 +
 bsnes/misc/libstr_sprintf.cpp   |  130 ++++
 bsnes/misc/libvlist.cpp         |   55 ++
 bsnes/mmio.obj                  |  Bin 0 -> 81207 bytes
 bsnes/ppu/mmio.cpp              |  198 +++++
 bsnes/ppu/ppu.cpp               |  476 ++++++++++++
 bsnes/ppu/ppu_addsub.cpp        |   60 ++
 bsnes/ppu/ppu_cache.cpp         |   49 ++
 bsnes/ppu/ppu_dma.cpp           |  485 ++++++++++++
 bsnes/ppu/ppu_joypad.cpp        |   67 ++
 bsnes/ppu/ppu_misc.cpp          |   15 +
 bsnes/ppu/ppu_mode7.cpp         |   74 ++
 bsnes/ppu/ppu_muldiv.cpp        |   57 ++
 bsnes/ppu/ppu_oam.cpp           |   86 ++
 bsnes/ppu/ppu_palette.cpp       |   36 +
 bsnes/ppu/ppu_render.cpp        |  753 ++++++++++++++++++
 bsnes/ppu/ppu_render_mode7f.cpp |   74 ++
 bsnes/ppu/ppu_render_mode7i.cpp |   66 ++
 bsnes/ppu/ppu_screen.cpp        |   92 +++
 bsnes/ppu/ppu_scroll.cpp        |   46 ++
 bsnes/ppu/ppu_timing.cpp        |  160 ++++
 bsnes/ppu/ppu_vram.cpp          |  131 ++++
 bsnes/ppu/ppu_window.cpp        |  121 +++
 bsnes/ppu/ppu_wram.cpp          |   24 +
 bsnes/qc.bat                    |    3 +
 bsnes/timing.obj                |  Bin 0 -> 3162 bytes
 bsnes/timing/timing.cpp         |  103 +++
 bsnes/timing/timing.h           |   23 +
 bsnes/win/gui.cpp               |  434 +++++++++++
 bsnes/win/gui_bgtoggle.cpp      |  149 ++++
 bsnes/win/gui_bp.cpp            |  131 ++++
 bsnes/win/gui_cpu.cpp           |  208 +++++
 bsnes/win/gui_mem.cpp           |  252 ++++++
 bsnes/win/render.cpp            |  269 +++++++
 bsnes/win/render_modes.cpp      |  303 ++++++++
 75 files changed, 12993 insertions(+)
 create mode 100644 bsnes/Makefile
 create mode 100644 bsnes/base.h
 create mode 100644 bsnes/bsnes.exe
 create mode 100644 bsnes/cc.bat
 create mode 100644 bsnes/clean.bat
 create mode 100644 bsnes/cpu/d65816.cpp
 create mode 100644 bsnes/cpu/g65816.cpp
 create mode 100644 bsnes/cpu/g65816.h
 create mode 100644 bsnes/cpu/g65816_ops.cpp
 create mode 100644 bsnes/cpu/g65816_ops_adc.cpp
 create mode 100644 bsnes/cpu/g65816_ops_and.cpp
 create mode 100644 bsnes/cpu/g65816_ops_cmp.cpp
 create mode 100644 bsnes/cpu/g65816_ops_eor.cpp
 create mode 100644 bsnes/cpu/g65816_ops_incdec.cpp
 create mode 100644 bsnes/cpu/g65816_ops_lda.cpp
 create mode 100644 bsnes/cpu/g65816_ops_misc.cpp
 create mode 100644 bsnes/cpu/g65816_ops_ora.cpp
 create mode 100644 bsnes/cpu/g65816_ops_pc.cpp
 create mode 100644 bsnes/cpu/g65816_ops_sbc.cpp
 create mode 100644 bsnes/cpu/g65816_ops_shift.cpp
 create mode 100644 bsnes/cpu/g65816_ops_sta.cpp
 create mode 100644 bsnes/cpu/g65816_ops_stack.cpp
 create mode 100644 bsnes/d65816.obj
 create mode 100644 bsnes/demo.smc
 create mode 100644 bsnes/demo.srm
 create mode 100644 bsnes/demo_mode1.smc
 create mode 100644 bsnes/demo_mode1.srm
 create mode 100644 bsnes/demo_mode4.smc
 create mode 100644 bsnes/demo_mode4.srm
 create mode 100644 bsnes/g65816.obj
 create mode 100644 bsnes/gui.obj
 create mode 100644 bsnes/libstr.obj
 create mode 100644 bsnes/main.cpp
 create mode 100644 bsnes/main.h
 create mode 100644 bsnes/main.obj
 create mode 100644 bsnes/mem/memory.cpp
 create mode 100644 bsnes/memory.obj
 create mode 100644 bsnes/misc/libstr.cpp
 create mode 100644 bsnes/misc/libstr_math.cpp
 create mode 100644 bsnes/misc/libstr_replace.cpp
 create mode 100644 bsnes/misc/libstr_split.cpp
 create mode 100644 bsnes/misc/libstr_sprintf.cpp
 create mode 100644 bsnes/misc/libvlist.cpp
 create mode 100644 bsnes/mmio.obj
 create mode 100644 bsnes/ppu/mmio.cpp
 create mode 100644 bsnes/ppu/ppu.cpp
 create mode 100644 bsnes/ppu/ppu_addsub.cpp
 create mode 100644 bsnes/ppu/ppu_cache.cpp
 create mode 100644 bsnes/ppu/ppu_dma.cpp
 create mode 100644 bsnes/ppu/ppu_joypad.cpp
 create mode 100644 bsnes/ppu/ppu_misc.cpp
 create mode 100644 bsnes/ppu/ppu_mode7.cpp
 create mode 100644 bsnes/ppu/ppu_muldiv.cpp
 create mode 100644 bsnes/ppu/ppu_oam.cpp
 create mode 100644 bsnes/ppu/ppu_palette.cpp
 create mode 100644 bsnes/ppu/ppu_render.cpp
 create mode 100644 bsnes/ppu/ppu_render_mode7f.cpp
 create mode 100644 bsnes/ppu/ppu_render_mode7i.cpp
 create mode 100644 bsnes/ppu/ppu_screen.cpp
 create mode 100644 bsnes/ppu/ppu_scroll.cpp
 create mode 100644 bsnes/ppu/ppu_timing.cpp
 create mode 100644 bsnes/ppu/ppu_vram.cpp
 create mode 100644 bsnes/ppu/ppu_window.cpp
 create mode 100644 bsnes/ppu/ppu_wram.cpp
 create mode 100644 bsnes/qc.bat
 create mode 100644 bsnes/timing.obj
 create mode 100644 bsnes/timing/timing.cpp
 create mode 100644 bsnes/timing/timing.h
 create mode 100644 bsnes/win/gui.cpp
 create mode 100644 bsnes/win/gui_bgtoggle.cpp
 create mode 100644 bsnes/win/gui_bp.cpp
 create mode 100644 bsnes/win/gui_cpu.cpp
 create mode 100644 bsnes/win/gui_mem.cpp
 create mode 100644 bsnes/win/render.cpp
 create mode 100644 bsnes/win/render_modes.cpp

diff --git a/bsnes/Makefile b/bsnes/Makefile
new file mode 100644
index 00000000..c037c5e1
--- /dev/null
+++ b/bsnes/Makefile
@@ -0,0 +1,34 @@
+CC = cl
+CFLAGS = /nologo /O2
+OBJS = main.obj timing.obj g65816.obj d65816.obj memory.obj mmio.obj gui.obj libstr.obj
+LIBS = kernel32.lib user32.lib gdi32.lib comdlg32.lib ddraw.lib
+
+all: $(OBJS)
+	$(CC) /Febsnes.exe $(CFLAGS) $(OBJS) $(LIBS)
+
+clean:
+	del *.obj
+
+main.obj: main.cpp main.h
+	$(CC) $(CFLAGS) /c main.cpp
+
+timing.obj: timing/timing.cpp timing/timing.h
+	$(CC) $(CFLAGS) /c timing/timing.cpp
+
+g65816.obj: cpu/g65816*.cpp cpu/g65816.h
+	$(CC) $(CFLAGS) /c cpu/g65816.cpp
+
+d65816.obj: cpu/d65816.cpp
+	$(CC) $(CFLAGS) /c cpu/d65816.cpp
+
+memory.obj: mem/memory.cpp
+	$(CC) $(CFLAGS) /c mem/memory.cpp
+
+mmio.obj: ppu/mmio.cpp ppu/ppu*.cpp
+	$(CC) $(CFLAGS) /c ppu/mmio.cpp
+
+gui.obj: win/gui*.cpp win/render*.cpp
+	$(CC) $(CFLAGS) /c win/gui.cpp
+
+libstr.obj: misc/libstr.cpp
+	$(CC) $(CFLAGS) /c misc/libstr.cpp
diff --git a/bsnes/base.h b/bsnes/base.h
new file mode 100644
index 00000000..32dbfd6a
--- /dev/null
+++ b/bsnes/base.h
@@ -0,0 +1,332 @@
+//#define PUBLIC_DOMAIN
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define null 0xffffffff
+typedef unsigned char  byte;
+typedef unsigned short word;
+typedef unsigned long  ulong;
+typedef void (*vfunc)(void);
+
+#define SH_2   1
+#define SH_4   2
+#define SH_8   3
+#define SH_16  4
+#define SH_32  5
+#define SH_64  6
+#define SH_128 7
+#define SH_256 8
+
+/*************************
+ *** general functions ***
+ ************************/
+
+void alert(char *s, ...);
+
+/************************
+ *** joypad functions ***
+ ***********************/
+
+void UpdateJoypad(void);
+
+typedef struct {
+  byte a, b, x, y;
+  byte l, r;
+  byte select, start;
+  byte up, down, left, right;
+
+  byte read_pos;
+}joypad_state;
+
+/******************
+ *** deprecated ***
+ *****************/
+
+typedef struct {
+  char  rom_name[4096], sram_name[4096];
+  ulong sram_save_tick_count;
+}emustate;
+
+/***********************
+ *** video functions ***
+ **********************/
+
+void video_setmode(bool fullscreen, word width, word height);
+void video_setsnesmode(void);
+
+//global export: render
+typedef struct {
+  word  width, height;
+  word  snes_width, snes_height;
+  bool  fullscreen;
+  bool  show_menu;
+
+  byte  frame_skip;
+  byte  frame_count;
+
+  bool  bg1_enabled[3], bg2_enabled[3], bg3_enabled[3], bg4_enabled[3], oam_enabled[5];
+}videostate;
+
+/***************************
+ *** debugging functions ***
+ **************************/
+
+#define DEBUGMODE_NOROM      0
+#define DEBUGMODE_DISABLED   1
+#define DEBUGMODE_WAIT       2
+#define DEBUGMODE_RUN        3
+#define DEBUGMODE_STEP       4
+#define DEBUGMODE_PROCEED    5
+
+#define DEBUG_BGENABLED_ALL  0
+#define DEBUG_BGENABLED_PRI0 1
+#define DEBUG_BGENABLED_PRI1 2
+#define DEBUG_BGENABLED_PRI2 3
+#define DEBUG_BGENABLED_PRI3 4
+
+void debug_set_state(byte state);
+#define debug_get_state() debugger.mode
+void dprintf(char *s, ...);
+void debug_refresh_mem(void);
+void debug_refresh_bp(void);
+void debug_update_cycles(void);
+
+typedef struct {
+  byte mode;
+
+  bool  trace_enabled;
+  ulong mem_ptr;     //position of wram ptr for debug window
+  bool  disas_op;
+  bool  refresh_mem;
+  bool  refresh_bp;
+
+  FILE *trace_fp;
+}debugstate;
+
+/*********************
+ *** ppu functions ***
+ ********************/
+
+#define BG1     0x00
+#define BG2     0x01
+#define BG3     0x02
+#define BG4     0x03
+#define OAM     0x04
+#define SS_BG1  0x80
+#define SS_BG2  0x81
+#define SS_BG3  0x82
+#define SS_BG4  0x83
+#define SS_OAM  0x84
+#define BACK    0x05
+
+#define CLIPMODE_IN  0
+#define CLIPMODE_OUT 1
+
+#define WINDOWMASK_OR   0
+#define WINDOWMASK_AND  1
+#define WINDOWMASK_XOR  2
+#define WINDOWMASK_XNOR 3
+
+#define COLORMODE_ADD 0
+#define COLORMODE_SUB 1
+
+typedef struct {
+  word *screen;            //internal buffer used to render 512x448 screen
+  byte *vram;              //65536 bytes
+  byte *cgram;             //512 bytes
+  byte *oam;               //544 bytes mirrored as 1024 bytes (512-543 are mirrored to 544-1023)
+  word *light_table;       //16 * 32768 -- applies display_brightness to bgr555 color data
+//ppu.mosaic_table[ppu.mosaic_size][x] == (x / (ppu.mosaic_size + 1)) * (ppu.mosaic_size + 1)
+  word *mosaic_table[16];
+
+  ulong ppu_cycles, ppu_prev_cycles; //used in ppu_update_scanline()
+
+  bool display_disable;    //$2100 bit 7
+  byte display_brightness; //$2100 bits 0-3
+
+  byte visible_scanlines;  //$2133 bit 2 (NTSC/PAL mode) -- value = 224 or 240
+  byte toggle_visible_scanlines; //do not allow change midframe
+
+  bool interlace;
+  byte interlace_frame;    //0 or 1, used to alternate between scanlines rendered
+
+  bool bg_enabled[5];
+  bool ss_bg_enabled[5];
+  byte mosaic_size;
+  bool mosaic_enabled[4];
+  word bg_tilemap_loc[4];
+  byte bg_tile_size[4];
+  byte bg_tilemap_size[4];
+  word bg_tiledata_loc[4];
+  word oam_tiledata_loc;
+  byte bg_priority_mode;
+  byte oam_base_size;
+  byte oam_name_sel;
+  byte bg_mode;
+
+  word hline_pos;          //0-255: inside vblank, 256-339: outside vblank
+  word vline_pos;          //0-223: inside vblank, 224-261: outside vblank, 180 cycles/scanline
+  bool irq_triggered;      //for $4211 read
+  bool virq_triggered;     //prevent recursive calling
+  bool hirq_triggered;     //prevent recursive calling
+  word vram_write_pos;     //holds value at $2116
+  word vram_inc_size;      //amount to increment vram_write_pos by
+  byte vram_inc_reg;       //increment on 2118 (0) or 2119 (1)
+  word cgram_write_pos;    //holds value at $2121 (multiplied by 2)
+  word oam_write_pos;      //holds value at $2102/$2103 (multiplied by 2)
+  ulong wram_write_pos;    //holds value at $2181-$2183
+
+  word bg_hscroll_pos[4];  //$210d-$2114
+  word bg_vscroll_pos[4];
+  word m7hofs, m7vofs;
+
+  byte mul_a, mul_b;
+  word div_a;
+  byte div_b;
+  word r_4214, r_4216;
+
+  word  smul_a;
+  byte  smul_b;
+  ulong smul_r;
+
+  bool bg_window1_enabled[5];
+  bool bg_window2_enabled[5];
+  byte bg_window1_clipmode[5];
+  byte bg_window2_clipmode[5];
+
+  byte window1_left, window1_right;
+  byte window2_left, window2_right;
+
+  bool bg_windowing_enabled[5];
+  bool ss_bg_windowing_enabled[5];
+  byte bg_window_mask[5];
+
+  bool color_window1_enabled,  color_window2_enabled;
+  bool color_window1_clipmode, color_window2_clipmode;
+  byte color_window_mask;
+  byte color_mask, ss_color_mask;
+  byte addsub_mode;
+  byte color_mode, color_halve;
+  bool bg_color_enabled[6];
+  byte color_r, color_g, color_b;
+
+  byte toggle_active_hdma_channels;
+  byte active_hdma_channels;
+  word hdma_scanlines_remaining[8];
+  word hdma_index_pointer[8];
+  bool hdma_completed[8];
+
+  bool vcounter_enabled, hcounter_enabled;
+  word hirq_pos, virq_pos;
+
+  bool auto_joypad_read;
+  byte joypad_strobe_value;
+
+  byte latch_toggle;
+  word latch_vpos, latch_hpos;
+
+  word m7a, m7b, m7c, m7d, m7x, m7y;
+
+  bool mode7_vflip, mode7_hflip;
+}ppustate;
+
+/*********************
+ *** cpu functions ***
+ ********************/
+
+#define MEMSPEED_SLOWROM 0
+#define MEMSPEED_FASTROM 1
+
+#define PF_N 0x80
+#define PF_V 0x40
+#define PF_M 0x20
+#define PF_X 0x10
+#define PF_D 0x08
+#define PF_I 0x04
+#define PF_Z 0x02
+#define PF_C 0x01
+
+#define BP_OFF   0
+#define BP_READ  1
+#define BP_WRITE 2
+#define BP_EXEC  4
+#define BP_VAL   8
+
+/************************
+ *** memory functions ***
+ ***********************/
+
+#define MEMMAP_HIROM 0x01
+#define MEMMAP_LOROM 0x02
+
+#define MEMACCESS_NORMAL   0
+#define MEMACCESS_CPU      1
+#define MEMACCESS_DEBUGGER 1
+
+enum {
+  MEMMODE_NONE = 0,  //(no address translation)
+  MEMMODE_DP,        //dp
+  MEMMODE_DPX,       //dp,x
+  MEMMODE_DPY,       //dp,y
+  MEMMODE_IDP,       //(dp)
+  MEMMODE_IDPX,      //(dp,x)
+  MEMMODE_IDPY,      //(dp),y
+  MEMMODE_ILDP,      //[dp]
+  MEMMODE_ILDPY,     //[dp],y
+  MEMMODE_ADDR,      //addr
+  MEMMODE_ADDRX,     //addr,x
+  MEMMODE_ADDRY,     //addr,y
+  MEMMODE_IADDRX,    //(addr,x)
+  MEMMODE_ILADDR,    //[addr]
+  MEMMODE_LONG,      //long
+  MEMMODE_LONGX,     //long, x
+  MEMMODE_SR,        //sr,s
+  MEMMODE_ISRY,      //(sr,s),y
+//exchanges pbr for dbr, disables address mirroring
+  MEMMODE_ADDR_PC,   //addr
+  MEMMODE_IADDR_PC,  //(addr)
+  MEMMODE_IADDRX_PC, //(addr,x)
+  MEMMODE_ILADDR_PC  //[addr]
+};
+
+#define MEMSIZE_BYTE 1
+#define MEMSIZE_WORD 2
+#define MEMSIZE_LONG 3
+
+/***********************
+ *** misc. functions ***
+ **********************/
+
+//main.cpp
+void InitSNES(void);
+extern vfunc RunSNES;
+void RunSNES_NoDebug(void);
+void RunSNES_Debug(void);
+
+//cpu/g65816_ops_stack.cpp
+ulong g65816_stackread(byte size);
+void g65816_stackwrite(byte size, ulong value);
+
+//cpu/d65816.cpp
+void disas_g65816_op(void);
+
+//ppu/mmio.cpp
+byte mmio_read(word addr);
+void mmio_write(word addr, byte value);
+
+//ppu/ppu.cpp
+void ppu_render_scanline(void);
+void ppu_update_scanline(void);
+byte oam_read(word addr);
+void oam_write(word addr, byte value);
+void PPUInit(byte first_time);
+
+//win/render.cpp
+void UpdateDisplay(void);
+
+//misc/libstr.cpp
+ulong strhex(char *str);
+ulong strdec(char *str);
diff --git a/bsnes/bsnes.exe b/bsnes/bsnes.exe
new file mode 100644
index 0000000000000000000000000000000000000000..551d2a4a9a340a95fe3d19ca462e13ae619e0f61
GIT binary patch
literal 233472
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

literal 0
HcmV?d00001

diff --git a/bsnes/cc.bat b/bsnes/cc.bat
new file mode 100644
index 00000000..5a1afd6a
--- /dev/null
+++ b/bsnes/cc.bat
@@ -0,0 +1,2 @@
+@nmake /NOLOGO
+@pause
\ No newline at end of file
diff --git a/bsnes/clean.bat b/bsnes/clean.bat
new file mode 100644
index 00000000..02d7e1df
--- /dev/null
+++ b/bsnes/clean.bat
@@ -0,0 +1 @@
+@nmake /NOLOGO clean
\ No newline at end of file
diff --git a/bsnes/cpu/d65816.cpp b/bsnes/cpu/d65816.cpp
new file mode 100644
index 00000000..35f12cf2
--- /dev/null
+++ b/bsnes/cpu/d65816.cpp
@@ -0,0 +1,337 @@
+#include "../base.h"
+#include "g65816.h"
+extern g65816 *gx816;
+
+ulong _disas_relb(byte addr) {
+  return gx816->regs.pc + (signed char)(addr + 2);
+}
+
+ulong _disas_relw(word addr) {
+  return gx816->regs.pc + (signed short)(addr + 3);
+}
+
+char __disas_op_str[256];
+void __disas_op(byte op, byte op0, byte op1, byte op2) {
+char *s = (char*)__disas_op_str;
+  switch(op) {
+  case 0x00:sprintf(s, "brk #$%0.2x               ", op0);break;
+  case 0x01:sprintf(s, "ora ($%0.2x,x)   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
+  case 0x02:sprintf(s, "cop #$%0.2x               ", op0);break;
+  case 0x03:sprintf(s, "ora $%0.2x,s     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
+  case 0x04:sprintf(s, "tsb $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x05:sprintf(s, "ora $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x06:sprintf(s, "asl $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x07:sprintf(s, "ora [$%0.2x]     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
+  case 0x08:sprintf(s, "php                    ");break;
+  case 0x09:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "ora #$%0.2x               ", op0);
+    else sprintf(s, "ora #$%0.4x             ", op0|op1<<8);break;
+  case 0x0a:sprintf(s, "asl a                  ");break;
+  case 0x0b:sprintf(s, "phd                    ");break;
+  case 0x0c:sprintf(s, "tsb $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x0d:sprintf(s, "ora $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x0e:sprintf(s, "asl $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x0f:sprintf(s, "ora $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0x10:sprintf(s, "bpl $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0x11:sprintf(s, "ora ($%0.2x),y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
+  case 0x12:sprintf(s, "ora ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0x13:sprintf(s, "ora ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
+  case 0x14:sprintf(s, "trb $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x15:sprintf(s, "ora $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x16:sprintf(s, "asl $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x17:sprintf(s, "ora [$%0.2x],y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
+  case 0x18:sprintf(s, "clc                    ");break;
+  case 0x19:sprintf(s, "ora $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0x1a:sprintf(s, "inc                    ");break;
+  case 0x1b:sprintf(s, "tcs                    ");break;
+  case 0x1c:sprintf(s, "trb $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x1d:sprintf(s, "ora $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x1e:sprintf(s, "asl $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x1f:sprintf(s, "ora $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
+  case 0x20:sprintf(s, "jsr $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR_PC, (op0|op1<<8)));break;
+  case 0x21:sprintf(s, "and ($%0.2x,x)   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
+  case 0x22:sprintf(s, "jsl $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0x23:sprintf(s, "and $%0.2x,s     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
+  case 0x24:sprintf(s, "bit $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x25:sprintf(s, "and $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x26:sprintf(s, "rol $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x27:sprintf(s, "and [$%0.2x]     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
+  case 0x28:sprintf(s, "plp                    ");break;
+  case 0x29:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "and #$%0.2x               ", op0);
+    else sprintf(s, "and #$%0.4x             ", op0|op1<<8);break;
+  case 0x2a:sprintf(s, "rol a                  ");break;
+  case 0x2b:sprintf(s, "pld                    ");break;
+  case 0x2c:sprintf(s, "bit $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x2d:sprintf(s, "and $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x2e:sprintf(s, "rol $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x2f:sprintf(s, "and $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0x30:sprintf(s, "bmi $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0x31:sprintf(s, "and ($%0.2x),y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
+  case 0x32:sprintf(s, "and ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0x33:sprintf(s, "and ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
+  case 0x34:sprintf(s, "bit $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x35:sprintf(s, "and $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x36:sprintf(s, "rol $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x37:sprintf(s, "and [$%0.2x],y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
+  case 0x38:sprintf(s, "sec                    ");break;
+  case 0x39:sprintf(s, "and $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0x3a:sprintf(s, "dec                    ");break;
+  case 0x3b:sprintf(s, "tsc                    ");break;
+  case 0x3c:sprintf(s, "bit $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x3d:sprintf(s, "and $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x3e:sprintf(s, "rol $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x3f:sprintf(s, "and $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
+  case 0x40:sprintf(s, "rti                    ");break;
+  case 0x41:sprintf(s, "eor ($%0.2x,x)   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
+  case 0x42:sprintf(s, "wdm                    ");break;
+  case 0x43:sprintf(s, "eor $%0.2x,s     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
+  case 0x44:sprintf(s, "mvp $%0.2x,$%0.2x            ", op1, op0);break;
+  case 0x45:sprintf(s, "eor $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x46:sprintf(s, "lsr $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x47:sprintf(s, "eor [$%0.2x]     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
+  case 0x48:sprintf(s, "pha                    ");break;
+  case 0x49:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "eor #$%0.2x               ", op0);
+    else sprintf(s, "eor #$%0.4x             ", op0|op1<<8);break;
+  case 0x4a:sprintf(s, "lsr a                  ");break;
+  case 0x4b:sprintf(s, "phk                    ");break;
+  case 0x4c:sprintf(s, "jmp $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR_PC, (op0|op1<<8)));break;
+  case 0x4d:sprintf(s, "eor $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x4e:sprintf(s, "lsr $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x4f:sprintf(s, "eor $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0x50:sprintf(s, "bvc $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0x51:sprintf(s, "eor ($%0.2x),y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
+  case 0x52:sprintf(s, "eor ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0x53:sprintf(s, "eor ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
+  case 0x54:sprintf(s, "mvn $%0.2x,$%0.2x            ", op1, op0);break;
+  case 0x55:sprintf(s, "eor $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x56:sprintf(s, "lsr $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x57:sprintf(s, "eor [$%0.2x],y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
+  case 0x58:sprintf(s, "cli                    ");break;
+  case 0x59:sprintf(s, "eor $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0x5a:sprintf(s, "phy                    ");break;
+  case 0x5b:sprintf(s, "tcd                    ");break;
+  case 0x5c:sprintf(s, "jml $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0x5d:sprintf(s, "eor $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x5e:sprintf(s, "lsr $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x5f:sprintf(s, "eor $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
+  case 0x60:sprintf(s, "rts                    ");break;
+  case 0x61:sprintf(s, "adc ($%0.2x,x)   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
+  case 0x62:sprintf(s, "per $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x63:sprintf(s, "adc $%0.2x,s     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
+  case 0x64:sprintf(s, "stz $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x65:sprintf(s, "adc $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x66:sprintf(s, "ror $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x67:sprintf(s, "adc [$%0.2x]     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
+  case 0x68:sprintf(s, "pla                    ");break;
+  case 0x69:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "adc #$%0.2x               ", op0);
+    else sprintf(s, "adc #$%0.4x             ", op0|op1<<8);break;
+  case 0x6a:sprintf(s, "ror a                  ");break;
+  case 0x6b:sprintf(s, "rtl                    ");break;
+  case 0x6c:sprintf(s, "jmp ($%0.4x)   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDR_PC, (op0|op1<<8)));break;
+  case 0x6d:sprintf(s, "adc $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x6e:sprintf(s, "ror $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x6f:sprintf(s, "adc $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0x70:sprintf(s, "bvs $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0x71:sprintf(s, "adc ($%0.2x),y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
+  case 0x72:sprintf(s, "adc ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0x73:sprintf(s, "adc ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
+  case 0x74:sprintf(s, "stz $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x75:sprintf(s, "adc $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x76:sprintf(s, "ror $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x77:sprintf(s, "adc [$%0.2x],y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
+  case 0x78:sprintf(s, "sei                    ");break;
+  case 0x79:sprintf(s, "adc $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0x7a:sprintf(s, "ply                    ");break;
+  case 0x7b:sprintf(s, "tdc                    ");break;
+  case 0x7c:sprintf(s, "jmp ($%0.4x,x) [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDRX_PC, (op0|op1<<8)));break;
+  case 0x7d:sprintf(s, "adc $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x7e:sprintf(s, "ror $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x7f:sprintf(s, "adc $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
+  case 0x80:sprintf(s, "bra $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0x81:sprintf(s, "sta ($%0.2x,x)   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
+  case 0x82:sprintf(s, "brl $%0.4x     [$%0.6x]", _disas_relw(op0|op1<<8)&0xffff, _disas_relw(op0|op1<<8)&0xffffff);break;
+  case 0x83:sprintf(s, "sta $%0.2x,s     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
+  case 0x84:sprintf(s, "sty $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x85:sprintf(s, "sta $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x86:sprintf(s, "stx $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0x87:sprintf(s, "sta [$%0.2x]     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
+  case 0x88:sprintf(s, "dey                    ");break;
+  case 0x89:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "bit #$%0.2x               ", op0);
+    else sprintf(s, "bit #$%0.4x             ", op0|op1<<8);break;
+  case 0x8a:sprintf(s, "txa                    ");break;
+  case 0x8b:sprintf(s, "phb                    ");break;
+  case 0x8c:sprintf(s, "sty $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x8d:sprintf(s, "sta $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x8e:sprintf(s, "stx $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x8f:sprintf(s, "sta $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0x90:sprintf(s, "bcc $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0x91:sprintf(s, "sta ($%0.2x),y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
+  case 0x92:sprintf(s, "sta ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0x93:sprintf(s, "sta ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
+  case 0x94:sprintf(s, "sty $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x95:sprintf(s, "sta $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0x96:sprintf(s, "stx $%0.2x,y     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPY, op0));break;
+  case 0x97:sprintf(s, "sta [$%0.2x],y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
+  case 0x98:sprintf(s, "tya                    ");break;
+  case 0x99:sprintf(s, "sta $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0x9a:sprintf(s, "txs                    ");break;
+  case 0x9b:sprintf(s, "txy                    ");break;
+  case 0x9c:sprintf(s, "stz $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0x9d:sprintf(s, "sta $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x9e:sprintf(s, "stz $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0x9f:sprintf(s, "sta $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
+  case 0xa0:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "ldy #$%0.2x               ", op0);
+    else sprintf(s, "ldy #$%0.4x             ", op0|op1<<8);break;
+  case 0xa1:sprintf(s, "lda ($%0.2x,x)   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
+  case 0xa2:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "ldx #$%0.2x               ", op0);
+    else sprintf(s, "ldx #$%0.4x             ", op0|op1<<8);break;
+  case 0xa3:sprintf(s, "lda $%0.2x,s     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
+  case 0xa4:sprintf(s, "ldy $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xa5:sprintf(s, "lda $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xa6:sprintf(s, "ldx $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xa7:sprintf(s, "lda [$%0.2x]     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
+  case 0xa8:sprintf(s, "tay                    ");break;
+  case 0xa9:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "lda #$%0.2x               ", op0);
+    else sprintf(s, "lda #$%0.4x             ", op0|op1<<8);break;
+  case 0xaa:sprintf(s, "tax                    ");break;
+  case 0xab:sprintf(s, "plb                    ");break;
+  case 0xac:sprintf(s, "ldy $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xad:sprintf(s, "lda $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xae:sprintf(s, "ldx $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xaf:sprintf(s, "lda $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0xb0:sprintf(s, "bcs $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0xb1:sprintf(s, "lda ($%0.2x),y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
+  case 0xb2:sprintf(s, "lda ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0xb3:sprintf(s, "lda ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
+  case 0xb4:sprintf(s, "ldy $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0xb5:sprintf(s, "lda $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0xb6:sprintf(s, "ldx $%0.2x,y     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPY, op0));break;
+  case 0xb7:sprintf(s, "lda [$%0.2x],y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
+  case 0xb8:sprintf(s, "clv                    ");break;
+  case 0xb9:sprintf(s, "lda $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0xba:sprintf(s, "tsx                    ");break;
+  case 0xbb:sprintf(s, "tyx                    ");break;
+  case 0xbc:sprintf(s, "ldy $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0xbd:sprintf(s, "lda $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0xbe:sprintf(s, "ldx $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0xbf:sprintf(s, "lda $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
+  case 0xc0:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "cpy #$%0.2x               ", op0);
+    else sprintf(s, "cpy #$%0.4x             ", op0|op1<<8);break;
+  case 0xc1:sprintf(s, "cmp ($%0.2x,x)   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
+  case 0xc2:sprintf(s, "rep #$%0.2x               ", op0);break;
+  case 0xc3:sprintf(s, "cmp $%0.2x,s     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
+  case 0xc4:sprintf(s, "cpy $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xc5:sprintf(s, "cmp $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xc6:sprintf(s, "dec $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xc7:sprintf(s, "cmp [$%0.2x]     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
+  case 0xc8:sprintf(s, "iny                    ");break;
+  case 0xc9:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "cmp #$%0.2x               ", op0);
+    else sprintf(s, "cmp #$%0.4x             ", op0|op1<<8);break;
+  case 0xca:sprintf(s, "dex                    ");break;
+  case 0xcb:sprintf(s, "wai                    ");break;
+  case 0xcc:sprintf(s, "cpy $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xcd:sprintf(s, "cmp $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xce:sprintf(s, "dec $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xcf:sprintf(s, "cmp $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0xd0:sprintf(s, "bne $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0xd1:sprintf(s, "cmp ($%0.2x),y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
+  case 0xd2:sprintf(s, "cmp ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0xd3:sprintf(s, "cmp ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
+  case 0xd4:sprintf(s, "pei ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0xd5:sprintf(s, "cmp $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0xd6:sprintf(s, "dec $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0xd7:sprintf(s, "cmp [$%0.2x],y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
+  case 0xd8:sprintf(s, "cld                    ");break;
+  case 0xd9:sprintf(s, "cmp $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0xda:sprintf(s, "phx                    ");break;
+  case 0xdb:sprintf(s, "stp                    ");break;
+  case 0xdc:sprintf(s, "jmp [$%0.4x]   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ILADDR_PC, (op0|op1<<8)));break;
+  case 0xdd:sprintf(s, "cmp $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0xde:sprintf(s, "dec $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0xdf:sprintf(s, "cmp $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
+  case 0xe0:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "cpx #$%0.2x               ", op0);
+    else sprintf(s, "cpx #$%0.4x             ", op0|op1<<8);break;
+  case 0xe1:sprintf(s, "sbc ($%0.2x,x)   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
+  case 0xe2:sprintf(s, "sep #$%0.2x               ", op0);break;
+  case 0xe3:sprintf(s, "sbc $%0.2x,s     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
+  case 0xe4:sprintf(s, "cpx $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xe5:sprintf(s, "sbc $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xe6:sprintf(s, "inc $%0.2x       [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
+  case 0xe7:sprintf(s, "sbc [$%0.2x]     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
+  case 0xe8:sprintf(s, "inx                    ");break;
+  case 0xe9:
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "sbc #$%0.2x               ", op0);
+    else sprintf(s, "sbc #$%0.4x             ", op0|op1<<8);break;
+  case 0xea:sprintf(s, "nop                    ");break;
+  case 0xeb:sprintf(s, "xba                    ");break;
+  case 0xec:sprintf(s, "cpx $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xed:sprintf(s, "sbc $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xee:sprintf(s, "inc $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xef:sprintf(s, "sbc $%0.6x   [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
+  case 0xf0:sprintf(s, "beq $%0.4x     [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
+  case 0xf1:sprintf(s, "sbc ($%0.2x),y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
+  case 0xf2:sprintf(s, "sbc ($%0.2x)     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
+  case 0xf3:sprintf(s, "sbc ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
+  case 0xf4:sprintf(s, "pea $%0.4x     [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
+  case 0xf5:sprintf(s, "sbc $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0xf6:sprintf(s, "inc $%0.2x,x     [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
+  case 0xf7:sprintf(s, "sbc [$%0.2x],y   [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
+  case 0xf8:sprintf(s, "sed                    ");break;
+  case 0xf9:sprintf(s, "sbc $%0.4x,y   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
+  case 0xfa:sprintf(s, "plx                    ");break;
+  case 0xfb:sprintf(s, "xce                    ");break;
+  case 0xfc:sprintf(s, "jsr ($%0.4x,x) [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDRX_PC, (op0|op1<<8)));break;
+  case 0xfd:sprintf(s, "sbc $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0xfe:sprintf(s, "inc $%0.4x,x   [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
+  case 0xff:sprintf(s, "sbc $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
+  }
+}
+
+void disas_g65816_op(void) {
+byte op  = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc,     MEMACCESS_DEBUGGER);
+byte op0 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 1, MEMACCESS_DEBUGGER),
+     op1 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 2, MEMACCESS_DEBUGGER),
+     op2 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 3, MEMACCESS_DEBUGGER);
+char str0[256], str1[256], str2[256];
+
+  strcpy(__disas_op_str, "???                    ");
+  __disas_op(op, op0, op1, op2);
+
+  if(gx816->regs.e == true) {
+    sprintf(str1, "%c%c%c%c%c%c%c%c E",
+      (gx816->regs.p & 0x80)?'N':'n',
+      (gx816->regs.p & 0x40)?'V':'v',
+      (gx816->regs.p & 0x20)?'1':'0',
+      (gx816->regs.p & 0x10)?'B':'b',
+      (gx816->regs.p & 0x08)?'D':'d',
+      (gx816->regs.p & 0x04)?'I':'i',
+      (gx816->regs.p & 0x02)?'Z':'z',
+      (gx816->regs.p & 0x01)?'C':'c');
+  } else {
+    sprintf(str1, "%c%c%c%c%c%c%c%c N",
+      (gx816->regs.p & 0x80)?'N':'n',
+      (gx816->regs.p & 0x40)?'V':'v',
+      (gx816->regs.p & 0x20)?'M':'m',
+      (gx816->regs.p & 0x10)?'X':'x',
+      (gx816->regs.p & 0x08)?'D':'d',
+      (gx816->regs.p & 0x04)?'I':'i',
+      (gx816->regs.p & 0x02)?'Z':'z',
+      (gx816->regs.p & 0x01)?'C':'c');
+  }
+
+  dprintf("%0.6x %s A:%0.4x X:%0.4x Y:%0.4x S:%0.4x D:%0.4x DB:%0.2x %s", gx816->regs.pc, __disas_op_str,
+    gx816->regs.a.w, gx816->regs.x, gx816->regs.y, gx816->regs.s,
+    gx816->regs.d, gx816->regs.db, str1);
+
+  debug_update_cycles();
+}
diff --git a/bsnes/cpu/g65816.cpp b/bsnes/cpu/g65816.cpp
new file mode 100644
index 00000000..9d117b50
--- /dev/null
+++ b/bsnes/cpu/g65816.cpp
@@ -0,0 +1,234 @@
+#include "../base.h"
+#include "../timing/timing.h"
+#include "g65816.h"
+
+extern emustate emu_state;
+extern debugstate debugger;
+extern ppustate ppu;
+extern snes_timer *snes_time;
+g65816 *gx816;
+
+#include "g65816_ops.cpp"
+
+void g65816::LoadROM(void) {
+FILE *fp;
+ulong fsize;
+word  header_offset = 0;
+word  cksum, icksum;
+byte  t;
+int   i;
+  dprintf("* Loading [%s]...", emu_state.rom_name);
+
+  fp = fopen(emu_state.rom_name, "rb");
+  if(!fp)return;
+
+  fseek(fp, 0, SEEK_END);
+  fsize = ftell(fp);
+  fseek(fp, 0, SEEK_SET);
+
+  map = MEMMAP_LOROM;
+
+  if((fsize & 0x000fff) == 0x000200)header_offset = 512;
+
+  fseek(fp, 0x7fdc + header_offset, SEEK_SET);
+  cksum = fgetc(fp) | fgetc(fp) << 8;
+  icksum = fgetc(fp) | fgetc(fp) << 8;
+  if(cksum + icksum == 0xffff)map = MEMMAP_LOROM;
+
+  fseek(fp, 0xffdc + header_offset, SEEK_SET);
+  cksum = fgetc(fp) | fgetc(fp) << 8;
+  icksum = fgetc(fp) | fgetc(fp) << 8;
+  if(cksum + icksum == 0xffff)map = MEMMAP_HIROM;
+
+  fseek(fp, 0 + header_offset, SEEK_SET);
+  fsize -= header_offset;
+
+  dprintf("* ROM detected as: %s", (map == MEMMAP_LOROM)?"LoROM":"HiROM");
+
+  InitializeROM(map);
+
+  fread(rom, 1, fsize, fp);
+
+  t = (mem_read(MEMMODE_NONE, MEMSIZE_BYTE, 0x00ffd8) & 7);
+  switch(t) {
+  case 0: sram_size =   0;       break;
+  case 1: sram_size =   2 * 1024;break;
+  case 2: sram_size =   4 * 1024;break;
+  case 3: sram_size =   8 * 1024;break;
+  case 4: sram_size =  16 * 1024;break;
+  case 5: sram_size =  32 * 1024;break;
+  case 6: sram_size =  64 * 1024;break;
+  case 7: sram_size = 128 * 1024;break;
+  default:sram_size =   0;       break;
+  }
+  dprintf("* SRAM Size: %dkb", sram_size / 1024);
+
+//pbr is loaded with 00, and 16-bit pc is loaded with reset vector at 0xfffc
+//upon power on and at first reset
+  regs.pc   = mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00fffc);
+
+  fclose(fp);
+
+  if(sram_size != 0) {
+    fp = fopen(emu_state.sram_name, "rb");
+
+//create sram file if it does not exist
+    if(!fp) {
+      fp = fopen(emu_state.sram_name, "wb");
+      for(i=0;i<sram_size;i++) {
+        fputc(0, fp);
+      }
+      fclose(fp);
+      fp = fopen(emu_state.sram_name, "rb");
+    }
+    fseek(fp, 0, SEEK_END);
+    fsize = ftell(fp);
+
+//fix sram size if it is smaller than actual size
+    if(fsize < sram_size) {
+      fclose(fp);
+      fp = fopen(emu_state.sram_name, "rb+wb");
+      fseek(fp, 0, SEEK_END);
+      while(fsize < sram_size) {
+        fputc(0, fp);
+        fsize++;
+      }
+      fclose(fp);
+      fp = fopen(emu_state.sram_name, "rb");
+    }
+
+//read file into sram
+    fseek(fp, 0, SEEK_SET);
+    fread(sram, 1, sram_size, fp);
+    fclose(fp);
+  }
+}
+
+void g65816::PowerOn(byte first_time) {
+//default register states
+  regs.a.w = regs.x = regs.y = 0x0000;
+  regs.d   = 0x0000;
+  regs.s   = 0x01ff;
+  regs.db  = 0x00;
+  regs.p   = 0x34;
+  regs.e   = true;
+  snes_time->master_cycles = 0;
+  memory_speed             = MEMSPEED_SLOWROM;
+  toggle_memory_speed      = MEMSPEED_SLOWROM;
+  wai_interrupt_occurred   = false;
+
+  InitializeWRAM(0x00);
+  PPUInit(first_time);
+  UpdateDisplay();
+}
+
+void g65816::Reset(void) {
+  regs.x &= 0xff;
+  regs.y &= 0xff;
+  regs.s  = 0x0100 | (regs.s & 0xff);
+  regs.d  = 0x0000;
+  regs.db = 0x00;
+  regs.p  = 0x34;
+  regs.e  = true;
+  regs.pc = mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00fffc);
+  snes_time->master_cycles = 0;
+  memory_speed             = MEMSPEED_SLOWROM;
+  toggle_memory_speed      = MEMSPEED_SLOWROM;
+  wai_interrupt_occurred   = false;
+
+  PPUInit(0); //0 blocks reallocating memory for vram, cgram, etc.
+  UpdateDisplay();
+
+  if(debug_get_state() == DEBUGMODE_WAIT)disas_g65816_op();
+}
+
+void g65816::InvokeIRQ(word addr) {
+  wai_interrupt_occurred = true;
+  snes_time->add_cpu_pcycles(1);
+  if(gx816->regs.e == true) {
+    snes_time->add_cpu_scycles(3);
+    g65816_stackwrite(MEMSIZE_WORD, gx816->regs.pc);
+    g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.p);
+  } else {
+    snes_time->add_cpu_scycles(4);
+    g65816_stackwrite(MEMSIZE_LONG, gx816->regs.pc);
+    g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.p);
+  }
+  snes_time->add_cpu_mcycles(2, addr);
+  snes_time->add_cpu_icycles(1);
+  gx816->regs.pc = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, addr);
+  gx816->regs.p |= PF_I;
+
+  snes_time->update_timer();
+}
+
+void g65816::Run(void) {
+FILE *fp;
+byte  op;
+word  h;
+int   i;
+static ulong sram_save_tick = 0;
+  op = mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc);
+  if(regs.e == true)g65816_optbl_e[op]();
+  else switch((regs.p & 0x30)) {
+  case 0x30:g65816_optbl_MX[op]();break;
+  case 0x20:g65816_optbl_Mx[op]();break;
+  case 0x10:g65816_optbl_mX[op]();break;
+  case 0x00:g65816_optbl_mx[op]();break;
+  }
+
+  h = snes_time->hscan_pos;
+  snes_time->update_timer();
+  if(snes_time->hscan_pos >= WRAM_REFRESH_DOT_POS && h < WRAM_REFRESH_DOT_POS) {
+    snes_time->add_cpu_cycles(40);
+    snes_time->update_timer();
+  }
+  ppu_update_scanline();
+
+  memory_speed = toggle_memory_speed;
+
+  if(debug_get_state() == DEBUGMODE_DISABLED)return;
+
+  for(i=0;i<16;i++) {
+    if(gx816->bp_list[i].flags & BP_EXEC) {
+      if(gx816->bp_list[i].offset == gx816->regs.pc) {
+        dprintf("* breakpoint %d hit -- exec access", i);
+        gx816->bp_list[i].hit_count++;
+        debug_set_state(DEBUGMODE_WAIT);
+        disas_g65816_op();
+        debugger.refresh_bp = true;
+      }
+    }
+  }
+
+//see if we need to backup sram to a file yet...
+  if(sram_size != 0) {
+    sram_save_tick++;
+    if(sram_save_tick >= emu_state.sram_save_tick_count) {
+      sram_save_tick = 0;
+      fp = fopen(emu_state.sram_name, "wb");
+      fwrite(sram, 1, sram_size, fp);
+      fclose(fp);
+    }
+  }
+}
+
+g65816::g65816() {
+  rom  = (byte*)malloc(0x600000);
+  wram = (byte*)malloc(0x020000);
+  sram = (byte*)malloc(0x0e0000);
+  for(int i=0;i<16;i++) {
+    bp_list[i].offset    = 0;
+    bp_list[i].flags     = BP_OFF;
+    bp_list[i].value     = 0;
+    bp_list[i].hit_count = 0;
+  }
+  nmi_enabled = false;
+  nmi_pin     = 0;
+}
+
+g65816::~g65816() {
+  if(rom)free(rom);
+  if(wram)free(wram);
+  if(sram)free(sram);
+}
diff --git a/bsnes/cpu/g65816.h b/bsnes/cpu/g65816.h
new file mode 100644
index 00000000..f1e83a1b
--- /dev/null
+++ b/bsnes/cpu/g65816.h
@@ -0,0 +1,69 @@
+/*
+  regs.dc is not a real register. it is used to store the data counter
+  for reading from / writing to memory locations. it is also needed
+  to emulate slowrom / fastrom, as the speed varies depending on the
+  location where the memory was accessed.
+*/
+
+class g65816 {
+public:
+//cpu declarations
+  struct {
+    ulong pc, dc;
+    union {
+      byte b;
+      word w;
+      struct { byte l, h; }p;
+    }a;
+    word  x, y, d, s;
+    byte  db, p;
+    bool  e;
+  }regs;
+  byte  memory_speed;
+  byte  toggle_memory_speed;
+  bool  index_bank_crossed;
+
+  byte  nmi_pin;
+  bool  nmi_enabled;
+
+  bool  wai_interrupt_occurred;
+
+//memory declarations
+  byte *wram, *sram, *rom;
+  ulong map;
+  ulong sram_size;
+//debug declarations
+  struct {
+    ulong offset;
+    byte  flags;
+    byte  value;
+    ulong hit_count;
+  }bp_list[16];
+
+//cpu functions (cpu/g65816.cpp)
+  void  Run(void);
+  void  LoadROM(void);
+  void  PowerOn(byte first_time);
+  void  Reset(void);
+  void  InvokeIRQ(word addr);
+
+//memory functions (mem/memory.cpp)
+  void  InitializeROM(byte memory_map);
+  void  InitializeWRAM(byte value);
+  ulong mirror_offset(ulong offset);
+  ulong convert_offset(byte read_mode, ulong addr, bool mirror = true);
+  ulong adjust_base_offset(byte read_mode, ulong addr);
+  ulong read_indirect_address(byte read_mode, ulong addr);
+  ulong get_dc(byte read_mode, ulong addr);
+  byte  mem_getbyte_direct(ulong addr, byte access_mode = MEMACCESS_NORMAL);
+  byte  mem_getbyte(ulong addr, byte access_mode = MEMACCESS_NORMAL);
+  void  mem_putbyte_direct(ulong addr, byte value, byte access_mode = MEMACCESS_NORMAL);
+  void  mem_putbyte(ulong addr, byte value, byte access_mode = MEMACCESS_NORMAL);
+  ulong mem_read(byte read_mode, byte read_size, ulong addr, byte access_mode = MEMACCESS_NORMAL);
+  void  mem_write(byte write_mode, byte write_size, ulong addr, ulong value, byte access_mode = MEMACCESS_NORMAL);
+  ulong rom_read(ulong addr, byte read_size);
+  void  rom_write(ulong addr, ulong v, byte write_size);
+
+  g65816();
+  ~g65816();
+};
diff --git a/bsnes/cpu/g65816_ops.cpp b/bsnes/cpu/g65816_ops.cpp
new file mode 100644
index 00000000..02e036da
--- /dev/null
+++ b/bsnes/cpu/g65816_ops.cpp
@@ -0,0 +1,161 @@
+#define g65816_setn() gx816->regs.p |=  PF_N
+#define g65816_clrn() gx816->regs.p &= ~PF_N
+#define g65816_setv() gx816->regs.p |=  PF_V
+#define g65816_clrv() gx816->regs.p &= ~PF_V
+#define g65816_setm() gx816->regs.p |=  PF_M
+#define g65816_clrm() gx816->regs.p &= ~PF_M
+#define g65816_setx() gx816->regs.p |=  PF_X
+#define g65816_clrx() gx816->regs.p &= ~PF_X
+#define g65816_setd() gx816->regs.p |=  PF_D
+#define g65816_clrd() gx816->regs.p &= ~PF_D
+#define g65816_seti() gx816->regs.p |=  PF_I
+#define g65816_clri() gx816->regs.p &= ~PF_I
+#define g65816_setz() gx816->regs.p |=  PF_Z
+#define g65816_clrz() gx816->regs.p &= ~PF_Z
+#define g65816_setc() gx816->regs.p |=  PF_C
+#define g65816_clrc() gx816->regs.p &= ~PF_C
+#define g65816_testn(x) if(x)g65816_setn(); else g65816_clrn()
+#define g65816_testv(x) if(x)g65816_setv(); else g65816_clrv()
+#define g65816_testd(x) if(x)g65816_setd(); else g65816_clrd()
+#define g65816_testi(x) if(x)g65816_seti(); else g65816_clri()
+#define g65816_testz(x) if(x)g65816_setz(); else g65816_clrz()
+#define g65816_testc(x) if(x)g65816_setc(); else g65816_clrc()
+
+//read opcode argument
+#define g65816_prefetch(__size) ulong arg = gx816->mem_read(MEMMODE_NONE, __size, gx816->regs.pc + 1, MEMACCESS_CPU)
+//get destination address, do not mirror
+#define g65816_getaddr(__mode) ulong dest_addr = gx816->get_dc(__mode, arg)
+//get indirect destination address + destination address, do not mirror
+#define g65816_getiaddr(__mode) ulong base_addr = gx816->adjust_base_offset(__mode, arg);ulong dest_addr = gx816->read_indirect_address(__mode, base_addr)
+//increment program counter, wrap around pbr
+#define g65816_incpc(__n) gx816->regs.pc = (gx816->regs.pc & 0xff0000) | ((gx816->regs.pc + __n) & 0xffff)
+
+//opcode functions
+#include "g65816_ops_adc.cpp"
+#include "g65816_ops_and.cpp"
+#include "g65816_ops_cmp.cpp"
+#include "g65816_ops_eor.cpp"
+#include "g65816_ops_lda.cpp"
+#include "g65816_ops_ora.cpp"
+#include "g65816_ops_sbc.cpp"
+#include "g65816_ops_sta.cpp"
+#include "g65816_ops_incdec.cpp"
+#include "g65816_ops_shift.cpp"
+#include "g65816_ops_stack.cpp"
+#include "g65816_ops_pc.cpp"
+#include "g65816_ops_misc.cpp"
+
+vfunc g65816_optbl_e[256] = { //                                                                                 g65816_optbl_e,                                                                                                  g65816_optbl_e,                                                                                                  g65816_optbl_e,
+      // ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
+/* 0x */           g65816_op_brke,      g65816_op_ora_idpxb,           g65816_op_cope,        g65816_op_ora_srb, /* 0x */        g65816_op_tsb_dpb,        g65816_op_ora_dpb,        g65816_op_asl_dpb,      g65816_op_ora_ildpb, /* 0x */            g65816_op_php,     g65816_op_ora_constb,           g65816_op_aslb,            g65816_op_phd, /* 0x */      g65816_op_tsb_addrb,      g65816_op_ora_addrb,      g65816_op_asl_addrb,      g65816_op_ora_longb,
+/* 1x */            g65816_op_bpl,      g65816_op_ora_idpyb,       g65816_op_ora_idpb,      g65816_op_ora_isryb, /* 1x */        g65816_op_trb_dpb,       g65816_op_ora_dpxb,       g65816_op_asl_dpxb,     g65816_op_ora_ildpyb, /* 1x */            g65816_op_clc,     g65816_op_ora_addryb,           g65816_op_incb,           g65816_op_tcse, /* 1x */      g65816_op_trb_addrb,     g65816_op_ora_addrxb,     g65816_op_asl_addrxb,     g65816_op_ora_longxb,
+/* 2x */       g65816_op_jsr_addr,      g65816_op_and_idpxb,       g65816_op_jsr_long,        g65816_op_and_srb, /* 2x */        g65816_op_bit_dpb,        g65816_op_and_dpb,        g65816_op_rol_dpb,      g65816_op_and_ildpb, /* 2x */            g65816_op_plp,     g65816_op_and_constb,           g65816_op_rolb,            g65816_op_pld, /* 2x */      g65816_op_bit_addrb,      g65816_op_and_addrb,      g65816_op_rol_addrb,      g65816_op_and_longb,
+/* 3x */            g65816_op_bmi,      g65816_op_and_idpyb,       g65816_op_and_idpb,      g65816_op_and_isryb, /* 3x */       g65816_op_bit_dpxb,       g65816_op_and_dpxb,       g65816_op_rol_dpxb,     g65816_op_and_ildpyb, /* 3x */            g65816_op_sec,     g65816_op_and_addryb,           g65816_op_decb,           g65816_op_tsce, /* 3x */     g65816_op_bit_addrxb,     g65816_op_and_addrxb,     g65816_op_rol_addrxb,     g65816_op_and_longxb,
+
+/* 4x */           g65816_op_rtie,      g65816_op_eor_idpxb,            g65816_op_wdm,        g65816_op_eor_srb, /* 4x */            g65816_op_mvp,        g65816_op_eor_dpb,        g65816_op_lsr_dpb,      g65816_op_eor_ildpb, /* 4x */           g65816_op_phab,     g65816_op_eor_constb,           g65816_op_lsrb,            g65816_op_phk, /* 4x */       g65816_op_jmp_addr,      g65816_op_eor_addrb,      g65816_op_lsr_addrb,      g65816_op_eor_longb,
+/* 5x */            g65816_op_bvc,      g65816_op_eor_idpyb,       g65816_op_eor_idpb,      g65816_op_eor_isryb, /* 5x */            g65816_op_mvn,       g65816_op_eor_dpxb,       g65816_op_lsr_dpxb,     g65816_op_eor_ildpyb, /* 5x */            g65816_op_cli,     g65816_op_eor_addryb,           g65816_op_phyb,            g65816_op_tcd, /* 5x */       g65816_op_jmp_long,     g65816_op_eor_addrxb,     g65816_op_lsr_addrxb,     g65816_op_eor_longxb,
+/* 6x */            g65816_op_rts,      g65816_op_adc_idpxb,            g65816_op_per,        g65816_op_adc_srb, /* 6x */        g65816_op_stz_dpb,        g65816_op_adc_dpb,        g65816_op_ror_dpb,      g65816_op_adc_ildpb, /* 6x */           g65816_op_plab,     g65816_op_adc_constb,           g65816_op_rorb,            g65816_op_rtl, /* 6x */      g65816_op_jmp_iaddr,      g65816_op_adc_addrb,      g65816_op_ror_addrb,      g65816_op_adc_longb,
+/* 7x */            g65816_op_bvs,      g65816_op_adc_idpyb,       g65816_op_adc_idpb,      g65816_op_adc_isryb, /* 7x */       g65816_op_stz_dpxb,       g65816_op_adc_dpxb,       g65816_op_ror_dpxb,     g65816_op_adc_ildpyb, /* 7x */            g65816_op_sei,     g65816_op_adc_addryb,           g65816_op_plyb,               g65816_tdc, /* 7x */     g65816_op_jmp_iaddrx,     g65816_op_adc_addrxb,     g65816_op_ror_addrxb,     g65816_op_adc_longxb,
+
+/* 8x */            g65816_op_bra,      g65816_op_sta_idpxb,            g65816_op_brl,        g65816_op_sta_srb, /* 8x */        g65816_op_sty_dpb,        g65816_op_sta_dpb,        g65816_op_stx_dpb,      g65816_op_sta_ildpb, /* 8x */           g65816_op_deyb,     g65816_op_bit_constb,           g65816_op_txab,            g65816_op_phb, /* 8x */      g65816_op_sty_addrb,      g65816_op_sta_addrb,      g65816_op_stx_addrb,      g65816_op_sta_longb,
+/* 9x */            g65816_op_bcc,      g65816_op_sta_idpyb,       g65816_op_sta_idpb,      g65816_op_sta_isryb, /* 9x */       g65816_op_sty_dpxb,       g65816_op_sta_dpxb,       g65816_op_stx_dpyb,     g65816_op_sta_ildpyb, /* 9x */           g65816_op_tyab,     g65816_op_sta_addryb,           g65816_op_txsb,           g65816_op_txyb, /* 9x */      g65816_op_stz_addrb,     g65816_op_sta_addrxb,     g65816_op_stz_addrxb,     g65816_op_sta_longxb,
+/* ax */     g65816_op_ldy_constb,      g65816_op_lda_idpxb,     g65816_op_ldx_constb,        g65816_op_lda_srb, /* ax */        g65816_op_ldy_dpb,        g65816_op_lda_dpb,        g65816_op_ldx_dpb,      g65816_op_lda_ildpb, /* ax */           g65816_op_tayb,     g65816_op_lda_constb,           g65816_op_taxb,            g65816_op_plb, /* ax */      g65816_op_ldy_addrb,      g65816_op_lda_addrb,      g65816_op_ldx_addrb,      g65816_op_lda_longb,
+/* bx */            g65816_op_bcs,      g65816_op_lda_idpyb,       g65816_op_lda_idpb,      g65816_op_lda_isryb, /* bx */       g65816_op_ldy_dpxb,       g65816_op_lda_dpxb,       g65816_op_ldx_dpyb,     g65816_op_lda_ildpyb, /* bx */            g65816_op_clv,     g65816_op_lda_addryb,           g65816_op_tsxb,           g65816_op_tyxb, /* bx */     g65816_op_ldy_addrxb,     g65816_op_lda_addrxb,     g65816_op_ldx_addryb,     g65816_op_lda_longxb,
+
+/* cx */     g65816_op_cpy_constb,      g65816_op_cmp_idpxb,            g65816_op_rep,        g65816_op_cmp_srb, /* cx */        g65816_op_cpy_dpb,        g65816_op_cmp_dpb,        g65816_op_dec_dpb,      g65816_op_cmp_ildpb, /* cx */           g65816_op_inyb,     g65816_op_cmp_constb,           g65816_op_dexb,            g65816_op_wai, /* cx */      g65816_op_cpy_addrb,      g65816_op_cmp_addrb,      g65816_op_dec_addrb,      g65816_op_cmp_longb,
+/* dx */            g65816_op_bne,      g65816_op_cmp_idpyb,       g65816_op_cmp_idpb,      g65816_op_cmp_isryb, /* dx */            g65816_op_pei,       g65816_op_cmp_dpxb,       g65816_op_dec_dpxb,     g65816_op_cmp_ildpyb, /* dx */            g65816_op_cld,     g65816_op_cmp_addryb,           g65816_op_phxb,            g65816_op_stp, /* dx */     g65816_op_jmp_iladdr,     g65816_op_cmp_addrxb,     g65816_op_dec_addrxb,     g65816_op_cmp_longxb,
+/* ex */     g65816_op_cpx_constb,      g65816_op_sbc_idpxb,            g65816_op_sep,        g65816_op_sbc_srb, /* ex */        g65816_op_cpx_dpb,        g65816_op_sbc_dpb,        g65816_op_inc_dpb,      g65816_op_sbc_ildpb, /* ex */           g65816_op_inxb,     g65816_op_sbc_constb,            g65816_op_nop,            g65816_op_xba, /* ex */      g65816_op_cpx_addrb,      g65816_op_sbc_addrb,      g65816_op_inc_addrb,      g65816_op_sbc_longb,
+/* fx */            g65816_op_beq,      g65816_op_sbc_idpyb,       g65816_op_sbc_idpb,      g65816_op_sbc_isryb, /* fx */            g65816_op_pea,       g65816_op_sbc_dpxb,       g65816_op_inc_dpxb,     g65816_op_sbc_ildpyb, /* fx */            g65816_op_sed,     g65816_op_sbc_addryb,           g65816_op_plxb,            g65816_op_xce, /* fx */     g65816_op_jsr_iaddrx,     g65816_op_sbc_addrxb,     g65816_op_inc_addrxb,     g65816_op_sbc_longxb
+};
+
+vfunc g65816_optbl_MX[256] = { //                                                                                g65816_optbl_MX,                                                                                                 g65816_optbl_MX,                                                                                                 g65816_optbl_MX,
+      // ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
+/* 0x */           g65816_op_brkn,      g65816_op_ora_idpxb,           g65816_op_copn,        g65816_op_ora_srb, /* 0x */        g65816_op_tsb_dpb,        g65816_op_ora_dpb,        g65816_op_asl_dpb,      g65816_op_ora_ildpb, /* 0x */            g65816_op_php,     g65816_op_ora_constb,           g65816_op_aslb,            g65816_op_phd, /* 0x */      g65816_op_tsb_addrb,      g65816_op_ora_addrb,      g65816_op_asl_addrb,      g65816_op_ora_longb,
+/* 1x */            g65816_op_bpl,      g65816_op_ora_idpyb,       g65816_op_ora_idpb,      g65816_op_ora_isryb, /* 1x */        g65816_op_trb_dpb,       g65816_op_ora_dpxb,       g65816_op_asl_dpxb,     g65816_op_ora_ildpyb, /* 1x */            g65816_op_clc,     g65816_op_ora_addryb,           g65816_op_incb,           g65816_op_tcsn, /* 1x */      g65816_op_trb_addrb,     g65816_op_ora_addrxb,     g65816_op_asl_addrxb,     g65816_op_ora_longxb,
+/* 2x */       g65816_op_jsr_addr,      g65816_op_and_idpxb,       g65816_op_jsr_long,        g65816_op_and_srb, /* 2x */        g65816_op_bit_dpb,        g65816_op_and_dpb,        g65816_op_rol_dpb,      g65816_op_and_ildpb, /* 2x */            g65816_op_plp,     g65816_op_and_constb,           g65816_op_rolb,            g65816_op_pld, /* 2x */      g65816_op_bit_addrb,      g65816_op_and_addrb,      g65816_op_rol_addrb,      g65816_op_and_longb,
+/* 3x */            g65816_op_bmi,      g65816_op_and_idpyb,       g65816_op_and_idpb,      g65816_op_and_isryb, /* 3x */       g65816_op_bit_dpxb,       g65816_op_and_dpxb,       g65816_op_rol_dpxb,     g65816_op_and_ildpyb, /* 3x */            g65816_op_sec,     g65816_op_and_addryb,           g65816_op_decb,           g65816_op_tscn, /* 3x */     g65816_op_bit_addrxb,     g65816_op_and_addrxb,     g65816_op_rol_addrxb,     g65816_op_and_longxb,
+
+/* 4x */           g65816_op_rtin,      g65816_op_eor_idpxb,            g65816_op_wdm,        g65816_op_eor_srb, /* 4x */            g65816_op_mvp,        g65816_op_eor_dpb,        g65816_op_lsr_dpb,      g65816_op_eor_ildpb, /* 4x */           g65816_op_phab,     g65816_op_eor_constb,           g65816_op_lsrb,            g65816_op_phk, /* 4x */       g65816_op_jmp_addr,      g65816_op_eor_addrb,      g65816_op_lsr_addrb,      g65816_op_eor_longb,
+/* 5x */            g65816_op_bvc,      g65816_op_eor_idpyb,       g65816_op_eor_idpb,      g65816_op_eor_isryb, /* 5x */            g65816_op_mvn,       g65816_op_eor_dpxb,       g65816_op_lsr_dpxb,     g65816_op_eor_ildpyb, /* 5x */            g65816_op_cli,     g65816_op_eor_addryb,           g65816_op_phyb,            g65816_op_tcd, /* 5x */       g65816_op_jmp_long,     g65816_op_eor_addrxb,     g65816_op_lsr_addrxb,     g65816_op_eor_longxb,
+/* 6x */            g65816_op_rts,      g65816_op_adc_idpxb,            g65816_op_per,        g65816_op_adc_srb, /* 6x */        g65816_op_stz_dpb,        g65816_op_adc_dpb,        g65816_op_ror_dpb,      g65816_op_adc_ildpb, /* 6x */           g65816_op_plab,     g65816_op_adc_constb,           g65816_op_rorb,            g65816_op_rtl, /* 6x */      g65816_op_jmp_iaddr,      g65816_op_adc_addrb,      g65816_op_ror_addrb,      g65816_op_adc_longb,
+/* 7x */            g65816_op_bvs,      g65816_op_adc_idpyb,       g65816_op_adc_idpb,      g65816_op_adc_isryb, /* 7x */       g65816_op_stz_dpxb,       g65816_op_adc_dpxb,       g65816_op_ror_dpxb,     g65816_op_adc_ildpyb, /* 7x */            g65816_op_sei,     g65816_op_adc_addryb,           g65816_op_plyb,               g65816_tdc, /* 7x */     g65816_op_jmp_iaddrx,     g65816_op_adc_addrxb,     g65816_op_ror_addrxb,     g65816_op_adc_longxb,
+
+/* 8x */            g65816_op_bra,      g65816_op_sta_idpxb,            g65816_op_brl,        g65816_op_sta_srb, /* 8x */        g65816_op_sty_dpb,        g65816_op_sta_dpb,        g65816_op_stx_dpb,      g65816_op_sta_ildpb, /* 8x */           g65816_op_deyb,     g65816_op_bit_constb,           g65816_op_txab,            g65816_op_phb, /* 8x */      g65816_op_sty_addrb,      g65816_op_sta_addrb,      g65816_op_stx_addrb,      g65816_op_sta_longb,
+/* 9x */            g65816_op_bcc,      g65816_op_sta_idpyb,       g65816_op_sta_idpb,      g65816_op_sta_isryb, /* 9x */       g65816_op_sty_dpxb,       g65816_op_sta_dpxb,       g65816_op_stx_dpyb,     g65816_op_sta_ildpyb, /* 9x */           g65816_op_tyab,     g65816_op_sta_addryb,           g65816_op_txsb,           g65816_op_txyb, /* 9x */      g65816_op_stz_addrb,     g65816_op_sta_addrxb,     g65816_op_stz_addrxb,     g65816_op_sta_longxb,
+/* ax */     g65816_op_ldy_constb,      g65816_op_lda_idpxb,     g65816_op_ldx_constb,        g65816_op_lda_srb, /* ax */        g65816_op_ldy_dpb,        g65816_op_lda_dpb,        g65816_op_ldx_dpb,      g65816_op_lda_ildpb, /* ax */           g65816_op_tayb,     g65816_op_lda_constb,           g65816_op_taxb,            g65816_op_plb, /* ax */      g65816_op_ldy_addrb,      g65816_op_lda_addrb,      g65816_op_ldx_addrb,      g65816_op_lda_longb,
+/* bx */            g65816_op_bcs,      g65816_op_lda_idpyb,       g65816_op_lda_idpb,      g65816_op_lda_isryb, /* bx */       g65816_op_ldy_dpxb,       g65816_op_lda_dpxb,       g65816_op_ldx_dpyb,     g65816_op_lda_ildpyb, /* bx */            g65816_op_clv,     g65816_op_lda_addryb,           g65816_op_tsxb,           g65816_op_tyxb, /* bx */     g65816_op_ldy_addrxb,     g65816_op_lda_addrxb,     g65816_op_ldx_addryb,     g65816_op_lda_longxb,
+
+/* cx */     g65816_op_cpy_constb,      g65816_op_cmp_idpxb,            g65816_op_rep,        g65816_op_cmp_srb, /* cx */        g65816_op_cpy_dpb,        g65816_op_cmp_dpb,        g65816_op_dec_dpb,      g65816_op_cmp_ildpb, /* cx */           g65816_op_inyb,     g65816_op_cmp_constb,           g65816_op_dexb,            g65816_op_wai, /* cx */      g65816_op_cpy_addrb,      g65816_op_cmp_addrb,      g65816_op_dec_addrb,      g65816_op_cmp_longb,
+/* dx */            g65816_op_bne,      g65816_op_cmp_idpyb,       g65816_op_cmp_idpb,      g65816_op_cmp_isryb, /* dx */            g65816_op_pei,       g65816_op_cmp_dpxb,       g65816_op_dec_dpxb,     g65816_op_cmp_ildpyb, /* dx */            g65816_op_cld,     g65816_op_cmp_addryb,           g65816_op_phxb,            g65816_op_stp, /* dx */     g65816_op_jmp_iladdr,     g65816_op_cmp_addrxb,     g65816_op_dec_addrxb,     g65816_op_cmp_longxb,
+/* ex */     g65816_op_cpx_constb,      g65816_op_sbc_idpxb,            g65816_op_sep,        g65816_op_sbc_srb, /* ex */        g65816_op_cpx_dpb,        g65816_op_sbc_dpb,        g65816_op_inc_dpb,      g65816_op_sbc_ildpb, /* ex */           g65816_op_inxb,     g65816_op_sbc_constb,            g65816_op_nop,            g65816_op_xba, /* ex */      g65816_op_cpx_addrb,      g65816_op_sbc_addrb,      g65816_op_inc_addrb,      g65816_op_sbc_longb,
+/* fx */            g65816_op_beq,      g65816_op_sbc_idpyb,       g65816_op_sbc_idpb,      g65816_op_sbc_isryb, /* fx */            g65816_op_pea,       g65816_op_sbc_dpxb,       g65816_op_inc_dpxb,     g65816_op_sbc_ildpyb, /* fx */            g65816_op_sed,     g65816_op_sbc_addryb,           g65816_op_plxb,            g65816_op_xce, /* fx */     g65816_op_jsr_iaddrx,     g65816_op_sbc_addrxb,     g65816_op_inc_addrxb,     g65816_op_sbc_longxb
+};
+
+vfunc g65816_optbl_Mx[256] = { //                                                                                g65816_optbl_Mx,                                                                                                 g65816_optbl_Mx,                                                                                                 g65816_optbl_Mx,
+      // ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
+/* 0x */           g65816_op_brkn,      g65816_op_ora_idpxb,           g65816_op_copn,        g65816_op_ora_srb, /* 0x */        g65816_op_tsb_dpb,        g65816_op_ora_dpb,        g65816_op_asl_dpb,      g65816_op_ora_ildpb, /* 0x */            g65816_op_php,     g65816_op_ora_constb,           g65816_op_aslb,            g65816_op_phd, /* 0x */      g65816_op_tsb_addrb,      g65816_op_ora_addrb,      g65816_op_asl_addrb,      g65816_op_ora_longb,
+/* 1x */            g65816_op_bpl,      g65816_op_ora_idpyb,       g65816_op_ora_idpb,      g65816_op_ora_isryb, /* 1x */        g65816_op_trb_dpb,       g65816_op_ora_dpxb,       g65816_op_asl_dpxb,     g65816_op_ora_ildpyb, /* 1x */            g65816_op_clc,     g65816_op_ora_addryb,           g65816_op_incb,           g65816_op_tcsn, /* 1x */      g65816_op_trb_addrb,     g65816_op_ora_addrxb,     g65816_op_asl_addrxb,     g65816_op_ora_longxb,
+/* 2x */       g65816_op_jsr_addr,      g65816_op_and_idpxb,       g65816_op_jsr_long,        g65816_op_and_srb, /* 2x */        g65816_op_bit_dpb,        g65816_op_and_dpb,        g65816_op_rol_dpb,      g65816_op_and_ildpb, /* 2x */            g65816_op_plp,     g65816_op_and_constb,           g65816_op_rolb,            g65816_op_pld, /* 2x */      g65816_op_bit_addrb,      g65816_op_and_addrb,      g65816_op_rol_addrb,      g65816_op_and_longb,
+/* 3x */            g65816_op_bmi,      g65816_op_and_idpyb,       g65816_op_and_idpb,      g65816_op_and_isryb, /* 3x */       g65816_op_bit_dpxb,       g65816_op_and_dpxb,       g65816_op_rol_dpxb,     g65816_op_and_ildpyb, /* 3x */            g65816_op_sec,     g65816_op_and_addryb,           g65816_op_decb,           g65816_op_tscn, /* 3x */     g65816_op_bit_addrxb,     g65816_op_and_addrxb,     g65816_op_rol_addrxb,     g65816_op_and_longxb,
+
+/* 4x */           g65816_op_rtin,      g65816_op_eor_idpxb,            g65816_op_wdm,        g65816_op_eor_srb, /* 4x */            g65816_op_mvp,        g65816_op_eor_dpb,        g65816_op_lsr_dpb,      g65816_op_eor_ildpb, /* 4x */           g65816_op_phab,     g65816_op_eor_constb,           g65816_op_lsrb,            g65816_op_phk, /* 4x */       g65816_op_jmp_addr,      g65816_op_eor_addrb,      g65816_op_lsr_addrb,      g65816_op_eor_longb,
+/* 5x */            g65816_op_bvc,      g65816_op_eor_idpyb,       g65816_op_eor_idpb,      g65816_op_eor_isryb, /* 5x */            g65816_op_mvn,       g65816_op_eor_dpxb,       g65816_op_lsr_dpxb,     g65816_op_eor_ildpyb, /* 5x */            g65816_op_cli,     g65816_op_eor_addryb,           g65816_op_phyw,            g65816_op_tcd, /* 5x */       g65816_op_jmp_long,     g65816_op_eor_addrxb,     g65816_op_lsr_addrxb,     g65816_op_eor_longxb,
+/* 6x */            g65816_op_rts,      g65816_op_adc_idpxb,            g65816_op_per,        g65816_op_adc_srb, /* 6x */        g65816_op_stz_dpb,        g65816_op_adc_dpb,        g65816_op_ror_dpb,      g65816_op_adc_ildpb, /* 6x */           g65816_op_plab,     g65816_op_adc_constb,           g65816_op_rorb,            g65816_op_rtl, /* 6x */      g65816_op_jmp_iaddr,      g65816_op_adc_addrb,      g65816_op_ror_addrb,      g65816_op_adc_longb,
+/* 7x */            g65816_op_bvs,      g65816_op_adc_idpyb,       g65816_op_adc_idpb,      g65816_op_adc_isryb, /* 7x */       g65816_op_stz_dpxb,       g65816_op_adc_dpxb,       g65816_op_ror_dpxb,     g65816_op_adc_ildpyb, /* 7x */            g65816_op_sei,     g65816_op_adc_addryb,           g65816_op_plyw,               g65816_tdc, /* 7x */     g65816_op_jmp_iaddrx,     g65816_op_adc_addrxb,     g65816_op_ror_addrxb,     g65816_op_adc_longxb,
+
+/* 8x */            g65816_op_bra,      g65816_op_sta_idpxb,            g65816_op_brl,        g65816_op_sta_srb, /* 8x */        g65816_op_sty_dpw,        g65816_op_sta_dpb,        g65816_op_stx_dpw,      g65816_op_sta_ildpb, /* 8x */           g65816_op_deyw,     g65816_op_bit_constb,           g65816_op_txab,            g65816_op_phb, /* 8x */      g65816_op_sty_addrw,      g65816_op_sta_addrb,      g65816_op_stx_addrw,      g65816_op_sta_longb,
+/* 9x */            g65816_op_bcc,      g65816_op_sta_idpyb,       g65816_op_sta_idpb,      g65816_op_sta_isryb, /* 9x */       g65816_op_sty_dpxw,       g65816_op_sta_dpxb,       g65816_op_stx_dpyw,     g65816_op_sta_ildpyb, /* 9x */           g65816_op_tyab,     g65816_op_sta_addryb,           g65816_op_txsw,           g65816_op_txyw, /* 9x */      g65816_op_stz_addrb,     g65816_op_sta_addrxb,     g65816_op_stz_addrxb,     g65816_op_sta_longxb,
+/* ax */     g65816_op_ldy_constw,      g65816_op_lda_idpxb,     g65816_op_ldx_constw,        g65816_op_lda_srb, /* ax */        g65816_op_ldy_dpw,        g65816_op_lda_dpb,        g65816_op_ldx_dpw,      g65816_op_lda_ildpb, /* ax */           g65816_op_tayw,     g65816_op_lda_constb,           g65816_op_taxw,            g65816_op_plb, /* ax */      g65816_op_ldy_addrw,      g65816_op_lda_addrb,      g65816_op_ldx_addrw,      g65816_op_lda_longb,
+/* bx */            g65816_op_bcs,      g65816_op_lda_idpyb,       g65816_op_lda_idpb,      g65816_op_lda_isryb, /* bx */       g65816_op_ldy_dpxw,       g65816_op_lda_dpxb,       g65816_op_ldx_dpyw,     g65816_op_lda_ildpyb, /* bx */            g65816_op_clv,     g65816_op_lda_addryb,           g65816_op_tsxw,           g65816_op_tyxw, /* bx */     g65816_op_ldy_addrxw,     g65816_op_lda_addrxb,     g65816_op_ldx_addryw,     g65816_op_lda_longxb,
+
+/* cx */     g65816_op_cpy_constw,      g65816_op_cmp_idpxb,            g65816_op_rep,        g65816_op_cmp_srb, /* cx */        g65816_op_cpy_dpw,        g65816_op_cmp_dpb,        g65816_op_dec_dpb,      g65816_op_cmp_ildpb, /* cx */           g65816_op_inyw,     g65816_op_cmp_constb,           g65816_op_dexw,            g65816_op_wai, /* cx */      g65816_op_cpy_addrw,      g65816_op_cmp_addrb,      g65816_op_dec_addrb,      g65816_op_cmp_longb,
+/* dx */            g65816_op_bne,      g65816_op_cmp_idpyb,       g65816_op_cmp_idpb,      g65816_op_cmp_isryb, /* dx */            g65816_op_pei,       g65816_op_cmp_dpxb,       g65816_op_dec_dpxb,     g65816_op_cmp_ildpyb, /* dx */            g65816_op_cld,     g65816_op_cmp_addryb,           g65816_op_phxw,            g65816_op_stp, /* dx */     g65816_op_jmp_iladdr,     g65816_op_cmp_addrxb,     g65816_op_dec_addrxb,     g65816_op_cmp_longxb,
+/* ex */     g65816_op_cpx_constw,      g65816_op_sbc_idpxb,            g65816_op_sep,        g65816_op_sbc_srb, /* ex */        g65816_op_cpx_dpw,        g65816_op_sbc_dpb,        g65816_op_inc_dpb,      g65816_op_sbc_ildpb, /* ex */           g65816_op_inxw,     g65816_op_sbc_constb,            g65816_op_nop,            g65816_op_xba, /* ex */      g65816_op_cpx_addrw,      g65816_op_sbc_addrb,      g65816_op_inc_addrb,      g65816_op_sbc_longb,
+/* fx */            g65816_op_beq,      g65816_op_sbc_idpyb,       g65816_op_sbc_idpb,      g65816_op_sbc_isryb, /* fx */            g65816_op_pea,       g65816_op_sbc_dpxb,       g65816_op_inc_dpxb,     g65816_op_sbc_ildpyb, /* fx */            g65816_op_sed,     g65816_op_sbc_addryb,           g65816_op_plxw,            g65816_op_xce, /* fx */     g65816_op_jsr_iaddrx,     g65816_op_sbc_addrxb,     g65816_op_inc_addrxb,     g65816_op_sbc_longxb
+};
+
+vfunc g65816_optbl_mX[256] = { //                                                                                g65816_optbl_mX,                                                                                                 g65816_optbl_mX,                                                                                                 g65816_optbl_mX,
+      // ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
+/* 0x */           g65816_op_brkn,      g65816_op_ora_idpxw,           g65816_op_copn,        g65816_op_ora_srw, /* 0x */        g65816_op_tsb_dpw,        g65816_op_ora_dpw,        g65816_op_asl_dpw,      g65816_op_ora_ildpw, /* 0x */            g65816_op_php,     g65816_op_ora_constw,           g65816_op_aslw,            g65816_op_phd, /* 0x */      g65816_op_tsb_addrw,      g65816_op_ora_addrw,      g65816_op_asl_addrw,      g65816_op_ora_longw,
+/* 1x */            g65816_op_bpl,      g65816_op_ora_idpyw,       g65816_op_ora_idpw,      g65816_op_ora_isryw, /* 1x */        g65816_op_trb_dpw,       g65816_op_ora_dpxw,       g65816_op_asl_dpxw,     g65816_op_ora_ildpyw, /* 1x */            g65816_op_clc,     g65816_op_ora_addryw,           g65816_op_incw,           g65816_op_tcsn, /* 1x */      g65816_op_trb_addrw,     g65816_op_ora_addrxw,     g65816_op_asl_addrxw,     g65816_op_ora_longxw,
+/* 2x */       g65816_op_jsr_addr,      g65816_op_and_idpxw,       g65816_op_jsr_long,        g65816_op_and_srw, /* 2x */        g65816_op_bit_dpw,        g65816_op_and_dpw,        g65816_op_rol_dpw,      g65816_op_and_ildpw, /* 2x */            g65816_op_plp,     g65816_op_and_constw,           g65816_op_rolw,            g65816_op_pld, /* 2x */      g65816_op_bit_addrw,      g65816_op_and_addrw,      g65816_op_rol_addrw,      g65816_op_and_longw,
+/* 3x */            g65816_op_bmi,      g65816_op_and_idpyw,       g65816_op_and_idpw,      g65816_op_and_isryw, /* 3x */       g65816_op_bit_dpxw,       g65816_op_and_dpxw,       g65816_op_rol_dpxw,     g65816_op_and_ildpyw, /* 3x */            g65816_op_sec,     g65816_op_and_addryw,           g65816_op_decw,           g65816_op_tscn, /* 3x */     g65816_op_bit_addrxw,     g65816_op_and_addrxw,     g65816_op_rol_addrxw,     g65816_op_and_longxw,
+
+/* 4x */           g65816_op_rtin,      g65816_op_eor_idpxw,            g65816_op_wdm,        g65816_op_eor_srw, /* 4x */            g65816_op_mvp,        g65816_op_eor_dpw,        g65816_op_lsr_dpw,      g65816_op_eor_ildpw, /* 4x */           g65816_op_phaw,     g65816_op_eor_constw,           g65816_op_lsrw,            g65816_op_phk, /* 4x */       g65816_op_jmp_addr,      g65816_op_eor_addrw,      g65816_op_lsr_addrw,      g65816_op_eor_longw,
+/* 5x */            g65816_op_bvc,      g65816_op_eor_idpyw,       g65816_op_eor_idpw,      g65816_op_eor_isryw, /* 5x */            g65816_op_mvn,       g65816_op_eor_dpxw,       g65816_op_lsr_dpxw,     g65816_op_eor_ildpyw, /* 5x */            g65816_op_cli,     g65816_op_eor_addryw,           g65816_op_phyb,            g65816_op_tcd, /* 5x */       g65816_op_jmp_long,     g65816_op_eor_addrxw,     g65816_op_lsr_addrxw,     g65816_op_eor_longxw,
+/* 6x */            g65816_op_rts,      g65816_op_adc_idpxw,            g65816_op_per,        g65816_op_adc_srw, /* 6x */        g65816_op_stz_dpw,        g65816_op_adc_dpw,        g65816_op_ror_dpw,      g65816_op_adc_ildpw, /* 6x */           g65816_op_plaw,     g65816_op_adc_constw,           g65816_op_rorw,            g65816_op_rtl, /* 6x */      g65816_op_jmp_iaddr,      g65816_op_adc_addrw,      g65816_op_ror_addrw,      g65816_op_adc_longw,
+/* 7x */            g65816_op_bvs,      g65816_op_adc_idpyw,       g65816_op_adc_idpw,      g65816_op_adc_isryw, /* 7x */       g65816_op_stz_dpxw,       g65816_op_adc_dpxw,       g65816_op_ror_dpxw,     g65816_op_adc_ildpyw, /* 7x */            g65816_op_sei,     g65816_op_adc_addryw,           g65816_op_plyb,               g65816_tdc, /* 7x */     g65816_op_jmp_iaddrx,     g65816_op_adc_addrxw,     g65816_op_ror_addrxw,     g65816_op_adc_longxw,
+
+/* 8x */            g65816_op_bra,      g65816_op_sta_idpxw,            g65816_op_brl,        g65816_op_sta_srw, /* 8x */        g65816_op_sty_dpb,        g65816_op_sta_dpw,        g65816_op_stx_dpb,      g65816_op_sta_ildpw, /* 8x */           g65816_op_deyb,     g65816_op_bit_constw,           g65816_op_txaw,            g65816_op_phb, /* 8x */      g65816_op_sty_addrb,      g65816_op_sta_addrw,      g65816_op_stx_addrb,      g65816_op_sta_longw,
+/* 9x */            g65816_op_bcc,      g65816_op_sta_idpyw,       g65816_op_sta_idpw,      g65816_op_sta_isryw, /* 9x */       g65816_op_sty_dpxb,       g65816_op_sta_dpxw,       g65816_op_stx_dpyb,     g65816_op_sta_ildpyw, /* 9x */           g65816_op_tyaw,     g65816_op_sta_addryw,           g65816_op_txsb,           g65816_op_txyb, /* 9x */      g65816_op_stz_addrw,     g65816_op_sta_addrxw,     g65816_op_stz_addrxw,     g65816_op_sta_longxw,
+/* ax */     g65816_op_ldy_constb,      g65816_op_lda_idpxw,     g65816_op_ldx_constb,        g65816_op_lda_srw, /* ax */        g65816_op_ldy_dpb,        g65816_op_lda_dpw,        g65816_op_ldx_dpb,      g65816_op_lda_ildpw, /* ax */           g65816_op_tayb,     g65816_op_lda_constw,           g65816_op_taxb,            g65816_op_plb, /* ax */      g65816_op_ldy_addrb,      g65816_op_lda_addrw,      g65816_op_ldx_addrb,      g65816_op_lda_longw,
+/* bx */            g65816_op_bcs,      g65816_op_lda_idpyw,       g65816_op_lda_idpw,      g65816_op_lda_isryw, /* bx */       g65816_op_ldy_dpxb,       g65816_op_lda_dpxw,       g65816_op_ldx_dpyb,     g65816_op_lda_ildpyw, /* bx */            g65816_op_clv,     g65816_op_lda_addryw,           g65816_op_tsxb,           g65816_op_tyxb, /* bx */     g65816_op_ldy_addrxb,     g65816_op_lda_addrxw,     g65816_op_ldx_addryb,     g65816_op_lda_longxw,
+
+/* cx */     g65816_op_cpy_constb,      g65816_op_cmp_idpxw,            g65816_op_rep,        g65816_op_cmp_srw, /* cx */        g65816_op_cpy_dpb,        g65816_op_cmp_dpw,        g65816_op_dec_dpw,      g65816_op_cmp_ildpw, /* cx */           g65816_op_inyb,     g65816_op_cmp_constw,           g65816_op_dexb,            g65816_op_wai, /* cx */      g65816_op_cpy_addrb,      g65816_op_cmp_addrw,      g65816_op_dec_addrw,      g65816_op_cmp_longw,
+/* dx */            g65816_op_bne,      g65816_op_cmp_idpyw,       g65816_op_cmp_idpw,      g65816_op_cmp_isryw, /* dx */            g65816_op_pei,       g65816_op_cmp_dpxw,       g65816_op_dec_dpxw,     g65816_op_cmp_ildpyw, /* dx */            g65816_op_cld,     g65816_op_cmp_addryw,           g65816_op_phxb,            g65816_op_stp, /* dx */     g65816_op_jmp_iladdr,     g65816_op_cmp_addrxw,     g65816_op_dec_addrxw,     g65816_op_cmp_longxw,
+/* ex */     g65816_op_cpx_constb,      g65816_op_sbc_idpxw,            g65816_op_sep,        g65816_op_sbc_srw, /* ex */        g65816_op_cpx_dpb,        g65816_op_sbc_dpw,        g65816_op_inc_dpw,      g65816_op_sbc_ildpw, /* ex */           g65816_op_inxb,     g65816_op_sbc_constw,            g65816_op_nop,            g65816_op_xba, /* ex */      g65816_op_cpx_addrb,      g65816_op_sbc_addrw,      g65816_op_inc_addrw,      g65816_op_sbc_longw,
+/* fx */            g65816_op_beq,      g65816_op_sbc_idpyw,       g65816_op_sbc_idpw,      g65816_op_sbc_isryw, /* fx */            g65816_op_pea,       g65816_op_sbc_dpxw,       g65816_op_inc_dpxw,     g65816_op_sbc_ildpyw, /* fx */            g65816_op_sed,     g65816_op_sbc_addryw,           g65816_op_plxb,            g65816_op_xce, /* fx */     g65816_op_jsr_iaddrx,     g65816_op_sbc_addrxw,     g65816_op_inc_addrxw,     g65816_op_sbc_longxw
+};
+
+vfunc g65816_optbl_mx[256] = { //                                                                                g65816_optbl_mx,                                                                                                 g65816_optbl_mx,                                                                                                 g65816_optbl_mx,
+      // ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
+/* 0x */           g65816_op_brkn,      g65816_op_ora_idpxw,           g65816_op_copn,        g65816_op_ora_srw, /* 0x */        g65816_op_tsb_dpw,        g65816_op_ora_dpw,        g65816_op_asl_dpw,      g65816_op_ora_ildpw, /* 0x */            g65816_op_php,     g65816_op_ora_constw,           g65816_op_aslw,            g65816_op_phd, /* 0x */      g65816_op_tsb_addrw,      g65816_op_ora_addrw,      g65816_op_asl_addrw,      g65816_op_ora_longw,
+/* 1x */            g65816_op_bpl,      g65816_op_ora_idpyw,       g65816_op_ora_idpw,      g65816_op_ora_isryw, /* 1x */        g65816_op_trb_dpw,       g65816_op_ora_dpxw,       g65816_op_asl_dpxw,     g65816_op_ora_ildpyw, /* 1x */            g65816_op_clc,     g65816_op_ora_addryw,           g65816_op_incw,           g65816_op_tcsn, /* 1x */      g65816_op_trb_addrw,     g65816_op_ora_addrxw,     g65816_op_asl_addrxw,     g65816_op_ora_longxw,
+/* 2x */       g65816_op_jsr_addr,      g65816_op_and_idpxw,       g65816_op_jsr_long,        g65816_op_and_srw, /* 2x */        g65816_op_bit_dpw,        g65816_op_and_dpw,        g65816_op_rol_dpw,      g65816_op_and_ildpw, /* 2x */            g65816_op_plp,     g65816_op_and_constw,           g65816_op_rolw,            g65816_op_pld, /* 2x */      g65816_op_bit_addrw,      g65816_op_and_addrw,      g65816_op_rol_addrw,      g65816_op_and_longw,
+/* 3x */            g65816_op_bmi,      g65816_op_and_idpyw,       g65816_op_and_idpw,      g65816_op_and_isryw, /* 3x */       g65816_op_bit_dpxw,       g65816_op_and_dpxw,       g65816_op_rol_dpxw,     g65816_op_and_ildpyw, /* 3x */            g65816_op_sec,     g65816_op_and_addryw,           g65816_op_decw,           g65816_op_tscn, /* 3x */     g65816_op_bit_addrxw,     g65816_op_and_addrxw,     g65816_op_rol_addrxw,     g65816_op_and_longxw,
+
+/* 4x */           g65816_op_rtin,      g65816_op_eor_idpxw,            g65816_op_wdm,        g65816_op_eor_srw, /* 4x */            g65816_op_mvp,        g65816_op_eor_dpw,        g65816_op_lsr_dpw,      g65816_op_eor_ildpw, /* 4x */           g65816_op_phaw,     g65816_op_eor_constw,           g65816_op_lsrw,            g65816_op_phk, /* 4x */       g65816_op_jmp_addr,      g65816_op_eor_addrw,      g65816_op_lsr_addrw,      g65816_op_eor_longw,
+/* 5x */            g65816_op_bvc,      g65816_op_eor_idpyw,       g65816_op_eor_idpw,      g65816_op_eor_isryw, /* 5x */            g65816_op_mvn,       g65816_op_eor_dpxw,       g65816_op_lsr_dpxw,     g65816_op_eor_ildpyw, /* 5x */            g65816_op_cli,     g65816_op_eor_addryw,           g65816_op_phyw,            g65816_op_tcd, /* 5x */       g65816_op_jmp_long,     g65816_op_eor_addrxw,     g65816_op_lsr_addrxw,     g65816_op_eor_longxw,
+/* 6x */            g65816_op_rts,      g65816_op_adc_idpxw,            g65816_op_per,        g65816_op_adc_srw, /* 6x */        g65816_op_stz_dpw,        g65816_op_adc_dpw,        g65816_op_ror_dpw,      g65816_op_adc_ildpw, /* 6x */           g65816_op_plaw,     g65816_op_adc_constw,           g65816_op_rorw,            g65816_op_rtl, /* 6x */      g65816_op_jmp_iaddr,      g65816_op_adc_addrw,      g65816_op_ror_addrw,      g65816_op_adc_longw,
+/* 7x */            g65816_op_bvs,      g65816_op_adc_idpyw,       g65816_op_adc_idpw,      g65816_op_adc_isryw, /* 7x */       g65816_op_stz_dpxw,       g65816_op_adc_dpxw,       g65816_op_ror_dpxw,     g65816_op_adc_ildpyw, /* 7x */            g65816_op_sei,     g65816_op_adc_addryw,           g65816_op_plyw,               g65816_tdc, /* 7x */     g65816_op_jmp_iaddrx,     g65816_op_adc_addrxw,     g65816_op_ror_addrxw,     g65816_op_adc_longxw,
+
+/* 8x */            g65816_op_bra,      g65816_op_sta_idpxw,            g65816_op_brl,        g65816_op_sta_srw, /* 8x */        g65816_op_sty_dpw,        g65816_op_sta_dpw,        g65816_op_stx_dpw,      g65816_op_sta_ildpw, /* 8x */           g65816_op_deyw,     g65816_op_bit_constw,           g65816_op_txaw,            g65816_op_phb, /* 8x */      g65816_op_sty_addrw,      g65816_op_sta_addrw,      g65816_op_stx_addrw,      g65816_op_sta_longw,
+/* 9x */            g65816_op_bcc,      g65816_op_sta_idpyw,       g65816_op_sta_idpw,      g65816_op_sta_isryw, /* 9x */       g65816_op_sty_dpxw,       g65816_op_sta_dpxw,       g65816_op_stx_dpyw,     g65816_op_sta_ildpyw, /* 9x */           g65816_op_tyaw,     g65816_op_sta_addryw,           g65816_op_txsw,           g65816_op_txyw, /* 9x */      g65816_op_stz_addrw,     g65816_op_sta_addrxw,     g65816_op_stz_addrxw,     g65816_op_sta_longxw,
+/* ax */     g65816_op_ldy_constw,      g65816_op_lda_idpxw,     g65816_op_ldx_constw,        g65816_op_lda_srw, /* ax */        g65816_op_ldy_dpw,        g65816_op_lda_dpw,        g65816_op_ldx_dpw,      g65816_op_lda_ildpw, /* ax */           g65816_op_tayw,     g65816_op_lda_constw,           g65816_op_taxw,            g65816_op_plb, /* ax */      g65816_op_ldy_addrw,      g65816_op_lda_addrw,      g65816_op_ldx_addrw,      g65816_op_lda_longw,
+/* bx */            g65816_op_bcs,      g65816_op_lda_idpyw,       g65816_op_lda_idpw,      g65816_op_lda_isryw, /* bx */       g65816_op_ldy_dpxw,       g65816_op_lda_dpxw,       g65816_op_ldx_dpyw,     g65816_op_lda_ildpyw, /* bx */            g65816_op_clv,     g65816_op_lda_addryw,           g65816_op_tsxw,           g65816_op_tyxw, /* bx */     g65816_op_ldy_addrxw,     g65816_op_lda_addrxw,     g65816_op_ldx_addryw,     g65816_op_lda_longxw,
+
+/* cx */     g65816_op_cpy_constw,      g65816_op_cmp_idpxw,            g65816_op_rep,        g65816_op_cmp_srw, /* cx */        g65816_op_cpy_dpw,        g65816_op_cmp_dpw,        g65816_op_dec_dpw,      g65816_op_cmp_ildpw, /* cx */           g65816_op_inyw,     g65816_op_cmp_constw,           g65816_op_dexw,            g65816_op_wai, /* cx */      g65816_op_cpy_addrw,      g65816_op_cmp_addrw,      g65816_op_dec_addrw,      g65816_op_cmp_longw,
+/* dx */            g65816_op_bne,      g65816_op_cmp_idpyw,       g65816_op_cmp_idpw,      g65816_op_cmp_isryw, /* dx */            g65816_op_pei,       g65816_op_cmp_dpxw,       g65816_op_dec_dpxw,     g65816_op_cmp_ildpyw, /* dx */            g65816_op_cld,     g65816_op_cmp_addryw,           g65816_op_phxw,            g65816_op_stp, /* dx */     g65816_op_jmp_iladdr,     g65816_op_cmp_addrxw,     g65816_op_dec_addrxw,     g65816_op_cmp_longxw,
+/* ex */     g65816_op_cpx_constw,      g65816_op_sbc_idpxw,            g65816_op_sep,        g65816_op_sbc_srw, /* ex */        g65816_op_cpx_dpw,        g65816_op_sbc_dpw,        g65816_op_inc_dpw,      g65816_op_sbc_ildpw, /* ex */           g65816_op_inxw,     g65816_op_sbc_constw,            g65816_op_nop,            g65816_op_xba, /* ex */      g65816_op_cpx_addrw,      g65816_op_sbc_addrw,      g65816_op_inc_addrw,      g65816_op_sbc_longw,
+/* fx */            g65816_op_beq,      g65816_op_sbc_idpyw,       g65816_op_sbc_idpw,      g65816_op_sbc_isryw, /* fx */            g65816_op_pea,       g65816_op_sbc_dpxw,       g65816_op_inc_dpxw,     g65816_op_sbc_ildpyw, /* fx */            g65816_op_sed,     g65816_op_sbc_addryw,           g65816_op_plxw,            g65816_op_xce, /* fx */     g65816_op_jsr_iaddrx,     g65816_op_sbc_addrxw,     g65816_op_inc_addrxw,     g65816_op_sbc_longxw
+};
diff --git a/bsnes/cpu/g65816_ops_adc.cpp b/bsnes/cpu/g65816_ops_adc.cpp
new file mode 100644
index 00000000..06134a76
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_adc.cpp
@@ -0,0 +1,345 @@
+#define bcd_add_adjust_byte()             \
+  if(gx816->regs.p & PF_D) {              \
+    if(((r     ) & 15) > 9)r += 6;        \
+    if(((r >> 4) & 15) > 9)r += 6 << 4;   \
+  }
+
+#define bcd_add_adjust_word()             \
+  if(gx816->regs.p & PF_D) {              \
+    if(((r      ) & 15) > 9)r += 6;       \
+    if(((r >>  4) & 15) > 9)r += 6 <<  4; \
+    if(((r >>  8) & 15) > 9)r += 6 <<  8; \
+    if(((r >> 12) & 15) > 9)r += 6 << 12; \
+  }
+
+#define g65816_if_adc_b()                                                    \
+byte c = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);             \
+int  r = gx816->regs.a.b + c + (gx816->regs.p & PF_C);                       \
+  bcd_add_adjust_byte()                                                      \
+  g65816_testn(r & 0x80);                                                    \
+  g65816_testv(~(gx816->regs.a.b ^ c) & (gx816->regs.a.b ^ (byte)r) & 0x80); \
+  g65816_testz((byte)r == 0);                                                \
+  g65816_testc(r > 0xff);                                                    \
+  gx816->regs.a.b = r
+
+#define g65816_if_adc_w()                                                      \
+word c = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);               \
+int  r = gx816->regs.a.w + c + (gx816->regs.p & PF_C);                         \
+  bcd_add_adjust_word()                                                        \
+  g65816_testn(r & 0x8000);                                                    \
+  g65816_testv(~(gx816->regs.a.w ^ c) & (gx816->regs.a.w ^ (word)r) & 0x8000); \
+  g65816_testz((word)r == 0);                                                  \
+  g65816_testc(r > 0xffff);                                                    \
+  gx816->regs.a.w = r
+
+void g65816_op_adc_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_if_adc_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_adc_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_if_adc_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_adc_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_if_adc_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_adc_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_if_adc_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_adc_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_idpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_idpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_ildpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_ildpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_longb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_if_adc_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_adc_longw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_if_adc_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_adc_longxb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_if_adc_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_adc_longxw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_if_adc_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_adc_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_if_adc_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_adc_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_if_adc_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_adc_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_idpxb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_idpxw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_idpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_adc_idpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_adc_ildpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_ildpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_adc_srb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_adc_srw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_adc_isryb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_if_adc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_adc_isryw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_if_adc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_adc_constb(void) {
+g65816_prefetch(1);
+int r = gx816->regs.a.b + arg + (gx816->regs.p & PF_C);
+  bcd_add_adjust_byte()
+  g65816_testn(r & 0x80);
+  g65816_testv(~(gx816->regs.a.b ^ arg) & (gx816->regs.a.b ^ (byte)r) & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r > 0xff);
+  gx816->regs.a.b = r;
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_adc_constw(void) {
+g65816_prefetch(2);
+int r = gx816->regs.a.w + arg + (gx816->regs.p & PF_C);
+  bcd_add_adjust_word()
+  g65816_testn(r & 0x8000);
+  g65816_testv(~(gx816->regs.a.w ^ arg) & (gx816->regs.a.w ^ (word)r) & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r > 0xffff);
+  gx816->regs.a.w = r;
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
diff --git a/bsnes/cpu/g65816_ops_and.cpp b/bsnes/cpu/g65816_ops_and.cpp
new file mode 100644
index 00000000..4ea42256
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_and.cpp
@@ -0,0 +1,335 @@
+#define g65816_flags_and_b() g65816_testn(gx816->regs.a.b & 0x80);   g65816_testz(gx816->regs.a.b == 0)
+#define g65816_flags_and_w() g65816_testn(gx816->regs.a.w & 0x8000); g65816_testz(gx816->regs.a.w == 0)
+
+#define g65816_inst_and_b() gx816->regs.a.b &= gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr)
+#define g65816_inst_and_w() gx816->regs.a.w &= gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr)
+
+void g65816_op_and_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_and_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_and_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_and_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_and_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_and_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_and_idpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_and_idpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_and_ildpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_and_ildpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_and_longb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_and_longw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_and_longxb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_and_longxw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_and_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_and_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_and_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_and_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_and_idpxb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_and_idpxw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_and_idpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_and_idpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_and_ildpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_and_ildpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_and_srb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_and_srw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_and_isryb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_inst_and_b();
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_and_isryw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_inst_and_w();
+  g65816_flags_and_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_and_constb(void) {
+g65816_prefetch(1);
+  gx816->regs.a.b &= arg;
+  g65816_flags_and_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_and_constw(void) {
+g65816_prefetch(2);
+  gx816->regs.a.w &= arg;
+  g65816_flags_and_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
diff --git a/bsnes/cpu/g65816_ops_cmp.cpp b/bsnes/cpu/g65816_ops_cmp.cpp
new file mode 100644
index 00000000..9eabc22a
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_cmp.cpp
@@ -0,0 +1,321 @@
+#define g65816_flags_cmp_b()                                     \
+byte c = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr); \
+int  r = gx816->regs.a.b - c;                                    \
+  g65816_testn(r & 0x80);                                        \
+  g65816_testz((byte)r == 0);                                    \
+  g65816_testc(r >= 0)
+
+#define g65816_flags_cmp_w()                                     \
+word c = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr); \
+int  r = gx816->regs.a.w - c;                                    \
+  g65816_testn(r & 0x8000);                                      \
+  g65816_testz((word)r == 0);                                    \
+  g65816_testc(r >= 0)
+
+void g65816_op_cmp_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_flags_cmp_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_cmp_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_flags_cmp_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_cmp_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_flags_cmp_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_cmp_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_flags_cmp_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_cmp_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_idpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_idpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_ildpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_ildpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_longb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_flags_cmp_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_cmp_longw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_flags_cmp_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_cmp_longxb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_flags_cmp_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_cmp_longxw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_flags_cmp_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_cmp_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_flags_cmp_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_cmp_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_flags_cmp_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_cmp_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_idpxb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_idpxw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_idpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_cmp_idpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_cmp_ildpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_ildpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cmp_srb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_cmp_srw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_cmp_isryb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_flags_cmp_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_cmp_isryw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_flags_cmp_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_cmp_constb(void) {
+g65816_prefetch(1);
+int r;
+  r = gx816->regs.a.b - arg;
+  g65816_testn(r & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_cmp_constw(void) {
+g65816_prefetch(2);
+int r;
+  r = gx816->regs.a.w - arg;
+  g65816_testn(r & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
diff --git a/bsnes/cpu/g65816_ops_eor.cpp b/bsnes/cpu/g65816_ops_eor.cpp
new file mode 100644
index 00000000..80932ee4
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_eor.cpp
@@ -0,0 +1,335 @@
+#define g65816_flags_eor_b() g65816_testn(gx816->regs.a.b & 0x80);   g65816_testz(gx816->regs.a.b == 0)
+#define g65816_flags_eor_w() g65816_testn(gx816->regs.a.w & 0x8000); g65816_testz(gx816->regs.a.w == 0)
+
+#define g65816_inst_eor_b() gx816->regs.a.b ^= gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr)
+#define g65816_inst_eor_w() gx816->regs.a.w ^= gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr)
+
+void g65816_op_eor_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_eor_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_eor_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_eor_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_eor_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_idpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_idpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_ildpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_ildpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_longb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_eor_longw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_eor_longxb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_eor_longxw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_eor_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_eor_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_eor_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_idpxb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_idpxw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_idpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_eor_idpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_eor_ildpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_ildpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_eor_srb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_eor_srw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_eor_isryb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_inst_eor_b();
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_eor_isryw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_inst_eor_w();
+  g65816_flags_eor_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_eor_constb(void) {
+g65816_prefetch(1);
+  gx816->regs.a.b ^= arg;
+  g65816_flags_eor_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_eor_constw(void) {
+g65816_prefetch(2);
+  gx816->regs.a.w ^= arg;
+  g65816_flags_eor_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
diff --git a/bsnes/cpu/g65816_ops_incdec.cpp b/bsnes/cpu/g65816_ops_incdec.cpp
new file mode 100644
index 00000000..5abaa9c7
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_incdec.cpp
@@ -0,0 +1,355 @@
+/***********
+ *** inc ***
+ **********/
+
+void g65816_op_incb(void) {
+  gx816->regs.a.b++;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_incw(void) {
+  gx816->regs.a.w++;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_inc_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  m++;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_inc_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  m++;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_inc_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  m++;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_inc_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  m++;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_inc_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  m++;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_inc_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  m++;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_inc_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  m++;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+void g65816_op_inc_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  m++;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+/***********
+ *** inx ***
+ **********/
+
+void g65816_op_inxb(void) {
+  gx816->regs.x = (gx816->regs.x + 1) & 0xff;
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz((gx816->regs.x & 0xff) == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_inxw(void) {
+  gx816->regs.x += 1;
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+/***********
+ *** iny ***
+ **********/
+
+void g65816_op_inyb(void) {
+  gx816->regs.y = (gx816->regs.y + 1) & 0xff;
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz((gx816->regs.y & 0xff) == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_inyw(void) {
+  gx816->regs.y += 1;
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+/***********
+ *** dec ***
+ **********/
+
+void g65816_op_decb(void) {
+  gx816->regs.a.b--;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_decw(void) {
+  gx816->regs.a.w--;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_dec_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  m--;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_dec_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  m--;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_dec_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  m--;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_dec_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  m--;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_dec_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  m--;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_dec_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  m--;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_dec_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  m--;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+void g65816_op_dec_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  m--;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+/***********
+ *** dex ***
+ **********/
+
+void g65816_op_dexb(void) {
+  gx816->regs.x = (gx816->regs.x - 1) & 0xff;
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz((gx816->regs.x & 0xff) == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_dexw(void) {
+  gx816->regs.x -= 1;
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+/***********
+ *** dey ***
+ **********/
+
+void g65816_op_deyb(void) {
+  gx816->regs.y = (gx816->regs.y - 1) & 0xff;
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz((gx816->regs.y & 0xff) == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_deyw(void) {
+  gx816->regs.y -= 1;
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
diff --git a/bsnes/cpu/g65816_ops_lda.cpp b/bsnes/cpu/g65816_ops_lda.cpp
new file mode 100644
index 00000000..289285cd
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_lda.cpp
@@ -0,0 +1,335 @@
+#define g65816_flags_lda_b() g65816_testn(gx816->regs.a.b & 0x80);   g65816_testz(gx816->regs.a.b == 0)
+#define g65816_flags_lda_w() g65816_testn(gx816->regs.a.w & 0x8000); g65816_testz(gx816->regs.a.w == 0)
+
+#define g65816_set_lda_b() gx816->regs.a.b = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr)
+#define g65816_set_lda_w() gx816->regs.a.w = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr)
+
+void g65816_op_lda_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_lda_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_lda_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_lda_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_lda_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_idpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_idpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_ildpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_ildpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_longb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_lda_longw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_lda_longxb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_lda_longxw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_lda_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_lda_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_lda_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_idpxb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_idpxw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_idpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_lda_idpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_lda_ildpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_ildpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_lda_srb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_lda_srw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_lda_isryb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_set_lda_b();
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_lda_isryw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_set_lda_w();
+  g65816_flags_lda_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_lda_constb(void) {
+g65816_prefetch(1);
+  gx816->regs.a.b = arg;
+  g65816_flags_lda_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_lda_constw(void) {
+g65816_prefetch(2);
+  gx816->regs.a.w = arg;
+  g65816_flags_lda_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
diff --git a/bsnes/cpu/g65816_ops_misc.cpp b/bsnes/cpu/g65816_ops_misc.cpp
new file mode 100644
index 00000000..6737a35f
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_misc.cpp
@@ -0,0 +1,1294 @@
+/***********
+ *** bit ***
+ **********/
+
+void g65816_op_bit_constb(void) {
+g65816_prefetch(1);
+  g65816_testn(arg & 0x80);
+  g65816_testv(arg & 0x40);
+  g65816_testz((arg & gx816->regs.a.b) == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_bit_constw(void) {
+g65816_prefetch(2);
+  g65816_testn(arg & 0x8000);
+  g65816_testv(arg & 0x4000);
+  g65816_testz((arg & gx816->regs.a.w) == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
+
+void g65816_op_bit_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  arg = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(arg & 0x80);
+  g65816_testv(arg & 0x40);
+  g65816_testz((arg & gx816->regs.a.b) == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_bit_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  arg = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(arg & 0x8000);
+  g65816_testv(arg & 0x4000);
+  g65816_testz((arg & gx816->regs.a.w) == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_bit_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  arg = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(arg & 0x80);
+  g65816_testv(arg & 0x40);
+  g65816_testz((arg & gx816->regs.a.b) == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_bit_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  arg = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(arg & 0x8000);
+  g65816_testv(arg & 0x4000);
+  g65816_testz((arg & gx816->regs.a.w) == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_bit_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  arg = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(arg & 0x80);
+  g65816_testv(arg & 0x40);
+  g65816_testz((arg & gx816->regs.a.b) == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_bit_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  arg = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(arg & 0x8000);
+  g65816_testv(arg & 0x4000);
+  g65816_testz((arg & gx816->regs.a.w) == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_bit_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  arg = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(arg & 0x80);
+  g65816_testv(arg & 0x40);
+  g65816_testz((arg & gx816->regs.a.b) == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_bit_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  arg = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(arg & 0x8000);
+  g65816_testv(arg & 0x4000);
+  g65816_testz((arg & gx816->regs.a.w) == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+/***********
+ *** cpx ***
+ **********/
+
+void g65816_op_cpx_constb(void) {
+g65816_prefetch(1);
+int r = gx816->regs.x - arg;
+  g65816_testn(r & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_cpx_constw(void) {
+g65816_prefetch(2);
+int r = gx816->regs.x - arg;
+  g65816_testn(r & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
+
+void g65816_op_cpx_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+int r = gx816->regs.x - gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(r & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_cpx_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+int r = gx816->regs.x - gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(r & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_cpx_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+int r = gx816->regs.x - gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(r & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cpx_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+int r = gx816->regs.x - gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(r & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+/***********
+ *** cpy ***
+ **********/
+
+void g65816_op_cpy_constb(void) {
+g65816_prefetch(1);
+int r = gx816->regs.y - arg;
+  g65816_testn(r & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_cpy_constw(void) {
+g65816_prefetch(2);
+int r = gx816->regs.y - arg;
+  g65816_testn(r & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
+
+void g65816_op_cpy_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+int r = gx816->regs.y - gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(r & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_cpy_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+int r = gx816->regs.y - gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(r & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_cpy_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+int r = gx816->regs.y - gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(r & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_cpy_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+int r = gx816->regs.y - gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(r & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r >= 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+/***********
+ *** ldx ***
+ **********/
+
+void g65816_op_ldx_constb(void) {
+g65816_prefetch(1);
+  gx816->regs.x = arg;
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_ldx_constw(void) {
+g65816_prefetch(2);
+  gx816->regs.x = arg;
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
+
+void g65816_op_ldx_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->regs.x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_ldx_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->regs.x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_ldx_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  gx816->regs.x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_ldx_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  gx816->regs.x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_ldx_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->regs.x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ldx_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->regs.x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ldx_dpyb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPY);
+  gx816->regs.x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_ldx_dpyw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPY);
+  gx816->regs.x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+/***********
+ *** ldy ***
+ **********/
+
+void g65816_op_ldy_constb(void) {
+g65816_prefetch(1);
+  gx816->regs.y = (gx816->regs.y & 0xff00) | arg;
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_ldy_constw(void) {
+g65816_prefetch(2);
+  gx816->regs.y = arg;
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
+
+void g65816_op_ldy_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->regs.y = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_ldy_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->regs.y = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_ldy_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  gx816->regs.y = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_ldy_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  gx816->regs.y = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_ldy_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->regs.y = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ldy_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->regs.y = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ldy_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  gx816->regs.y = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_ldy_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  gx816->regs.y = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+/***********
+ *** stx ***
+ **********/
+
+void g65816_op_stx_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, gx816->regs.x);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_stx_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, gx816->regs.x);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_stx_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, gx816->regs.x);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_stx_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, gx816->regs.x);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_stx_dpyb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPY);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, gx816->regs.x);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_stx_dpyw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPY);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, gx816->regs.x);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+/***********
+ *** sty ***
+ **********/
+
+void g65816_op_sty_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, gx816->regs.y);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_sty_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, gx816->regs.y);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_sty_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, gx816->regs.y);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sty_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, gx816->regs.y);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sty_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, gx816->regs.y);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sty_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, gx816->regs.y);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+/***********
+ *** stz ***
+ **********/
+
+void g65816_op_stz_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_stz_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_stz_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_stz_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, 0);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_stz_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_stz_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_stz_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_stz_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, 0);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+/***********
+ *** xba ***
+ **********/
+
+void g65816_op_xba(void) {
+  gx816->regs.a.p.l ^= gx816->regs.a.p.h;
+  gx816->regs.a.p.h ^= gx816->regs.a.p.l;
+  gx816->regs.a.p.l ^= gx816->regs.a.p.h;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(2);
+}
+
+/***********
+ *** trb ***
+ **********/
+
+void g65816_op_trb_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testz((m & gx816->regs.a.b) == 0);
+  m &= ~gx816->regs.a.b;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_trb_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testz((m & gx816->regs.a.w) == 0);
+  m &= ~gx816->regs.a.w;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_trb_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testz((m & gx816->regs.a.b) == 0);
+  m &= ~gx816->regs.a.b;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_trb_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testz((m & gx816->regs.a.w) == 0);
+  m &= ~gx816->regs.a.w;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+/***********
+ *** tsb ***
+ **********/
+
+void g65816_op_tsb_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testz((m & gx816->regs.a.b) == 0);
+  m |= gx816->regs.a.b;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tsb_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testz((m & gx816->regs.a.w) == 0);
+  m |= gx816->regs.a.w;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tsb_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testz((m & gx816->regs.a.b) == 0);
+  m |= gx816->regs.a.b;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_tsb_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testz((m & gx816->regs.a.w) == 0);
+  m |= gx816->regs.a.w;
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+/***********
+ *** mvn ***
+ **********/
+
+void g65816_op_mvn(void) {
+g65816_prefetch(2);
+ulong sp, dp;
+byte m;
+  if(gx816->regs.a.w != 0xffff) {
+    gx816->regs.a.w--;
+    dp = (arg) & 0xff;
+    sp = (arg >> 8) & 0xff;
+    dp = (dp << 16) | gx816->regs.y;
+    sp = (sp << 16) | gx816->regs.x;
+    m = gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, sp);
+    gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, dp, m);
+    gx816->regs.x++;
+    gx816->regs.y++;
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X))) {
+      gx816->regs.x &= 0xff;
+      gx816->regs.y &= 0xff;
+    }
+  }
+  if(gx816->regs.a.w == 0xffff) {
+    g65816_incpc(3);
+  }
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, sp);
+  snes_time->add_cpu_mcycles(1, dp);
+  snes_time->add_cpu_icycles(2);
+}
+
+/***********
+ *** mvp ***
+ **********/
+
+void g65816_op_mvp(void) {
+g65816_prefetch(2);
+ulong sp, dp;
+byte m;
+  if(gx816->regs.a.w != 0xffff) {
+    gx816->regs.a.w--;
+    dp = (arg) & 0xff;
+    sp = (arg >> 8) & 0xff;
+    dp = (dp << 16) | gx816->regs.y;
+    sp = (sp << 16) | gx816->regs.x;
+    m = gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, sp);
+    gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, dp, m);
+    gx816->regs.x--;
+    gx816->regs.y--;
+    if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X))) {
+      gx816->regs.x &= 0xff;
+      gx816->regs.y &= 0xff;
+    }
+  }
+  if(gx816->regs.a.w == 0xffff) {
+    g65816_incpc(3);
+  }
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, sp);
+  snes_time->add_cpu_mcycles(1, dp);
+  snes_time->add_cpu_icycles(2);
+}
+
+/***********
+ *** brk ***
+ **********/
+
+void g65816_op_brke(void) {
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(3);
+  snes_time->add_cpu_mcycles(2, 0x00ffe6);
+  g65816_incpc(2);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.pc);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.p);
+  g65816_seti();
+  g65816_clrd();
+  gx816->regs.pc = gx816->mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00ffe6);
+}
+
+void g65816_op_brkn(void) {
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(4);
+  snes_time->add_cpu_mcycles(2, 0x00ffe6);
+  g65816_incpc(2);
+  g65816_stackwrite(MEMSIZE_LONG, gx816->regs.pc);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.p);
+  g65816_seti();
+  g65816_clrd();
+  gx816->regs.pc = gx816->mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00ffe6);
+}
+
+/***********
+ *** cop ***
+ **********/
+
+void g65816_op_cope(void) {
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(3);
+  snes_time->add_cpu_mcycles(2, 0x00fff4);
+  g65816_incpc(2);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.pc);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.p);
+  g65816_seti();
+  g65816_clrd();
+  gx816->regs.pc = gx816->mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00fff4);
+}
+
+void g65816_op_copn(void) {
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(4);
+  snes_time->add_cpu_mcycles(2, 0x00fff4);
+  g65816_incpc(2);
+  g65816_stackwrite(MEMSIZE_LONG, gx816->regs.pc);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.p);
+  g65816_seti();
+  g65816_clrd();
+  gx816->regs.pc = gx816->mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00fff4);
+}
+
+/***********
+ *** stp ***
+ **********/
+
+void g65816_op_stp(void) {
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(2);
+  dprintf("* stp not implemented");
+}
+
+/***********
+ *** wai ***
+ **********/
+
+void g65816_op_wai(void) {
+byte i = 0;
+  if(gx816->nmi_enabled == true)i = 1;
+  if((ppu.vcounter_enabled == true || ppu.hcounter_enabled == true) && !(gx816->regs.p & PF_I))i = 1;
+  if(gx816->wai_interrupt_occurred == true || i == 0) {
+    gx816->wai_interrupt_occurred = false;
+    g65816_incpc(1);
+  }
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(2);
+}
+
+/***********
+ *** xce ***
+ **********/
+
+void g65816_op_xce(void) {
+bool t = gx816->regs.e;
+  if(gx816->regs.p & PF_C)gx816->regs.e = true;
+  else                    gx816->regs.e = false;
+  g65816_setm();
+  g65816_setx();
+  if(t == true)g65816_setc();
+  else         g65816_clrc();
+
+  if(gx816->regs.e == true)gx816->regs.s = 0x0100 | (gx816->regs.s & 0xff);
+
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+/***********
+ *** nop ***
+ **********/
+
+void g65816_op_nop(void) {
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+/***********
+ *** wdm ***
+ **********/
+
+void g65816_op_wdm(void) {
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+/*****************************
+ *** clear/set bit opcodes ***
+ ****************************/
+
+void g65816_op_clc(void) {
+  g65816_clrc();
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_cld(void) {
+  g65816_clrd();
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_cli(void) {
+  g65816_clri();
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_clv(void) {
+  g65816_clrv();
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_sec(void) {
+  g65816_setc();
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_sed(void) {
+  g65816_setd();
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_sei(void) {
+  g65816_seti();
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_rep(void) {
+g65816_prefetch(1);
+  gx816->regs.p &= ~arg;
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(3);
+
+  if(gx816->regs.e == true)gx816->regs.p |= 0x30;
+}
+
+void g65816_op_sep(void) {
+g65816_prefetch(1);
+  gx816->regs.p |= arg;
+  if(arg & 0x10) {
+    gx816->regs.x &= 0xff;
+    gx816->regs.y &= 0xff;
+  }
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(3);
+}
+
+/************************
+ *** transfer opcodes ***
+ ***********************/
+
+void g65816_op_taxb(void) {
+  gx816->regs.x = gx816->regs.a.b;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_taxw(void) {
+  gx816->regs.x = gx816->regs.a.w;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tayb(void) {
+  gx816->regs.y = gx816->regs.a.b;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tayw(void) {
+  gx816->regs.y = gx816->regs.a.w;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tcd(void) {
+  gx816->regs.d = gx816->regs.a.w;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tcse(void) {
+  gx816->regs.s = 0x0100 | gx816->regs.a.b;
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tcsn(void) {
+  gx816->regs.s = gx816->regs.a.w;
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_tdc(void) {
+  gx816->regs.a.w = gx816->regs.d;
+  g65816_testn(gx816->regs.d & 0x8000);
+  g65816_testz(gx816->regs.d == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tsce(void) {
+  gx816->regs.a.w = gx816->regs.s;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tscn(void) {
+  gx816->regs.a.w = gx816->regs.s;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tsxb(void) {
+  gx816->regs.x = gx816->regs.s & 0xff;
+  g65816_testn(gx816->regs.s & 0x80);
+  g65816_testz((gx816->regs.s & 0xff) == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tsxw(void) {
+  gx816->regs.x = gx816->regs.s;
+  g65816_testn(gx816->regs.s & 0x8000);
+  g65816_testz(gx816->regs.s == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_txab(void) {
+  gx816->regs.a.b = gx816->regs.x;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_txaw(void) {
+  gx816->regs.a.w = gx816->regs.x;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_txsb(void) {
+  gx816->regs.s = gx816->regs.x;
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz((gx816->regs.x & 0xff) == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_txsw(void) {
+  gx816->regs.s = gx816->regs.x;
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_txyb(void) {
+  gx816->regs.y = gx816->regs.x;
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz((gx816->regs.x & 0xff) == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_txyw(void) {
+  gx816->regs.y = gx816->regs.x;
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tyab(void) {
+  gx816->regs.a.b = gx816->regs.y;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tyaw(void) {
+  gx816->regs.a.w = gx816->regs.y;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tyxb(void) {
+  gx816->regs.x = gx816->regs.y;
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz((gx816->regs.y & 0xff) == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_tyxw(void) {
+  gx816->regs.x = gx816->regs.y;
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
diff --git a/bsnes/cpu/g65816_ops_ora.cpp b/bsnes/cpu/g65816_ops_ora.cpp
new file mode 100644
index 00000000..f6aa2d75
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_ora.cpp
@@ -0,0 +1,335 @@
+#define g65816_flags_ora_b() g65816_testn(gx816->regs.a.b & 0x80);   g65816_testz(gx816->regs.a.b == 0)
+#define g65816_flags_ora_w() g65816_testn(gx816->regs.a.w & 0x8000); g65816_testz(gx816->regs.a.w == 0)
+
+#define g65816_inst_ora_b() gx816->regs.a.b |= gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr)
+#define g65816_inst_ora_w() gx816->regs.a.w |= gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr)
+
+void g65816_op_ora_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_ora_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_ora_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_ora_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_ora_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_idpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_idpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_ildpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_ildpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_longb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_ora_longw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_ora_longxb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_ora_longxw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_ora_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_ora_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_ora_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_idpxb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_idpxw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_idpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_ora_idpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_ora_ildpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_ildpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_ora_srb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_ora_srw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_ora_isryb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_inst_ora_b();
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_ora_isryw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_inst_ora_w();
+  g65816_flags_ora_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_ora_constb(void) {
+g65816_prefetch(1);
+  gx816->regs.a.b |= arg;
+  g65816_flags_ora_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_ora_constw(void) {
+g65816_prefetch(2);
+  gx816->regs.a.w |= arg;
+  g65816_flags_ora_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
diff --git a/bsnes/cpu/g65816_ops_pc.cpp b/bsnes/cpu/g65816_ops_pc.cpp
new file mode 100644
index 00000000..efa52755
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_pc.cpp
@@ -0,0 +1,223 @@
+/***********
+ *** jmp ***
+ **********/
+
+void g65816_op_jmp_addr(void) {
+g65816_prefetch(2);
+  snes_time->add_cpu_pcycles(3);
+  gx816->regs.pc = (gx816->regs.pc & 0xff0000) | arg;
+}
+
+void g65816_op_jmp_long(void) {
+g65816_prefetch(3);
+  snes_time->add_cpu_pcycles(4);
+  gx816->regs.pc = arg;
+}
+
+void g65816_op_jmp_iaddr(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_IADDR_PC);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+}
+
+void g65816_op_jmp_iaddrx(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_IADDRX_PC);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+  gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+}
+
+void g65816_op_jmp_iladdr(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ILADDR_PC);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(3, dest_addr);
+  gx816->regs.pc = gx816->mem_read(MEMMODE_NONE, MEMSIZE_LONG, dest_addr);
+}
+
+/***********
+ *** jsr ***
+ **********/
+
+//Note: The address pushed onto the stack is one byte less than the operand size.
+//Upon returning, the address counter is incremented one more to move to the next
+//instruction. The third/fourth cycles store the pc address on the stack, before
+//the second operand byte is read in.
+
+void g65816_op_jsr_addr(void) {
+g65816_prefetch(2);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.pc + 2);
+  gx816->regs.pc = (gx816->regs.pc & 0xff0000) | arg;
+}
+
+void g65816_op_jsr_long(void) {
+g65816_prefetch(3);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_scycles(3);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_LONG, gx816->regs.pc + 3);
+  gx816->regs.pc = arg;
+}
+
+void g65816_op_jsr_iaddrx(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_IADDRX_PC);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.pc + 2);
+  gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->mem_read(MEMMODE_IADDRX_PC, MEMSIZE_WORD, arg);
+  snes_time->add_cpu_pcycles(2);
+}
+
+/***********
+ *** ret ***
+ **********/
+
+void g65816_op_rtie(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(3);
+  gx816->regs.p  = g65816_stackread(MEMSIZE_BYTE);
+  gx816->regs.pc = (gx816->regs.pc & 0xff0000) | g65816_stackread(MEMSIZE_WORD);
+  if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
+  gx816->regs.p &= ~ PF_I;
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_rtin(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(4);
+  gx816->regs.p  = g65816_stackread(MEMSIZE_BYTE);
+  gx816->regs.pc = g65816_stackread(MEMSIZE_LONG);
+  if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_rts(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(3);
+  gx816->regs.pc = ((gx816->regs.pc & 0xff0000) | g65816_stackread(MEMSIZE_WORD)) + 1;
+}
+
+void g65816_op_rtl(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(3);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.pc = g65816_stackread(MEMSIZE_LONG) + 1;
+}
+
+/***********
+ *** bra ***
+ **********/
+
+//Need to add condition (5) to cycle counts: if e=1, add one (i)cycle if page boundary crossed
+
+void g65816_op_bra(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_icycles(1);
+  gx816->regs.pc += (signed char)(arg + 2);
+}
+
+void g65816_op_brl(void) {
+g65816_prefetch(2);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_icycles(1);
+  gx816->regs.pc += (signed short)(arg + 3);
+}
+
+void g65816_op_bcc(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  if(!(gx816->regs.p & PF_C)) {
+    snes_time->add_cpu_icycles(1);
+    gx816->regs.pc += (signed char)(arg + 2);
+  } else {
+    g65816_incpc(2);
+  }
+}
+
+void g65816_op_bcs(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  if(gx816->regs.p & PF_C) {
+    snes_time->add_cpu_icycles(1);
+    gx816->regs.pc += (signed char)(arg + 2);
+  } else {
+    g65816_incpc(2);
+  }
+}
+
+void g65816_op_bne(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  if(!(gx816->regs.p & PF_Z)) {
+    snes_time->add_cpu_icycles(1);
+    gx816->regs.pc += (signed char)(arg + 2);
+  } else {
+    g65816_incpc(2);
+  }
+}
+
+void g65816_op_beq(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  if(gx816->regs.p & PF_Z) {
+    snes_time->add_cpu_icycles(1);
+    gx816->regs.pc += (signed char)(arg + 2);
+  } else {
+    g65816_incpc(2);
+  }
+}
+
+void g65816_op_bpl(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  if(!(gx816->regs.p & PF_N)) {
+    snes_time->add_cpu_icycles(1);
+    gx816->regs.pc += (signed char)(arg + 2);
+  } else {
+    g65816_incpc(2);
+  }
+}
+
+void g65816_op_bmi(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  if(gx816->regs.p & PF_N) {
+    snes_time->add_cpu_icycles(1);
+    gx816->regs.pc += (signed char)(arg + 2);
+  } else {
+    g65816_incpc(2);
+  }
+}
+
+void g65816_op_bvc(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  if(!(gx816->regs.p & PF_V)) {
+    snes_time->add_cpu_icycles(1);
+    gx816->regs.pc += (signed char)(arg + 2);
+  } else {
+    g65816_incpc(2);
+  }
+}
+
+void g65816_op_bvs(void) {
+g65816_prefetch(1);
+  snes_time->add_cpu_pcycles(2);
+  if(gx816->regs.p & PF_V) {
+    snes_time->add_cpu_icycles(1);
+    gx816->regs.pc += (signed char)(arg + 2);
+  } else {
+    g65816_incpc(2);
+  }
+}
diff --git a/bsnes/cpu/g65816_ops_sbc.cpp b/bsnes/cpu/g65816_ops_sbc.cpp
new file mode 100644
index 00000000..f5f3c076
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_sbc.cpp
@@ -0,0 +1,345 @@
+#define bcd_sub_adjust_byte()             \
+  if(gx816->regs.p & PF_D) {              \
+    if(((r     ) & 15) > 9)r -= 6;        \
+    if(((r >> 4) & 15) > 9)r -= 6 << 4;   \
+  }
+
+#define bcd_sub_adjust_word()             \
+  if(gx816->regs.p & PF_D) {              \
+    if(((r      ) & 15) > 9)r -= 6;       \
+    if(((r >>  4) & 15) > 9)r -= 6 <<  4; \
+    if(((r >>  8) & 15) > 9)r -= 6 <<  8; \
+    if(((r >> 12) & 15) > 9)r -= 6 << 12; \
+  }
+
+#define g65816_if_sbc_b()                                                   \
+byte c = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);            \
+int  r = gx816->regs.a.b - c - !(gx816->regs.p & PF_C);                     \
+  bcd_sub_adjust_byte()                                                     \
+  g65816_testn(r & 0x80);                                                   \
+  g65816_testv((gx816->regs.a.b ^ c) & (gx816->regs.a.b ^ (byte)r) & 0x80); \
+  g65816_testz((byte)r == 0);                                               \
+  g65816_testc(r >= 0);                                                     \
+  gx816->regs.a.b = r
+
+#define g65816_if_sbc_w()                                                     \
+word c = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);              \
+int  r = gx816->regs.a.w - c - !(gx816->regs.p & PF_C);                       \
+  bcd_sub_adjust_word()                                                       \
+  g65816_testn(r & 0x8000);                                                   \
+  g65816_testv((gx816->regs.a.w ^ c) & (gx816->regs.a.w ^ (word)r) & 0x8000); \
+  g65816_testz((word)r == 0);                                                 \
+  g65816_testc(r >= 0);                                                       \
+  gx816->regs.a.w = r
+
+void g65816_op_sbc_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_if_sbc_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_sbc_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_if_sbc_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_sbc_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_if_sbc_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_sbc_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_if_sbc_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_sbc_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_idpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_idpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_ildpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_ildpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_longb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_if_sbc_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_sbc_longw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_if_sbc_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_sbc_longxb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_if_sbc_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_sbc_longxw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_if_sbc_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_sbc_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_if_sbc_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_sbc_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_if_sbc_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_sbc_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_idpxb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_idpxw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_idpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_sbc_idpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_sbc_ildpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_ildpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sbc_srb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_sbc_srw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_sbc_isryb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_if_sbc_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_sbc_isryw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_if_sbc_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_sbc_constb(void) {
+g65816_prefetch(1);
+int r = gx816->regs.a.b - arg - !(gx816->regs.p & PF_C);
+  bcd_sub_adjust_byte()
+  g65816_testn(r & 0x80);
+  g65816_testv((gx816->regs.a.b ^ arg) & (gx816->regs.a.b ^ (byte)r) & 0x80);
+  g65816_testz((byte)r == 0);
+  g65816_testc(r >= 0);
+  gx816->regs.a.b = r;
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+}
+
+void g65816_op_sbc_constw(void) {
+g65816_prefetch(2);
+int r = gx816->regs.a.w - arg - !(gx816->regs.p & PF_C);
+  bcd_sub_adjust_word()
+  g65816_testn(r & 0x8000);
+  g65816_testv((gx816->regs.a.w ^ arg) & (gx816->regs.a.w ^ (word)r) & 0x8000);
+  g65816_testz((word)r == 0);
+  g65816_testc(r >= 0);
+  gx816->regs.a.w = r;
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+}
diff --git a/bsnes/cpu/g65816_ops_shift.cpp b/bsnes/cpu/g65816_ops_shift.cpp
new file mode 100644
index 00000000..2e61d5f8
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_shift.cpp
@@ -0,0 +1,595 @@
+/**********
+*** asl ***
+**********/
+
+void g65816_op_aslb(void) {
+  g65816_testc(gx816->regs.a.b & 0x80);
+  gx816->regs.a.b <<= 1;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_aslw(void) {
+  g65816_testc(gx816->regs.a.w & 0x8000);
+  gx816->regs.a.w <<= 1;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_asl_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x80);
+  m <<= 1;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_asl_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x8000);
+  m <<= 1;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_asl_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x80);
+  m <<= 1;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_asl_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x8000);
+  m <<= 1;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_asl_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x80);
+  m <<= 1;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_asl_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x8000);
+  m <<= 1;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_asl_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x80);
+  m <<= 1;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+void g65816_op_asl_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x8000);
+  m <<= 1;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+/**********
+*** lsr ***
+**********/
+
+void g65816_op_lsrb(void) {
+  g65816_testc(gx816->regs.a.b & 0x01);
+  gx816->regs.a.b >>= 1;
+  g65816_clrn();
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_lsrw(void) {
+  g65816_testc(gx816->regs.a.w & 0x0001);
+  gx816->regs.a.w >>= 1;
+  g65816_clrn();
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_lsr_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x01);
+  m >>= 1;
+  g65816_clrn();
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_lsr_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x0001);
+  m >>= 1;
+  g65816_clrn();
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_lsr_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x01);
+  m >>= 1;
+  g65816_clrn();
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_lsr_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x0001);
+  m >>= 1;
+  g65816_clrn();
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_lsr_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x01);
+  m >>= 1;
+  g65816_clrn();
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_lsr_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x0001);
+  m >>= 1;
+  g65816_clrn();
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_lsr_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x01);
+  m >>= 1;
+  g65816_clrn();
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+void g65816_op_lsr_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x0001);
+  m >>= 1;
+  g65816_clrn();
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+/**********
+*** rol ***
+**********/
+
+void g65816_op_rolb(void) {
+byte c = gx816->regs.p & PF_C;
+  g65816_testc(gx816->regs.a.b & 0x80);
+  gx816->regs.a.b = (gx816->regs.a.b << 1) | c;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_rolw(void) {
+byte c = gx816->regs.p & PF_C;
+  g65816_testc(gx816->regs.a.w & 0x8000);
+  gx816->regs.a.w = (gx816->regs.a.w << 1) | c;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_rol_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte c = gx816->regs.p & PF_C;
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x80);
+  m = (m << 1) | c;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_rol_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte c = gx816->regs.p & PF_C;
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x8000);
+  m = (m << 1) | c;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_rol_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+byte c = gx816->regs.p & PF_C;
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x80);
+  m = (m << 1) | c;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_rol_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+byte c = gx816->regs.p & PF_C;
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x8000);
+  m = (m << 1) | c;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_rol_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte c = gx816->regs.p & PF_C;
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x80);
+  m = (m << 1) | c;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_rol_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte c = gx816->regs.p & PF_C;
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x8000);
+  m = (m << 1) | c;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_rol_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+byte c = gx816->regs.p & PF_C;
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x80);
+  m = (m << 1) | c;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+void g65816_op_rol_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+byte c = gx816->regs.p & PF_C;
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, arg);
+  g65816_testc(m & 0x8000);
+  m = (m << 1) | c;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, arg, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+/**********
+*** ror ***
+**********/
+
+void g65816_op_rorb(void) {
+byte c = (gx816->regs.p & PF_C)?0x80:0x00;
+  g65816_testc(gx816->regs.a.b & 0x01);
+  gx816->regs.a.b = (gx816->regs.a.b >> 1) | c;
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_rorw(void) {
+word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
+  g65816_testc(gx816->regs.a.w & 0x0001);
+  gx816->regs.a.w = (gx816->regs.a.w >> 1) | c;
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_ror_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+byte c = (gx816->regs.p & PF_C)?0x80:0x00;
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x01);
+  m = (m >> 1) | c;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_ror_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x0001);
+  m = (m >> 1) | c;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_ror_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+byte c = (gx816->regs.p & PF_C)?0x80:0x00;
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x01);
+  m = (m >> 1) | c;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_ror_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x0001);
+  m = (m >> 1) | c;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_ror_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+byte c = (gx816->regs.p & PF_C)?0x80:0x00;
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x01);
+  m = (m >> 1) | c;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_ror_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x0001);
+  m = (m >> 1) | c;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_REGD);
+}
+
+void g65816_op_ror_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+byte c = (gx816->regs.p & PF_C)?0x80:0x00;
+byte m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr);
+  g65816_testc(m & 0x01);
+  m = (m >> 1) | c;
+  g65816_testn(m & 0x80);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
+
+void g65816_op_ror_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
+word m = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr);
+  g65816_testc(m & 0x0001);
+  m = (m >> 1) | c;
+  g65816_testn(m & 0x8000);
+  g65816_testz(m == 0);
+  gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, m);
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(4, dest_addr);
+  snes_time->add_cpu_icycles(2, TIMING_REGD);
+}
diff --git a/bsnes/cpu/g65816_ops_sta.cpp b/bsnes/cpu/g65816_ops_sta.cpp
new file mode 100644
index 00000000..5f2069cc
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_sta.cpp
@@ -0,0 +1,288 @@
+#define g65816_sta_data_b() gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dest_addr, gx816->regs.a.b)
+#define g65816_sta_data_w() gx816->mem_write(MEMMODE_NONE, MEMSIZE_WORD, dest_addr, gx816->regs.a.w)
+
+void g65816_op_sta_addrb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_sta_data_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_sta_addrw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDR);
+  g65816_sta_data_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_sta_addrxb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_sta_data_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_sta_addrxw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRX);
+  g65816_sta_data_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_sta_dpb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_dpw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_idpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_idpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDP);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_ildpb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_ildpw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDP);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_longb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_sta_data_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_sta_longw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONG);
+  g65816_sta_data_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_sta_longxb(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_sta_data_b();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+}
+
+void g65816_op_sta_longxw(void) {
+g65816_prefetch(3);
+g65816_getaddr(MEMMODE_LONGX);
+  g65816_sta_data_w();
+  g65816_incpc(4);
+  snes_time->add_cpu_pcycles(4);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+}
+
+void g65816_op_sta_addryb(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_sta_data_b();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_sta_addryw(void) {
+g65816_prefetch(2);
+g65816_getaddr(MEMMODE_ADDRY);
+  g65816_sta_data_w();
+  g65816_incpc(3);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION4);
+}
+
+void g65816_op_sta_dpxb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_dpxw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DPX);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_idpxb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_idpxw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPX);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(1, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_idpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_sta_idpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_IDPY);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2 | TIMING_CONDITION4);
+}
+
+void g65816_op_sta_ildpyb(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_ildpyw(void) {
+g65816_prefetch(1);
+g65816_getiaddr(MEMMODE_ILDPY);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(3, base_addr);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(0, TIMING_CONDITION2);
+}
+
+void g65816_op_sta_srb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_sta_srw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_SR);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+}
+
+void g65816_op_sta_isryb(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_sta_data_b();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(1, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
+
+void g65816_op_sta_isryw(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_ISRY);
+  g65816_sta_data_w();
+  g65816_incpc(2);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_icycles(2);
+}
diff --git a/bsnes/cpu/g65816_ops_stack.cpp b/bsnes/cpu/g65816_ops_stack.cpp
new file mode 100644
index 00000000..a126db5c
--- /dev/null
+++ b/bsnes/cpu/g65816_ops_stack.cpp
@@ -0,0 +1,243 @@
+ulong g65816_stackread(byte size) {
+ulong r = 0;
+  if(size == MEMSIZE_BYTE) {
+    gx816->regs.s++;
+    r  = gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s);
+  } else if(size == MEMSIZE_WORD) {
+    gx816->regs.s++;
+    r  = gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s);
+    gx816->regs.s++;
+    r |= gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s) << 8;
+  } else if(size == MEMSIZE_LONG) {
+    gx816->regs.s++;
+    r  = gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s);
+    gx816->regs.s++;
+    r |= gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s) << 8;
+    gx816->regs.s++;
+    r |= gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s) << 16;
+  }
+  if(gx816->regs.e == true) {
+    gx816->regs.s = 0x0100 | (gx816->regs.s & 0xff);
+  }
+  return r;
+}
+
+void g65816_stackwrite(byte size, ulong value) {
+  if(size == MEMSIZE_BYTE) {
+    gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s, value);
+    gx816->regs.s--;
+  } else if(size == MEMSIZE_WORD) {
+    gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s, value >> 8);
+    gx816->regs.s--;
+    gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s, value);
+    gx816->regs.s--;
+  } else if(size == MEMSIZE_LONG) {
+    gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s, value >> 16);
+    gx816->regs.s--;
+    gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s, value >> 8);
+    gx816->regs.s--;
+    gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, gx816->regs.s, value);
+    gx816->regs.s--;
+  }
+  if(gx816->regs.e == true) {
+    gx816->regs.s = 0x0100 | (gx816->regs.s & 0xff);
+  }
+}
+
+void g65816_op_phab(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.a.b);
+  g65816_incpc(1);
+}
+
+void g65816_op_phaw(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.a.w);
+  g65816_incpc(1);
+}
+
+void g65816_op_phb(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.db);
+  g65816_incpc(1);
+}
+
+void g65816_op_phd(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.d);
+  g65816_incpc(1);
+}
+
+void g65816_op_phk(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.pc >> 16);
+  g65816_incpc(1);
+}
+
+void g65816_op_php(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.p);
+  g65816_incpc(1);
+}
+
+void g65816_op_phxb(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.x);
+  g65816_incpc(1);
+}
+
+void g65816_op_phxw(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.x);
+  g65816_incpc(1);
+}
+
+void g65816_op_phyb(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_BYTE, gx816->regs.y);
+  g65816_incpc(1);
+}
+
+void g65816_op_phyw(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.y);
+  g65816_incpc(1);
+}
+
+void g65816_op_plab(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.a.b = g65816_stackread(MEMSIZE_BYTE);
+  g65816_testn(gx816->regs.a.b & 0x80);
+  g65816_testz(gx816->regs.a.b == 0);
+  g65816_incpc(1);
+}
+
+void g65816_op_plaw(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.a.w = g65816_stackread(MEMSIZE_WORD);
+  g65816_testn(gx816->regs.a.w & 0x8000);
+  g65816_testz(gx816->regs.a.w == 0);
+  g65816_incpc(1);
+}
+
+void g65816_op_plb(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.db = g65816_stackread(MEMSIZE_BYTE);
+  g65816_testn(gx816->regs.db & 0x80);
+  g65816_testz(gx816->regs.db == 0);
+  g65816_incpc(1);
+}
+
+void g65816_op_pld(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.d = g65816_stackread(MEMSIZE_WORD);
+  g65816_testn(gx816->regs.d & 0x8000);
+  g65816_testz(gx816->regs.d == 0);
+  g65816_incpc(1);
+}
+
+void g65816_op_plp(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.p = g65816_stackread(MEMSIZE_BYTE);
+  g65816_incpc(1);
+  if(gx816->regs.e == true)gx816->regs.p |= 0x30;
+  if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
+}
+
+void g65816_op_plxb(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.x = g65816_stackread(MEMSIZE_BYTE);
+  g65816_testn(gx816->regs.x & 0x80);
+  g65816_testz((gx816->regs.x & 0xff) == 0);
+  g65816_incpc(1);
+}
+
+void g65816_op_plxw(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.x = g65816_stackread(MEMSIZE_WORD);
+  g65816_testn(gx816->regs.x & 0x8000);
+  g65816_testz(gx816->regs.x == 0);
+  g65816_incpc(1);
+}
+
+void g65816_op_plyb(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(1);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.y = g65816_stackread(MEMSIZE_BYTE);
+  g65816_testn(gx816->regs.y & 0x80);
+  g65816_testz((gx816->regs.y & 0xff) == 0);
+  g65816_incpc(1);
+}
+
+void g65816_op_plyw(void) {
+  snes_time->add_cpu_pcycles(1);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(2);
+  gx816->regs.y = g65816_stackread(MEMSIZE_WORD);
+  g65816_testn(gx816->regs.y & 0x8000);
+  g65816_testz(gx816->regs.y == 0);
+  g65816_incpc(1);
+}
+
+void g65816_op_pea(void) {
+g65816_prefetch(2);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_scycles(2);
+  g65816_stackwrite(MEMSIZE_WORD, arg);
+  g65816_incpc(3);
+}
+
+void g65816_op_pei(void) {
+g65816_prefetch(1);
+g65816_getaddr(MEMMODE_DP);
+  snes_time->add_cpu_pcycles(2);
+  snes_time->add_cpu_mcycles(2, dest_addr);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(0, TIMING_REGD);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dest_addr));
+  g65816_incpc(2);
+}
+
+void g65816_op_per(void) {
+g65816_prefetch(2);
+  snes_time->add_cpu_pcycles(3);
+  snes_time->add_cpu_scycles(2);
+  snes_time->add_cpu_icycles(1);
+  g65816_stackwrite(MEMSIZE_WORD, gx816->regs.pc + arg + 3);
+  g65816_incpc(3);
+}
diff --git a/bsnes/d65816.obj b/bsnes/d65816.obj
new file mode 100644
index 0000000000000000000000000000000000000000..e685f195330d2ed1a8336e19d86349ce0f003c91
GIT binary patch
literal 84902
zcmeI52Ygi3*7hfqfPfGnaIr@WP3cWQlu0t_lL8_lf<Ow*05J&&iU@*=6hXv`T~t)$
zDwd0g9S{{eAR=M|MFmAf6h%e(p0(CKXP+~(GdUCQ{eIv3y&h%q&+PR)d!Mz-DKnV~
z#+(@QcIHz_cdhaH&adU;tz%JHabd;eV)@PIYYj+jZ~dlz){FCXEGRE`JsactjenWp
z>%6XGMe&phM^OSe3x4C2C&?1x@<((mDlV8bIx)=(jRRC5X0{_PBQ7r4<aZ-tRypD-
z^IMCUO^!H|-?DB#-&VwwjgXc+RNHFb$cm9x<M6XN{vEm1@dVHxhy5*b$F;!o4R7-n
z*V<#;c^=~id5oLjG448#ad&%&I}s^a<1uct$GC4i#8H3Ly1nZDp!S{YF|Mb_xO@+B
z)V^^Z;%NL`;~|dxZuJ=VxW~9n9^-a-j632X?j-C-+#PsuY^M2k0?N<w5J!0lc!)a@
zaYH@EP4*bK$Yb0}k8vA4#GQow_|!uj?eDK1;>fS*op^9;mGwtQ4{<b}(>=sdzYX&k
zH_2n%0*`SIc#M0&W8C{5<G%9{NBvg&E=OkoP5nV}r+JL)?J@3rk8$HY#$E3*?p_aZ
zG+v(b5J%(hJr8l@x6fl-%-slfY^MGozY{#hb@3RN=^>8h???}Ew4P4$5J&rQi-$NG
ze~)^Md(C6qZjW)ldyH##4;ty%O#Mdr>*OJh_BYEz9QhS_h@<|v+Cv<T=UY9*QNOM7
z8275jxKBOC{p>NW;W9MRv6=dV_M`POM-Z^Gxbr;3QNIoH7+2~sZm!3;<sRc+^cc6p
zW85JRag^r<_u|2^net5IFVRCB`StM_H^5`uIFE7Hc#ON<LmbWDCq2Z`{C(R)9OdOJ
z4{<b3|MVEw;ywgBHdDWmUssQDL632xJj7A{W_XCB{N3Rpj`m}<hd8SD9S?C-?>-N4
zH12EMj|azQ$}{zE3y*P~J;r5tj2q!GZi>gaMIPf;c!;BZTjw!ur^mRTJjOL#?&vh2
zso$u5Z9T>%dyE_EA&$n&WDjvP{%-UTM}Esa#y#&bZkxxr{T}0LJ%C0!HdBAl{5{!2
z9L?XeJ;YI7@;$`SI2hwG?i!DAcY2Il<1ucthdA2bZ#=}&{?>R9501^$ALMtkhd3Ii
z-95ySUzW$X0*`T5c#K=@F>a;DxD6iTc6x}T{y5|@uE9eHc5J48Bfr)j<NO}uhIovt
z@ECWahd3H9D?G%}_*>^8j{LTJj62{lE_MY>9h<2?sNPdO#`W|NN9$y+hd5d%$9jmP
z_Fdy4j>gsP9^+PfjC;pp++L4yH6BJI9b0Anak7Uv+TZRT;wXQ)9^z=6j`9#ke$zb0
zE%6XX^*-Vuj_TduF>a^FxI-S}>a9fOj?L6>)E_N9#`X0WH^@WWsi?QqLmaj5MvrkT
zJjQMC5J&y?v4=Ps2S0g;Bfon8!h>To^#{eZ^cdI2W846bapOG1(K>mJhd5d%@A42w
z`@6<N9F2o_JjU(y7+2#Fm^wC7f6zER*+U$)uaAc~+TVd5;>fSWLmc^C=OK>9>D?aU
z$ZxgBxVJpU?eQ3Q)MH%yqiCdKGxZzoM|+QP0S|H1A45IHP4*bK$Yb0}k8vA4#(nBB
z?udst%5#%dj?Ms@`h&*bnI7WE&+jpAu*bMkk8yK6#x3&@N9*KT4{@|kzULv1^0MDU
z9F5ajkKw_wnfim`PW2eq%VXRCk8vd);%K~F=OK>v<4zB8l)p6|;;7ztJj9XT9*=QH
zJ;ud94pYZw>Nl#ly~ntK$GD*$<0?GFQGd+$826yZxOE=mc6yBa$zxo@CmfvtH1!AV
zZ(9#>)Njci;%NL0@eoITr5@wvc#K=-F>bBLxXm8oXr0{aA&%C`nor`vv6=dV@^Z3=
zIO@0V9^-O7#*Oh9ca6umJ3Yiv{?>Siqy63DA&&gMHO7U%|1|dBc%LW!(H4V$ruT~`
z)WG{g5#xV~!+i1hA@4tRzYp|WJYRQ>#8{7}{%wlFRF83kJ;c#?xzrdJzQ3~&ce9GM
z_P0Y(@u-oLN-9dm7W4^bCZ{AgpU4Xaa+7jW&rg^eNUSyQc-pU8HRd&L^y0dj8(v=I
z*kVyqAOGm5k8?ynsSeue;a?r!JlkW|x|%R~Da6F>(TtVaBhL01)an@cTzY79{j^R#
z-?7ANDH#3@xF~-N{mKt}iDqqVaLLQ_DiRyW9?blTq~l@+jjPSY`GdmZ;}9QAY%p^-
zMfMLXuEZ`blAWRYnE%J(>qKZzSPtqUMLZzpCdK!Ssc1KQ-K5x`lbR+>I<4E*xfO|V
za|b3i7!anS%th>`Fa_!{JvR^b-Cmztk{CDhbLymdKS*opAEJ&uZZDqlRo=1P*3B(~
zlDl`_!ErJ5mAVQgS}r>$b@5=Ecc?xLst{U@jhDvG4JO8oi&?+Bu5R_9aSbE28KY+q
zm(SW*tJSe%$FOgXU$LuWXovYhJx@azs?Z@H%f*#s#t>gC%J{}n#z#8`YDDQDZG7Db
z{$oOOOmhIsMCGHYew1#;8vgRAGft6u5t<fxry?q?#>T6~VPIk$Pm}eZ*PVx{S^wam
zag8F?Y|Rv7o0~*Z8U}Aw>pOQ`yetDa!qJ@ERd?P&y&6<CCqrk~-$#JIj{xSg32R*c
zeFO-dGtsWl|LyqyVMl<7tFblejH_uxWyHf;MCD&R0vHd0QLgP?Jt8jG$N)|<)k&h9
zxAhM{p{?XJE85eVXygA=r|Ntjj6+|8@DoTnRgZiPWJ<H?IXdI7^t?IZF+Jk={V$*7
zM>vD2>a@UlZvH>?RQ)fF{{O{Gbah8f#E~9xz5O4(QvZd^c*8Lv;(Bg~k9O7lZ^!@t
zv#K}UOV`Sk+-8V4*8g7BDRcTB<$wDI%zt~Wj@Ccw)9;9*=|6G<CgKVkA8DjVI`N6P
zs7KtXh)S!mk#1{5yaR)E@;`I_66x;Cs77maZg2<nKU3r1>%ZK7;rrsa$=tyF(gg;W
zT+f7G&fuiqbOvvFF7i#nh|9R{dVU2V`upg{>)D7^dYKmg3r_1Xx&Lq9f2kR1fi$!y
z>H|Qe(exi#|1n?w8!t6QT*f2qR79cG*hn`TBd-637xm)sqTXM+Q($@}D$?OWy?Eey
zWsw^3S6*2(wc+mr#@`2wN-k3VK45ID<lbhqXY|p=|9^hKh`4%Nqt5u=gow&W2aHHZ
zLHiEO|Lg+>4to*KY5!jPaWmg=V5fKM{G|iC>B7MDT*Q|EBA&Qg=QGtm<u}fyh;>?X
zsk%3FEB;fL(EqQ!TPNC^QPD2_(Z)x8tq^fEMOr3JgWB|5<g4Oldn4QywMJc>%v9G^
zam1xR;!Z_WT8Eoz-z+k$DgTZ0^oZ9A*onX2s7d2$7M-yf2c@B#{(hq-rHr%1laiC?
z>161C!EGXIU5NhBi9_H2?Hf!{9|R&TwEvM~K*R+(;tK{56CZIYkF-+}g;ry$d;Y(O
z=F#8V-x>Hj1OGcS;P^A3MfBH5eQVL*0kr}3VQLSmgMYEUE_gf}&&B)vAo+Wtd{7U5
z?m|#^RtyD+VkAfulR=%i^h&#QhF!W4B!2gR#E(8asXZ&`;}pb?{%}(KUIK~YU63fY
zgW9s<BakR|fkg2=NEGx3C!&bOpExD5qCQ9zaUfBg1`<UlkSKbB5?FB#NECjMDDps}
z7!DG}DA38QxD+IcQjjRF0JY%KtL@U+cIiTp_&pAa=eVcrxM%IScR-D~^gX+Dhh6$P
z=y)#u+AiI1m;MYoj!S>HOMUpOIceW1AZbB6knB-sP;FN90LdQp0g2*bkSGd4q8JB?
zVZ}s{C@MgrxB(=JJ3*qjAM{5}8g(l`qIeV}iuXXG_yi=1J)mD%u@5AQ10YfS0iwTS
zi}y7^jL?ao!>l+BkD^EfiJ}`w>PP`e9a*3s@GsVvheuHi1c{;$B#Ls7D6Rl~hkvoY
ztMMp`*&tEe3=+ltAW^IY?ZdxV-(z?b#cGf!UIvNcJ&-7Ng1*GRSl?%O6vZBpD1HQq
zq9%Gk6!k#6S<wh23L0IaI0Gb#ZXi+6TJQ-g`hi3d0EvRWokSFcAW@71eaMQ5AW>9+
zL@^!oK9|n2OXt|74}-+-36S`$1#Mx)3n1~^0205qKyP#D7Q1x2UAhbOI+uQFmwscH
z9s@~jO=?@Uod9};6{muvwlhFdn;#^KAV}JGK4?8F27^Q~45aoKB#P@mqF4ZWffb8E
zqF4$N#Umh5yb2P<+n{Gyu@xkW4?v>$2_y;(1*ND1dWsbdK%!_25=8<?6rDj*$JwAK
zSkV_GiX@OI#)3p~8AudUK##KGDv&6y0g2)!kSOj2iDCulVOBf}62+4sQLG1vVhczV
zJ3tSx;uDZ4J_m{72aqUYP$Y`FpnF+yJV+Ex@Iw@*gGA8<B#K_3yI6592>&CE$@n3P
z{vc6|1c_n{=r&f22jPDx%J4%J(?GXy=}f!yI=l2HkoY|bx{2eSw&R|+<2HkC<kI);
z(w%nc9?)Da-Dj5`uuG4CuH(`_?9v)_t@fP;k`|l=l0E7Qx`q{JgCN2l^##cu4Fidy
z7$k}k&~#Q@1`@?&kSOMXL~%Dr6c2!CU5xdu1c~A?kSN{<iQ+SmD82$sX2rK4Q5*z`
z;uuI)^oGY-bTX)n6{mwl(HbO*9w4bB6(n^8K@(WfA0&!FAW;;9L@@~@ifN#6te6QB
z#dRQ2+yWBC10Yd60vg4NCqSZD0}{n6AW^&z62-@$0#@t>iQ+4eC=P=}Q5y*mMFY?!
ztY{1pMRSlST7g8-10;&RpdqYC0*N9GB#H|_q9_K5q69RE6_<fTF&QL^8K41NdaYeL
z*Dn1RNc{c{62E6bxvY2zBz_w~;`a`Sj=ZtH_w3RgcIoG!G%o$xF5PdJ#-J*xEgnCl
zwv#}~tVjS!ZLL63TQUg$qqbc95XA+c^H?ziB#Pl6wZ9<z55*k(5XC}JA66^@iQ+bp
zC{}^+KNOqrLlp0Vda`00NE9D}MDYcvE0^xIOTV*AkAm<&{2DZ{{F;I~vZ4h@{7wOh
zUmMVwT-x3)?P8buLE@JWlJ;E)YR!tFAn_Xs62F<CmRx$BT{_P$y&WWeD?#G-1n5*&
ztO1GNb0G1110;%_AW`fFoydx>K%)2-B#PfaqNs=arJ`sIYR-!0AW@tI5=ARe6D~c|
zF70HO_5q3C#h`{9H^Po9w&Sj#I4-@~E}d<c-bl}J>CJZOt#;{spqgCzkX`zSUAi75
zE!YN<J^BcA4Ck`3zFi>Mqc1_SM>QH+iiRLjGz0z4iW5PiI1MBUKS=7x0Er?G^b0En
zf<$o<NE8!5qL>2`#X``JtXKjP#cd!_tN>v`;@tabn_dBZ&x$udqIef1icdjO#{rPk
zaTxS1D}Dos;uuI24I5dCQ$eC=1^Sv5XM#l02_%a1KvG98NE8=<zF@@=kSK<OL~%9f
zGcKKNm)>BP-U<@G6(I3@4D=BzR)fUv8IbsG0*PV=NEDxeK48TjkSO+nL~#Tpin{nf
z4N)`#(e+TQFCHX{6F{Ok1N1JJwzW$;*rmB3@f!pZzhR&^Sy2EIztJG^yA1Rimrk}z
zue3|A1-;CrbM4ZFcIk4E)b=7sYI_Cr5-Z*SNp0_fq_+JaQ5*q@;uz>TR@7>2DUJh)
z;!Kbzx`IT}8}u|Q&I3suDIie{28p5!B#Nn^f3spbNEEX`qF4ZWj7t~WrAzJ72SMVu
z1|)tjfd0jb4IuG*4J3YhK%zJZ62&i|hgfkGB#M|OmLd)$iUg1-+JNY)Io8)6B#JH|
zslyKvMLtLr7lQ6##ZZtaMuJ393KGQ(kSMMP-NB0aAW_@|62&r*C>{ri;%U%QRy+?9
z#d?q^HiJa53nYrKK{vBvKS&fmfJE^-Xd##S@KHQcS{o##aUk*Q0-DEhJ?*%2?6`c;
z94@`UE*)Z*7J+7S=~%mTf?YZVG=od8vP-YAOP7MA1uH?aM^AvJv0@EK+WZ_y+PniK
ziaj7vd<&Ywii03g90rM^IX=Wl6sLkj(F#O&RAPN+f<(~?B#Hn?6qkTRQ4A_&#W;{C
zCW1sU9VBb^0-Nptm9SzNNE8o%M6ntqb!-Gl9dClhuwpYv6z_vXu?HlIpFpDc9aO{$
zA3j1z6tzL3hzE%x5hRMUKqFYu86=7xAW;NBq8JDg#l@hZtQY|jMKMSe6(CW}28m)G
zXfP`lfkbf&NEFLKqF4<Q#dDy6tXKyU#Va6DYy*j64@eZ>g7R5$5G0DjAW<9x1-Z0V
zbF1_?kd(FtiC<Tc`1J;5u;M(B_@#hEkpl{F=>WU*Lc4S%$j_yt?9xl^()l2%Z3#$f
zy93mh70W<U+XEn}?OBj0-Uf+c8>km6J_L#4Q;;Zr2Z^H2KP*K<P<K`|1&N{sNECjM
zC^A4&M;?goR>t}Uf<$o<NEBm0GR7~r=~_^GR?G#7Vj)NrcY~ykRUoP3DNtKhJPQ)V
zOCV9~1mS>%bDw=S{Q^p4#ZizbVsPtS6mcM_BLO6Jv;ifsqCH3yT|lDngG7-J62*m}
zlUXqoB#MzBQIvv2F#{xu>p?A8F&`v~n?Ryi1`@^NAW=LGif6_1AW^IbiDENI6uUs8
z_!<<)iv1u_`~VWg@1O=;>chwFNoj46l*WO?uM4Oy$Mv-1&avb2LAAN`0=smGU0MW+
z;nJ~o=>)rU3g{2q1&{SzWtU!Km);MO7W@k&d-NpeS5`a?k~TjNk~VJviDC~(6yJgl
zv*I8~6o)~gXo3&Q6UC_@QM3a6z=|_LqUZz?#f2bI3<rr~6zDrvTnZ9JDM%DogJj&_
zXw#jbeXO__B#H+?qIe1<b-V(SI^F_($%-u?QEUf^;!BVy4ueE-6ttTaG5DB2QN)5o
z(F`PtRv=Nd2YtedE+A3#1c@RQB#H|_q8JMLkQF0Aq8J4d#Uzj@t_6u=KInZ`+yoNE
zKS82+03?d1K%#gaw1pMxL85pSB#QSzqWBUdiv6IsS@8o%6hDJR;X4_3r@6E?NJ{I0
zr1Uh9_;m$|UvJPWtT+!OiWHD2azN|3bbwuYp<Ox>^a7WTvP&<uOXq;3wk05`?GDg0
ztXKw;+8zK&ZLfkv@eW87?}O-ds#xDnkSIO_iQ*@aDC(SIDH?*FU`11qC|ZC-aUMt%
z86c@65A-N227*L!5l9q8AW>WkdYI$p+Hni*xaFV+x%6SXbd_ED0!Uom21&i!K=-lY
zLy*+_DM;$w2NFd+e02NW9M=dWaq%FDYYV!AOFP)5UG35&kht^*Nxg$XOIa}tBz^@T
z@w*HpikTo$%mLlZiUlB1ECz|<UXUoB0EuEPh+cDy^}PTR#RiZlwtz&j8zhRopn0tL
z4kU_0AW_7eW+@tjM9~6tJu6NDiJ~P)6zxH?xU`F1+S4vg0!a%BK=g`ftZ%d(S7OJ_
z1Wn`8>+I5bcIhpkDO`HHU3!mQ`Y@=1OIO*Y|F%oFfusc=gJh4s0MRSDvA(?^*`x13
zvPU%%EJZVrC{6~Iu;O%(C|ZL=kphxB@<5^(1RBGNi$S6o0TRU=kSG>`M6nc9#ELsX
zqPQ0%ipN2640y?=w?QLVu@xkW4?v>$3M6&>43awj01ahDjngef9grxRgGA99B#I88
z!7-Gpt{|!7Y>+6@K%y7~62&mkz!*{#fJ8AGB#Ox(QCtTS#R5=%3@H|aM6nbkiU&cW
zSOXHp3!q>ODK>ya@ft`J+d-oE3M7i}Kp8QlI0O>KFCbCGwzL$@L83SX6ktV5kSN-K
zM9~FA?<0uy^|VXRu}kwo(t<*e_>BYgWyM60_*H<!Z#t+Km(H?F=h&r-LEX7@sa<-f
zUHS}2YI_AFwY>%E%!(}_sckz*YWoEwien&A#GZjOX;#z+i6RapidG;|^a6>ZAE+%W
z0w7Ujf<!S9B#NmZQOp1(vf^5hDCUAhaSKQkYd{Gc_naNK&W?K@bPAX5v`as;OAmm=
z<xh~*TRRco3eAdoAgQ+zNa{@lHRIBDc4<eu^jwhm<$%O*AgD1bE&_?)B_Qz|4-&;y
zAW_T)9nXpzK%%%2B#OI0qIeV}iq)XwSn&)<6fc5A@is^lpMXTM2UMFC`#_>N020L?
zAW<CO%2LFGVpwqkNED}nM9~)XhmXd12fMVZU3xA^{4N3g%5jBu+!#CVD$vhddW~Ir
zy<K_}=n$9w(=NTkE`0!WfJ;}}rH|RA8$r^74?vQGPeI?X;tP=M(O!`3QSH{2qA^Gm
zEkIwf;uMf5T7pE80+KqiL82G{`kWOPf<!SCB#O&GqL>E~#bVH>tXK*X#hoBg{0k&&
z`?EG}0_|kQ+aOVF1&LxeNb2|jBy}7CZD++FAW_t4V<{SgL~%Mu6m3CUS<wMhhp8(_
z>PP~KqCZF!gF)|b+%QlbrUH=KbC4)zf<!R~^ajT*0M%hy3=+k?AW=L462)53s~q<N
zs1DNxkSMl*M6nwrioKu>9QPfl4$~o!C}P@LipC&Ov;e)xai@Sp(Gnzz_Mm6Ew2NKZ
z(=I(9BrO;Y62DQPHLSQ4Bz~nJ@w)=_B$r-om(I3JZv?I4(wptlTkX<kKvLU!kkqyb
zw2~EXgQT{tAgS$ZkSKlwi6W*Q&YD>f3lc?rkSN-MMA022igQ5svBD1$MJh-X<3XaB
z1QNwG(A}(<2@=J1AW_@|62+6C+d1xOJMMWqZZl{pm%eY8?zBtyfyCukkksot6KBn=
zs11^O>w%=+(?AQkG|?_?XP5Q@iC+dt{PIBaSTPVJeiwnnZwyEjQ$V7)8gxA?W`jg=
z14tCNf<&<bB#OsCvskejB#LK1qSyoy#SV}tJ_B9Niaj7v>;sA72uKul&$1MaKv%LN
z9wdqrK%zJUbUBx{wM#qLrM*D)x%47XInyN|aVZ3e%jKX_E}dqV&a_MCfl9b^kzIO=
zU3w2_43{pqOCPpNUj^0Y(ybuL!H1wCe(qC{wB-wsw53*iOVI!%il(3utY`re#VH_B
zbOqJt(o~Qrf}o-NTz`-#27yE|4J3-|K%!Ux8qA8tAW<v@iQ+*}J(R}#p0ep>&_Gsf
z0*T^nkSIO|Ngew^Qpb;=d{!I*iQ*5CC>nII6eoj3aRw;Jinbt8bO4E>FG%VLf<$pX
zD1#M)L82H262)|o+H;WFb5MX4i$S7T3KGSGAW^IViQ)y2pA{QGqIeA?itQj#d<7E4
zcc8wkI0O>KFCbCGcC-}DL83SX)Qc4@L852_5=9qKcP{N|m!4yn=7XdKg&^@82kOj<
zi6HT-0Eypp5IO?qNVDwHId<t{5EfySF11VVv`e1>No}uyq_(#}I8lRQ3rK3)4wBk_
z0g2)mNEET1aIVaX`XEunfke>?B#K@jQS<}hmJaF&fJBiA62(N2D5io$F$08~y--{W
z62)AQD3*ZEsYRu?f_gID3F^YM4Ag;XIj9}e3Q#MiM?j}DJq|jBX*K8srnR7EOwWTF
zGOYvA`(a~!8$q#5n?N;~-U9tulS(&(eq-7O`k845=n&J#paV?1K;JO!0e!`^7xX#P
ze$b~(2SGcTegbW0Is)3tbQJUs6AhL(m}-GuWvUC>z|;WrB2ygbS*Cc<8m1PYCz(zL
ztzt?5tz=3BJ;>A+bRScD(A`X(LANt?2mO<&7ick4U(h@zKj?a<0B9Cd28iD89P0~$
zu4KvwUCuNRMDLJ}^$iA1WEu*(lxYNLG*c0%kZBBPI8zDeVy05ig-jKo^O>fA=$+ZI
zzG<LrrWv4grrDqrra7Q~O!GnKFf9U|&9ns6jp<fUC#E|=XE7}UwP9KgI)iBi=rpEB
zKqoOh4*CbvYEV<AwV*~!&x7hRtpn9!+6eM7Z2}#wLHqF*=m^th&`(U;KnIz2fc7(e
z4BE@I3$%x64`>(DUeL!(`$0RH4uZBZ{RG;~bOiJk(^1eSCi=6FjZC#b>zL|-o@Z(R
zTFVp%TFn#>dYq{R=n<xqK`WRNK+BmDLCcuhg6?E$54x49GiV7@chDlHUZD9*eL>eU
z`9U+80-&pyGC)(Af}lxE`Jl^~27<;j4F-*68VV|A8UY%~R0JBvGzN4LQwit-rczLU
zrV3CF(-cr9(=<>j(+p4&(`?YWOmjfJndXD&uP9=Di$GnNmVi1i-3n^QbSJ14(=yQM
zOv^#1Fs%Tc!1M^H8PnsS#!Rb0$1|-39mn)Ms0PzI(4TzGz7g~r(<Tu8T?ob>=n&Ip
z&;h1xpl_IVfWBh-7({<(g7>9?K4sbi+R3yRw4G@`Xe-k}5dGastnVk#8%#$)uQDA4
zZD8_s#R|t%3q*hO66>oATEo-;^dwUpXcbdDXeCn%(EUs&gYIEU0Nu)z2wK9_7PN?|
zJ!n2tXV4s`?jZV`oLFBk&<v)&ps7rL&?Ke+=rX1Z(0HaGXe?7csF-OWXe85M&@iT<
zpo^GBfG%Jv0`+Ga1Il440cA3kf>N0(KuJtfK<6?|1NCN_0qVgt8`Onq4yXgud{8^4
zMW9wpOF*YH-3mI9=}u5{re&ZeOv^zHnO1=6F+Bo`WqKS`gK0JBPd?hO1^veKJm^QJ
zb)fH=HiEuo+64NV=`GL~Oq)TUF>M2V#IytS0n^8z_n3Bp-euYYdXs4{=ryMOpqH5r
zf?i_!3G^J(5zy02M?wE)@^!<zy_jl&{>4-m^bk`6(EUttpnI6&L3c2<04-rU8MKHg
z0W_Z}5j2OXEoe4Vd(aG~&Y)>b-9b~BdVwmK`hvzY`9Wiu0-$214A4lXAZQp<KIkH*
zfuIYR27~%D4F%;ejR0jb6@gNj#(<KTN<il_m4bRRRe*XhO#xxzVx~+3;j|hw1B8of
z&}<NHoq^_nPG_1AI)!Nw2rq-9w7j4&A+c5Gjy<QepOSE~&@kWF3G!@rdNx5nZ$*bb
zKd!tip)HB2pq-ANQdkUm*ybxOA=|LcZVhavqSS6rd2vx#FrMIe4(d8(m|J1(L08!W
zr<dB}@RHKvk(`U}(l}i^6uftkl($1YrjmBtKx2u!Wd+5TRa%SW-?``3ewf-M33u09
zSUSb%KBZtJ2ZlWOCQK|1d5VAK%$`9NbPeq(U8LG%=`m_TW3`vnOZ<$TC2Q~OO6(GA
zq=lDQdl+7#HSNpY^^_NvCPdg9t8+1Q9Rr0bszhWLg{Gize5qkN6&0JOlNB8{o#4Wm
z=ssnbvqj|<=FTb|V@|xo-!+{IOU%=W;;oKy4_a#v!Y7SYM|eqT@mOoxgiH?7SUGo3
zC`U=<8k&NRekzzyY#j1d%X(6B?15$NN$7;KqQjmqooaNyeB@ZzhHbv0;>!D?veATe
za8c-J8ash@G;H%xTdjWL(y+Y?pB&cy8A{Y18cI-)tO21Ds;u$}MHN|{8#<w;Rz9Ir
zQD_QEieyc8AD>E!tX0lE6s+jb2~|>Lb)x%tRx#DwSrz5x=N<m8Ay`;4IjooPgpcB_
zjtXt5>;a~Y^s(KARvqCJ%GwK4$w)ir?g>S1sy9L=l(WR$wt~WP<B+#n=AKZxFWf`X
ziVmGn)?S1@Us_UN%wfgI%KM^{2}M;KCsf5q^MoRS)lZ>&VfB-0oS~n>OJuZ#Pbe!V
z=)sU96lJl}y-`J`xnZ7Zl;cX>Dw%2J6{eY1UU7vQ3+|a?MTgEb9q-O##T0YqE2c;y
zR1U2lK8L?+rd3QepT|(V)r0QQTwY=IVCYP<>Ik1t<rP*B@?JX*AEdEz?w)Cml8~9^
zEOEE3pwK!oaA(VEnR}*LdlEWxtmyFPtyRzMUOJ|dnKs3o+k&wbm5nC5D0FNV6`T8;
z+G_QayH(cSh0hvm|4b!TKdFIZ&rYogooNMSCC1f_6jsl=k6Q(0=IeryMW$<~vWaEJ
z8Dm9<&X{r5@sbK0*G?61H*C0eGH2G|@0u~?I1MvwK8m+`!aXXjJqVu{RvqCb*1Qid
zA&r$+_l$9rgv=OciMwqDlg-B_t7YyPW9>=k%&?+EpLg^Hwa6Y#Wfdic6ejq{-!Nx5
zx0S5FRJHNgR9a$i!Z`#9tbXD~=vJwb7CtYm{R=PA{iJrtcGH^B8B<zpjc9lMq_BF{
zJ!8r$%&U5_YH`Tf9PS>-wXFLXV?~G07@5KDzOE=VU(}S2G0zu=yKBA_mYC-Y#asR0
z9+M@i{o!NZsw2E){NxF|&nOAM%Jz}Y%B*|NI7&k1jI+euzJkf-qm0!$cOI?137s2O
zbm;RmXQcPsqoZ`prD}+|e)!1WFw%LSE15G?wRz5rF*sq)kihCIcdM+u3!fR*{)Lx}
zpKM<SRnk}Tbm+XfylA{@*VQks-VL2M=CL<&LJ{ZKJ#We;T1PVXys@G~=M5dKrKjBS
z73Jn54P7c5HlM@aHFL@%#9O`L9+}o2gwGGFj_?v|FTzVmW1cmRl8{;BEOEE3VEkC)
zxVBp6o;B8<gw75tI`nyKFG8O$t>o4W`5VSM_eCYMhN?EtniBJEBobKt#Qn~{^qevb
z$2l2k;d8^<zwi=k55r5eCUnM(D>tp|6mRvbd%n<pXVcm<QJt~5=gUat9y%|q=+NgY
z$_k9`6}Ub&Y<$<;^t{90HD3x#%=3%lt$uKiNox<n$G%lZc!{+a;r&1wE3fXOjH4uE
zzBo(VZ7V3XRwMV=v0CPyFV>!fj(;mU^!bW%b6=E>F(38G-!xyyzmoZ47pc0fuJo0T
zG0ztgSpDSQXKU}wId>gI>^WxbVI)oHd@01;`v`kub*_8T6qH?BnFucl`Ig|dA=>bk
zoEZ9vKZeG;hGy=M!*B9=#e*&!7c(y=e_YHs-(HH4XUE0N2_(kPYn(hFqySIXCBdw9
zHH?}T^BT|EP*bZA-+*2$^v!zxShsbDR{gT&tY7hI)A94x&-;a+U%#)$j}Oe-gfB{{
zJ8O5%AD7by$@j-Y{DA!a+@O0|y)kZXM*Q#@zs6iLY5LrZrgPW-ym{{C8K1|j`@D9e
z7q`xOBV_>nT4UYkwfNT|{A;aspV#DHGx^uLGu~*t?(-UWhJTHl@y6+!KgVzD_SGIR
zV|NS;Uhh2P^Y0qH`1-oNHD<i=Xkx<VZ~8aLZS>+Bjb7ZWz61N)$#eZpQTHYY*6l{!
zTjp*;?K5`Q7_e?P>gHdE%-CHEzoKsbHFL)9x&vms-gw<^)Qx9QS=@}*+i%{D-_R0x
zeg567-3h1>_0D=d$5iivKw|fNXFl342qwnii=pzH^zZiifKl@@8g|<{YF>Vv`VC(^
zjo<32-|Ehb>pzC_DBpa?KKw9qV=s(^mz^JF3a*RD`uG>i?={QE;EDI0YCqQnB+s2~
zKS%Fyl;;N6&yBX9D+T4j1+QO%>fm3j?_oUBXpHCgTuW_dqb)&>dkmDx^bAPe-A3<a
zkT`mWg}59ArEy#g-jk66iuc8Wl9~9W(1cdy2}ynU<;;Y^>gPr3=lSYq!1|d?fJxh`
z+}Enm{a-?E_*1FAe*OAcON;X-c1+$x5@7P7Nq8X`jjH48IBIMOz1U3KpU3c)t(d~n
zNu7#%_UP56XUD=)%9YPwIB|Sw$FW7RXVmu{LrhIy$D*?0!ivc(#6J6K#^7%Yc)M-=
zyY$WgY#j^A%Z2a;0zl0ene^6k)=xBpH;Sp@>sV1dg<cw`ttS18Nx&o3vAf4hJJh;?
z-%i3m+G_d|WOsacr<1+Gr>MAK(&)rAdWveO854&`@}aG!uQnc?b<yv-u2FMd#jDv?
zG@GEjHrM5Jj%AhQy!4?VU)2tCrlC<YW*L^ghfvAe(~iRvmh;6Zqpgl|9$7I`p77D2
zuNl)^{Whp$m*tX0dZJ7{OEEQkiNUU2y5qg813Fp5uw#+-ISw&3=~D@K8?b8b@!IE6
z^(@6GAG}@S1fvhVSy}sB`f}H)+GoG=p%~?Z&iKrJqpGt#G-b3;@T9^G+UG2l7K#y{
zZoTkvkw%{eE}z)v{(-+8;9-sDCnz6^Q9eEK(TqkPq{GpkCthoVF>U$K+mL9Z80CXJ
zUuE=Zh#0+J2Tok>=&u9Hhhmfu@*FVwG;;Zz+3TxsbbIK{WVBI?@<E<E8+~X@){Hrk
z!m;(pAB=bISo<|z0mX<<SLE4e^l6L&?bGC`K8}8;w+YflG0F#d-rT`74x1oG`yB57
zLO{3Y7v)1S$_IH~X7p*wKGt|1n)?iE@PMs1Eg0A+M)@Gmql`ZBh|%rI-JSEDZqHQZ
zLovz+dG2ZSp@W9@$!_)*78@(iFDW025uYx|bF9&aX1ew{_Dt(#+NTaYX`>kBgFJ6<
zZ_4vO5TnOor>E&-)U5X8Dj$kbK9pyp4`o=dKWm1k6>6Uwl@G-zALMzs(TCm&q}x;Y
z(a#my=MCjUG0F#dZf*3Tk*s}&tjT2!9<bG;#Ty&Nh)-wadH-3a{Lpbj`@B5t_-A!{
zvXl?SC?DkcNuv+FQC|CO-S7(Don_^DuJWN6<%2xmZS<ixO=+LuukU<X`@EriC`S1p
z&vT7FbV5{<K97U9mqzVP)IRm-Folg`=*Xy#4yWOnnlY4r+Ma%KK0>U$$X6<g;o3X*
zMmBmHYfnIo-ixDM4=vX|i<J+>C?8~_rP1ef_OVv2nMa=-qJ6e1ABs^v$i|^FO}*UG
z<uft2?mgP)L^>d2qZs9bQMbY9a|UActemrQ;eFcY66HfN;?oPGZn4n^o#F5qbK<rh
z+UH*7Lovz+c`h*ev~u~>|0VNw?enGbp%~?ZJa;wvv}PY`v@D;$<tFXZmQE|MQH=6I
zo|_td+8{>fXI900N54-{J`|&TkmoP(9ztqptZN*$Wgn|Omwz^Cwr<Z;%7<dyqZd}F
z-5R~mZ~t<sR{gG26eG2tjchD5){b3+Pjfudw*C0$8)~0(kCSI9M)@EcxkeuhY535p
zNZZ1uN0PM96y-xP$_LqqH~L@!bohKWWBV@c^R)7z81d<eQTGv&6P{HZXdFI+H^!uC
zpP!Wv#V8+)x_ga2I5BYe{J7wWYqd|GdMLz3G0F#dUSRaWiKWA*<)|x*wa*pGhhmfu
z@;ue(gTy&}hFs)7SNqUM5Yt96$_Lob=+gx;y1%|WknZUBUzHEVh))mX`7EOk8VVn4
z)k=Rd(J`BP*GC~Xicvnu^Y54x;r)e61cy(}1=Eh`{hFbCC`S1p&u<!iP~h;n{@?2{
z=&V)!W#vOL$_Gum!{~!W%Hgx}r$11+<rCWgh1e)Y`5@1i8hx<C4xhd?yIiAva+MFo
zh);Lq`5dFq*)E^nzdU}a_F1BQC`S3fvcAy=6*$_n;Nl_gYM+ml55*`Sr0OFqhIR0a
zd)4aAJ}vM_+obsT`P%1<<K<b3Q9j7?14f@dh|%j$&uMSIu6+uX55*`S<hj`Ba}N7h
z?Rjz3Z0v;9U-u{<iV+{WwmQq`)7Ry5;PA@Zw9jYChhmfu^85o1I^p@jw8VZ{?Wx(j
z)uY;nKDwATicvnu^ID_Nd5F<It+!9UO#2L1J`|&Tkmuz_pMEZ%(-+Rzt9|ZKJ`|&T
zkmp54A3yt8N2{EA^BqUw&y)|vxQ|vi7+^1~qt(a`Cv4TVx58OEZ4@K5cSSbNG1i`p
z7@dv2gLeK~`;1mT6r+5QjW$M~6!x)JtshT)$8k>bkn*7z<%4Yef>V_6UJkf?rccgw
zoI`%Ed?-eI=nCjHqfe^K=eLX>-`4xpEe?g)C`S2U)Gamoq#;JH#(7u&uv+_Eu6!s)
z`5@1ujXvovpQ+7y9M(S1Dj$kbKFIUgMxPA!u|~_6ONSlPK7S}5icvnD@h7!LpG;SK
ze)#9XH?<Fa3^HvLBR+Hmv=^tQ;r*3`7=5KMHSbTHP+P0ST;)SC?$MjgDr@wP>HANt
zla^|;Qc;Ym9oe|qSbLCtn&XkSQyM+?o%U(cM4qJ><%4VtF#6;mM$dwgpL~2&`{XDe
ziXopay?Y}YCm4NlT|UJPwqr%K_KQ9onKp`1J{WbMwKQcl4>7tui6aUSY5BaVd?-fw
zVAMTe^vQSme7R)WKebQ2rYOWlG0LYa?rRx+`XffS=geB?U#Wevln=!yALRKeqt5`B
z&#w3VziXcxln=#-4_yHTj6UbPd=kg+x<UJFQa%);e2~4)MxTM~W35`#|L{4^0qVq~
z5F5oPALN-X^ulMs1t`#~#G#mB0o|Tl<wG&b2YKF%c@pk3$mR3m(J!}XpPQ5q#V8--
zd707YLYL3EFU^{!eYPndiV>f)k>^sQ&tR8N?O?Mh+NXIl6k?+o<%2x?jXoD4M(4-3
zcF9fJXQ=X_80CXJ#~FQwxO`T}Pw%09=mVE&qZs9bJnu>{<@sX7=<)o1gV}FsANt5;
z+9*c(AkQlkOg=*qqtCVem`)$1QUlM?c2;xwNipI>*H&W_Og_U9<7m%iJ&{z)XSDL6
z80CXJcQX21;_?|db>(pF^N{kP80CXJ|9qOMJ&-xt)2!L4SZu8Je64&aM)@Gm&l`P4
zxO_?rUPe+apEmzMA+{0tr+kp-6-J+th|&33*#GIJ+Gn)#p&0R@YpW$jp91zd36HeZ
zd$9Z!?emcGp&0kksu0iUbFHf{zw}qF`cA1RM%9jN^fT68#6B(XNLyZyduC{#PU>lj
zQ9j7VSw^2?#OT@dM*nZ#)jkuI55<TNT><@$v#9XZW|Yfk^yy2G7^`>aW1MND80CXe
z_omTjG-7mnUas@O+1iIbzL_?PQ9c-TcNl%fAV&N615ezpefp`B1&UEV$n&K}pRsPA
zA&nbpANt^C+9*c(AkXI*ea0b1pWA$L4Sh7dm7iCX55>4g3l1Srsbb&y!S7*cSgQK!
zP(v|NdpBg`>r+g<Q^Gz<;M?@!wl3NyM?Fn3$_Lqa+UPT$eXKG6UXzJWXrCp@hhp4&
zF@aUqUNn1h*%7VUp;QzjwRgqXC@|JOk$u#X;X9bu`aSJ)qG}YyC?90wbfZrx`>4U>
z`?z28#oC8H=$ST(Q9j7V-jhvPy$msWCHdsfozH0>8vnFWjPk+QSY`AnLyY$ME^FMk
z+UGsxLown**C`c7pK_Pa4=1)kZmrSM6bjlXM)@GmBaA*3h|%r2>~Qx5+UI=bLovz+
zc@7$VCb@hDw+Uhau-bF8@}U^zgFI6!!`GI{E}x=1cip6YwkjWrQ9j7?F=Q>==W_N@
z1I~BogU8~vPZNw3+9*bR=sM+Hqt6t?=(T0~S%=QiJ{Kw<icvnu^F2nNsV<+c+p|__
zpWBrW#V8--d7{zh3YX6lx3sUReLhh>6r+5Q=YB??D_uS}jCvL+wE8Ons~T+-qkNF(
zMn<1$h|&3(zxbR3+GmvVp&0h*MOQ$dp;N;9>nfK|uk*Ix;?HW&D&<2l$_IIV%;+<n
zeOlm=wk2uhIG|ZRhm{Y-C?Di`s?q0a#OO1$xbylu#!n9%U1_5j<%2x;GWyIwjGkZP
zXZ3NMIg~0Nicvnu^PgBe!}BxK<+Fd@gB$dIJ+6ExMttZBh>kSjKG(Q>9{sw>R_$|8
z`B04VL7wLseP+3QzIgebi?vVZ1QcSU80CXJUvBi7jToJu$0y%hPy3W6pb#6yC?Djx
z(CBk5V)QY$-P`S2X`javP>79U+()bH@Qgm@-ha&|j1X(I{G5P7Y!oB4pN(uZG}eAS
zV)S0@{&vMN?bGXYa*+>VR6fYYZy2KCy)y@KdN!q9nfkc)nWB6sM)@EcZy0@WS?lom
zw*EOdJ+$^~o${d=<%3aoyU}N^%O|hHlnm`tt0fAtQH=P|b;>xS&pgEF{d#M{sb6ZJ
z4CO;H$_IJwWAvHt_9=a_RQt?VJ`|&Tkmq_v9~|Ty{T1v=_o%G=ysLaDM)@GmoBm<y
zuNz(M3H*3vuJ&mJPueI(`5@1?8hsWbMvtHQU$oq!eFiBXiV+{WPAM?@EMlMLc%-fW
zihsSYeg3I@C`S1p&!-!GZbFQ1&m%J~`9%9{Q9cx-e2{0lx(grAi(Niv)S!>{vGN?3
zh(c@>qkK@h%II@5Vsv{xE=Hj3lc#(rM)@Gm6-J*WE}z#w8t7Oh7Aqf$5g)n&8e#Og
z#pQF^{f)|Wd$uYcicvm2an@w?`KQb0!H>@SUi&mb+i0U0<%2voG5Rb;jLy$D`{;{(
ztUUKuJ`|&TkiI{gnfmKi_Q8RSx7qFQI8*!3hhfu3G0F#de#hu@8)Ec)@3Z{9PTFUO
z@}U^<q1S-!Hu~J|@(Fa9j=^i~*Ga8Wh>c>DPfxt-&ggRoVsv|M>)X|Fw7Nw3P>k|H
zp3gJ--0AW;cGr!)b$jkrJ`|&TkmrU*pSxT>zm09QS^Ipgd?-fwAkUx1oBHc+mrw31
zUsh<JPHj+#jbg-y-e0%M=yMNZ^!WL7{fC3J&t&C8G0F#do?`S_#y%LLygl*Z$4#`)
z8s)PLWy+^J&YFxq_aa8O=dQyomunyT@NC*BM)}ZqZfeTUeTdOMO)lS-t$n(-B^UW1
zY2|}FZ#4Sck2vkKc4M2N+NVtUP>lG{RogtH4|c=hbIU(wI*zAnln=!yALRLRqt62_
zpYziu9k1K-lk%Y$<%2vI8hsvQpOf%N+lQ@(U~*gYt6MvHmSWszO%LH2eb%(?yLF?q
zYN}FEjMProRt=4{uV9}Rc%-fKyU!J9pXZbh#V8+S<2Q__I(WwY3i!i#M$hifGcLm+
z*V>EUl@G-zA7tYVqt8m0Px|oPuWO$atc0{tjPk*#yWQyXFU08f^xhtvtbMLmJ`|&T
zFzUt`eI9Z7?0L=ig7$e+`A`h|oK4qOeT+Vjx_q9UH`jTVauy1)QH=6Ip6eNXRv|{u
zf?*H$T%_AGK>1LN@<E>IHM#KqdW?OnqfFPjd8OKCvGSo9<<k|fRv3LAceQ6p>i%=J
z&kp57G0LYiJ}S@X^91`e$0KbIC8Q6~KJ?Mtv{8)s(6v?2=<_6EbbhWoym-C#IbZou
zjPgOAn;3om?eh6*Q-_<i4}FX`Z4{$?kmnt7raZ4kjJ}5LwIY9@_SvF*C`S1p&$k+V
zo?;(sp0>HFJ6dkduj4zQ5F5oPALMzq(Ps@}bbdasaekTh$x%KOBR>4<lF{dBmrr5i
z=N#jCzVe|M<%8DtH2SP{`Lyb{;HYlTo63h`ln?UU(&+OH`&i?7`Lz#yt$pfuL?Jec
zQ9j7?p+=_udKNKy-5CGF2P3r40Odn5%BM5lFKYC8&gD}yJ9(J)xkdR<jQG%1+hU{7
z^X!95V&2N$`N*+8?@&GzqkNF(F-9LOTaNwutoxHc>Gqt~N!%$$`5@1|j6N^Ae0Hwu
zc8c~XRz4J?e30k5MxU2lJ`+klMCVxJ`BCLVG0F#d-qFz1U+dV%niu!X>v&B2{HS~=
zMttb1?LMOqmI=o^P4D0N7VXmwwbMp1$_IHaF#2pjjGkXl&p3d=Ywg!W<wG&b2YGI5
z^m*Ck^T7-KztKLADIbbaKFITd<4yV5=<>Pzk!#-2KHn=Jicvmz<|(7kD=wciX8v?o
z`*iApLTnTxK6KS~uhHjK#OVA??e+{-Upqg_hhmfu^1Q(4^BVhDXH9GS{EAaQ%V(AH
zp&0jB(<WA(fJfR+zhvS9t@=r+C`Q$eZ1ghLj*}9{Ufe(7>jLf56MaD&#fT4GTO}HO
z&>8TtR;{>pIVsv_vhtxA<%4Ye)WFosZ@PWzeR-Ysc~SXLjPk*#+i3K8%jI*z)umXX
ztgP1PhC*x<qkP~@@3ss-yLcNhHDjz*tJbeeFVjA0%7<c<5Ar<D=<^QySoyiV<(gUA
z=SJm2G2%nlR(*^<@3Kz|JkmC@;gL1kXN&To80CXJw>J80MvU&SCij+O$+Ys*7+Ix_
zVw4Y_`MJI+KU)x^XTb%#=!4@epTWw9Vw4Z^{JGI*EBiFZBW<t8e(0E$w<;fsQ9j7?
zeMX=65Tn~Oe$7c(dad?sRX!9WK6Gt0#^|%n<@3lRm*7xo`84i<LTnVHe30jkMxXZ)
zquX=o2My2FKKaUrVw4YBc(|S^&)Z!-XT5UI0PV9-`B04VL7sOTeLiscB;*DiXO-_N
zABs^v$n)DqpB*lrc9S-Z*6nG8Y|utA;zL($bT2-9etn1-ou6^B{T6DUT;)SC$_LL}
zZS>j6KGys?Vby_$w9k#ohhmfu@|<V%`N-w7@2NS+q}A{5D<6tcJ}5oS=<~75=flV9
zJI*dzoQ*<k6r+5Q=kJd*<>wQ`=y|$&{pd?{doET!6vI9}>8kA|qtB-<pMukVU#)%a
zQa%);e6XhrjXs~bd`5qJ#W3yjh4P^o<%2vAH~Q>y`Mj6D=vVD?7WRU+UHGSbkmpWD
zpWTSj<0s?Rrl)D2GUY=t$_IJ=wXP}8pR-SMJkr+g@>Pz0e^U8SjQG%1+ghW~7l_gA
z8T#^QoB~+m=YaB|80CXJUv2c+<MO%d!<H{=pN_pzh>c>D5AvL9^!XAox;;bgD+_3!
z3Cf3Jln?g0zR~9^m(RgoUE67&Rmz8Aln?U!3nqK`eE-_zv$(YLMD24x`B04b&{f+P
zMxVXxW1ThK_xxCNot5VfeNc#vV%%p<`|ymu*YxJKc`&e4<w`{{s&-^!p|SRF*rx>^
zX?tRK5vH=`^OW+T80CX(Txs<A7BPBuKU#ynY{l|9tb8a&eCXOL+vv03<+CLB*=^eA
z+;dQfjbfA!M%_t9pYIT(+p~ON@87l0Oyxr{$_JzF+gMXCA8`4+-sgg~+UFJJLovz+
zd4A65^S#Tb&2h&Zv!HHY6k?+o<%2xWGx{7vjJ|hKwC2jUbbGRu55<TNU0Y=teSTn{
z6Y)sfV{`lbp?$7bJ`|&TkmnPPK8FyaXXV#h-@}}<`u!c{Lovz+dEQmql;<DW2ScB?
z%b#jER{PMI25l6he30j5MxUP$quVpH)~~l|pG@ULG0F#d9%b}7?DDy?f9YcFGe`MQ
zjQG&CRePh)&n};P3mdf2KCdYsicvnu^N+Pm`T51=)B3m*f73p7&O;$Kicvnu^Jhk%
zBZ$%Y`Qyj)7HFSz<wG&b2YG(e=<}<~=g&D`<!PVml@G-zALRKaqYrk&(Vho3-+ig}
zc~$vPjQG%1+f_y%OmFyD<2m=@J639+*nTL)Mls3<dCoEV97T-w$^N7Lm)a+&d?-fw
zAkXymXIO$l?!Euv^0{%y^f>LaQ29`d@<E=z!-^U1^QX(_>zk+FuYI;EABs^v$ny(E
zpJOhc9^c&fjP_~nM<F(f5g)p0TVV8|4@c4Y>3nLVeC;#TPcGOHqkNF(VMd=Am(T1c
zzr>`p){W(UcJWb+@<E<E7=3E6PYV(F9@sq{m!6i-x5|fNln?SupJx%CXMFw*_N%$_
zS-NrRD(!Ptk~~c@$_IH~WAv%TK301kzwFvw+Gn)#p&0R@t2X*Ft?>5LcKKu_Ho(CX
zfxJDWd?-fwAkQgAANragJ>MtYaP{-r=WFFdG0F#drmwCFZ%-YUPvLD7+G(FQ$<i*0
zQ9j7?Vf+^EQ`hA)eZ$sF?K4{WP>k|Ho_8C4j$@ybR7QNqU;2gic~JRKjQgyKzCKBx
zH6`uej4_4X<!!%GQH<2y8QEBX-@^BzKKod`+|u9cW9`#1Mf@m6`5+rpjXn+7$6B?1
z`{lBR+Gm3Dp%~?ZY-AdJj(7R=j6Kz{Uu%>P#jsBg{(CE<4}H;;p4~s*8~j<f=Qrg;
zG0F#{ZXb3wJU@+GKKp7O#<_!)=ko%RABs^v$TOBBgAaZ5oNiC)(YcP<eU0*=80CXJ
z-(d7<%s$p=X_@ruLfxKMln=!yALMzQ(Wi;4Jx8w2JE(o?r^<d&jO^<G^^DJ#pq%My
ztB>tGyu7q*?1YL@qN5n+r++l%x~w)AotnAW^2J{>D`$$4HupkboNPPeQ>VJqt5Hij
z>8$Ec+=^%CI79<{*Su4DdL3VFkn<C_nsH15b|fAp?XG(AKK;2^&#Bs*#Za4Rd(X9}
z^vw6JXPo;*UvO44MxFZjb}fEvx!$iDX{41eL33y0AFOIB#lGV@4!c;Za+Hc<+^QBX
z)rMalUaM6Ll!{{9suNgc&F=aO60g##x0Q-wWZ#>ot48?}*hlA?zSPbA$!5)BD9_!X
z=r??L(b)2l<-;eI4ll1L^ZUEyCk2x5v^-l@TvFioUzC)c>L23kH+l*_?~OwSjpomO
z^ZQ+)mvd-3g=$-RZg46#db;266#wwf$?5)_?3^q=zAvd?kHmh7DQTVib?-T)U*{?P
zdh|<73p$=kOv~+;n3UwVrJ4S$<lJOGzPL$CyDMoAFY=sVZnnGTsN}g>X~}+k>?>83
zl4-S6ED}?)ytE)aBQML3Zze;mxBo&Cke{ED;>S0bc~qmJ?gVD12a>`wFjd)Ang8UJ
z49JU%s#krsKQkjKL#lW7b=N8QEw^81kIl&TXJlb7T*CksJc6vGR<S49{<J`@I}cGh
zWcqXRF|P5oZLYCs)nDaU&i1EfWCyKW=+Q*YD97;1l5|wLAGuk9RHKUwNUJ?n`UI2H
z)TDHdZR#1TDP&cJO{PDPoSxywx6D;9De3;y^pqTTzhG^Uov5<ztkkr0_o%?sv=ZQ<
z?KydAA!8ysJ$D7ZovnKNp6Soe$w>F(yYd`u)~z>D$lT7zO3C-*JN2rk5Bk&6Gu7IF
zP7hei8-{?XZvC9A6<PlL>|nqikhY5}lUgg}a>(>&W@o3NAFHZYySVh({=EEjwaPok
zD-C5VG7eSbgAG=hv<zy8<6sk(iz>!swm&N)(><J{x5&#0=J{R2su~^{scB*Dz&hhO
z8#Fr7VNpz@tJ<R@+aJhDQw<4OX0Uqe6|0K02K~8NXbk71`i;p#V{mR0=Hh**ru*}=
zvU2_S(m6flJ)g>?WoBmh@ht~hii+)HSQQz-nNT1<=&m^`c}iL)PGzX!&N%`LJx8i+
zLP}~b4m}msTyL-oY3Tt!zCO}13iWt2k!zk~z06Ba4o`u{lZZ@zN^%Y|SW@kCndF?b
zY^mOvLbc3zKbOhO!fAwS9KgaJ2b6{?Is%JKUV4%{5m8$t=ci`jWM(YSZu``hc81Su
zt=_1zDY-fM=~hyze^Qg0lAdLBiLx~**-4n-GRj@8iSDEZ`;_L#H+{OMs+E!|`zM_a
zB$@91@qSX1mWva3*YI$yPgQgXCRut$j=S#Y^r=}H8CWARtE>}(==9mCNtu3pUuktG
zd1@d(fc>xLA`$dwWF)I~@~<2zvNQ4wF0M@I@gNkkSS4rY(aEW`I)z4u|L)S`WF$3!
zeh6K#)oP>FRg4E*fu$uSyT=new4SI+kF1mw9DSWfz34si)9KLb7*^3+WaK1=Oe=Uq
zcT$rV3<Ul7K3QJ&?32~7rnvKi3^^~Vv;El_7~`g8Cc2ZF)L<soPRhw&8LD~dxF8I3
z@jg^>e<mv_*N<-t)l=T{Nli{h4oNYh9IJ)bV_~L0n1f@Xt7f#@J{DFnE^+ahjX{O4
zA9dGm4eu)D>2xxOZ{-b{4xyc|e|HT7T(<=B{rK|U>dJGmM1=3WwO~})`m~Gy&SoZ8
zuXc>#>|nms?wtRa3DMn|NzFtvTmyjSq_q>CR+p5_%rti%$ikV{DsqwS59VjW!7&b^
zc1X`orv0F6amTGbvWe#AOnz!+j?pE`^O&rhyyQxK?Ce&N7TmGQ!%08BVA(Z49K$*C
z1u<^Uq~%dw-3x>0tE@XaKRXFpbfaTs@LV^RhO8XbA=T3d^7BaV7!$4~vC8(RWnom}
zYoe<+zcT&FsW=b8*GX4TAH@D=t3~;*92`<pa?}Frba7=u_lfFR=dlipTxwb-_QN@&
zLly4dU5jM4KPM$O#Tv?bykTPL3s2Hl(I2?UlZqRSuJHtqkeanW4q)UT(w3Ce92%33
z@f^KJMv%J2F|4Au$jQzRIo`q}y7QQ<lyr66b@ppmQ{4FpIgiQm<Nhc04du~si^u!u
z$o3~E=jl=Eyo`+QOem8Mgfzq)&4_kq0{N-5Ga)YCcP8DRnM^NMR5*r*=kuWKU@mTB
zS6ty*?d)S%6@wcWZMgy5HgwjEc6*m+=cVD5g^=2H-&a|EN+31Qk1tIRnNQjwlw9))
zYeaHxI`q!li=hhl?;-m9B#gtb-M5-kW%D!g^U?gNbnN!_pR0N-QL5LSix5U%bSFZ2
zDM{1^j^iCoYHJ^;T~+J{F4a=7F1XS_7S2_!N{j4dx}{%%YOSMY)D}5O>9ix1&A)Ia
zl$MuI_X@*ZqC67{;3U0LA3MEO<OOF!*|?`(Q0Tt-ss~FI`gDJ8UdRCTenTfSkCz6=
zz;LZeRaA|&ArmL+u2B)4J~=Oo^o}7Bojwr2DMaa*YM%&Yr=`>4Qq9>J^ydfZBz9~C
zkH>0WvS;~olTrfVF0M@I;UMH%B{KcFfgs(ObI#~ch5L7xKHHy;m$|HwtWQ+bI-`|U
zj0e1ooR>`f=@?J&(0ZaOJu>rxA;+8OJ+gCi@XC&JTt)AZo`jQZ*Vu+fG-pCIv$6OW
zl$Gce&(*0_rXm>3QcVb5?r;RK?}b-kgIP+a>jh;P<<`O*O*7K{>FIdw5#MpI^`6f?
za&g@7mrcaGR2)^?hm9&*o|l)M;jS4i_byKh2J9D>^euO>ko;BI0^DB23PJns@juth
z%Jiq_rzhi5t(r5F?&GB9hG)RCtFrm2$yi#-`K1(ZJK$<QZeHZ#CKz|UbK+tmM0Wy`
z6U6N#*D#>D<Xjr6*b}^1o1c;APDIoenK<xcMmtV~qqfM%#a#!L4?UvDCYoC@c>%nR
zVRF%v+S^hYOwO*<$NLFLZbn+FzhH8;Z^h(gXC=A2#`_saZf<s_dt^kjHf8$rf+-<&
zN2kYWZNPf%S$8NrbXQa{H0i}#e^~_<d5{0OrWj^;UT%hDz}snvOCIzG@`8E{RQnVp
zn3a`ok0jg0mCDfFbF~8<k(Ejdowt49(e1pKlkLw<OUbfY@K;Vja_H5u(51%R_9{9Q
zYfS*J#JCQ4nBh@+WM=Uxm3y&?(jzxFN%e|#^purG+f=bDnf{C*&d^JX-3MULdYl>J
zJ+h{i3X69XGbAG;CmVC5nit{e{=7g=ioe)-8sYg2Bs(=V+h0QOleKb)QEeZ3s?1+%
zUS_~ua};viwjuer@s2Y<?@MEPdUC42qOh9p3CZ-QVPz~GW1TAKKCg^ICUgoeZ^QT8
zva2$287WzK9kQgFueD<iW~HV}^?&KiBQKDP7jT^2AN4Um7{t34T!Sx4i#)u!E6+cE
z@&r8w$-x?rU{76=jdytEWm`GX2P^W5=IkRq1E=%6KOt8YdO}lss_0>~2CsNmW)sE9
zM*z2U3MM-)E?h^QDq4Yyll+tnckg(gVcE&_3bAu=L{oRBKQ)NA^teVwbo%sQMv9z#
zSYshNeM&OsSm~HcD;+<f<0@o|=cfd5TblOY+hN-!5Bk%S0(tfbuumEy3}<PM%O%Sn
z3<m6puHWhFN<<aAkr}|LMCllB`@loned>{xoD#J5<FA~0<mKZ$*fpHOa#6)_#sybK
zAY|2z)&r|e3NDq#Pj<W!l$Ho<h=uv-?7Dgef0mFHI=sopc@VE+cW?|!!`=7Gi^f-P
zgwkzi90N^@OmycTxyg7*s;r`#2P3@LoQ#W%2{;m4N%VaB5y;0oYs)4&P5>~ny`O$$
z<l)HSsyQloS};9d?krjjk4hfM%f;)&<<-9Vk&%|H-d60f|6KzRuTuw7aQDHPcWS=p
zQ;@ts5U&={yP7@z=c*oWLrKN*%GEm$hL{7<-TcT-O3HB$0h&h6gMJm$DBGWso}J=O
zMAR0k=nB45ZH<Je9nw?rW-gVE>Ysh&<IO!rmnhFZvQlzzWkO@aa2DfzjHKg_0Q?2x
zu`*bB!4T8qrHY=x34Ufi?u|N!sQ1&407iy;U_?_lUEAS((yqFr)2HR(W|nJAM5hmA
z;=OsL)qT@C?u}+;(9L12jouF3uIU-{X9lwa_6Vr<=|_4RU1O_pWV^T$p@)Nzs~zZu
zT>SZ7X-PHz^Z+mM=2%0>u*~SXs~Cz{u5vIOT!$J=ajhq+(jz514|gV=!#R47%(N8u
zsEXbqCl!Ai8`_L$&OFkwWa5t2xN^sV*XzW@J4f<yyTTe1)qUp(-4aX2>3wxCFYw;i
zJpBFPMCa=^-cLJ{@%G)3&b`NowvRbg3<I=04{y3~)f|;PEe9_HR+Qmo+3GB+c)===
zmxMbX&NEH-I1c?SWJcnxyXr5qL&kro&iXw>pBcd4VukI#=kpHyl?46-rli{E9a$N<
zQoD1$ViHAn+L4xtD+$*SfQ3B-XwRz{1~~f;re?VF5VZx){{!x!P>t0f3x8<O-4SxA
zkLtEZT81^ILtLUf@d)JOB{frP$jAGMM@D`wUK=iTtWU0EP8EHFOOh0PaDi)#dR^b}
z-t<)b-GystL{m4t=n`6Ybo$KnOnP^EwbzF<yjc<#{MEiQiaTJqs-o4gS|=W9Nl9vT
z#7MGF8N$Z3wYXS6U5iYXKQjpjC~F+qF0MpcO6#Y~0hdR(t&TKQ`@|zX8JD%H1%Ktf
zM_MY{;Tle1xu{||W2wnVN^uY8=sj}s@dh*3u!`Oz9e>Lj){bb-Jc4-F2X2cM@}Is}
zdwAeRPzv5TVGWO{&p`?&PMBO=Rxy0ys8Qv`6@KeeQu-&QW~XKk&vkqRO3<I0gtwL!
zl+j(p=-VqF&m#W#>=yozmBILcl_L7sm*JC2i$+!y4=<crSW;ZB%j9Ez_;-BD%MknX
zSa2SlmWq2$XovbF7HU!&&I6MAbyH8$1R3o5?IOo-`tw-={;VKgS|(MYmxmr9@5m1L
v14-FgQRq|M@94%Vi_cJiK9Fz!v*vMCKV_beFCIU<taxORyZ6w6=)L~~+W!fc

literal 0
HcmV?d00001

diff --git a/bsnes/demo.smc b/bsnes/demo.smc
new file mode 100644
index 0000000000000000000000000000000000000000..4abad79c38eb7fb0c53cab4c39925d45f195a69f
GIT binary patch
literal 131584
zcmeIwy=oLu6ae5et093PE<$AO=2}}QzCrdyg0Mvjf5>i;LU2G*-smI9LW*1X3@&Ni
z!bcDbQSt(TmBg9VfWmazh~K?%=FT~XJ2T&%2!j9t0t5&UAV7cs0RjXF5FkK+009C7
z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N
z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+
z009C72oNAZfB*pk1PBly@P7-8R^?TWRCe-4D#N^)O62WSn!J-rmG5=oVLBbwZ<_jj
zGmqi%?NkPN)V1CDWi_w+DvPe?X1jfJQQ|0$s<*dx@2}c0T%AO|kxr^M^yN<L&+(~l
zJ~S8ei0+Y9j&T{~YFxhN!MJ_BYvZ!W*T?f_aJ(^Y%iFtq?JK3!_P^VIxyX0Zm#gc?
zt$2O5_ov5v7|V8kTgPS3X6Nh5RqSby`lkiD^IxpzG7fvb<j2W(|Hv}Vd+PE0@<liM
zN^%4U5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ
zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U
zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5*B6@f?7CzEMCeRi-vo7A((
zbXFfcef(gswHZ-GT>c#0>i4^@5KWgg2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF
z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs
z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ
zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U
zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+K*V?X
Cvyn3Z

literal 0
HcmV?d00001

diff --git a/bsnes/demo.srm b/bsnes/demo.srm
new file mode 100644
index 0000000000000000000000000000000000000000..6d17cf9d15fb9f4a2358a2d079f3b8c755d005fa
GIT binary patch
literal 8192
zcmeIu0Sy2E0K%a6Pi+o2h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
GyblZ@00031

literal 0
HcmV?d00001

diff --git a/bsnes/demo_mode1.smc b/bsnes/demo_mode1.smc
new file mode 100644
index 0000000000000000000000000000000000000000..687d174918c33fc9b9041a9f4a10bf4eafb354c6
GIT binary patch
literal 131584
zcmeIvF-sgl6ae72rxL+Hwuu}z-dI~$rxLgEN2Ce}X;knmEClxt>}j2HyA9+w2zG*n
zbs!+Aw6;{Z%tjkQwAb&=vb=e3-oktvA>OmV*Qks4e1CT*K!5-N0t5&UAV7cs0RjXF
z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs
z0RjXF5FkK+009C72oNAZfB=EFA@FUyvo#*=Z;kgyd%N4ChgciT&qNdv)5qwur@Oup
z^>jMCJ1e{6CQ?^4bE&JF&waL<y0ZC@x@Z<sJ1QrOsV!zF!<3&~OX=t7@49GK()HDP
zoZPk%`9vOzsv9;%)%|D&RsPgWm20zAyB?FdK3&-OyOzfzwXylD+$it9U&ZCerCd1w
zbUA2?`sPcYN6w@E^V<J8h>N`L|GzJuJA61jT8`!CI*+xNdM}J=5g<T-009C72oNAZ
zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U
zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7
z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N
z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+
z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly
zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF
z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAn-;7
F{sBA(UmO4c

literal 0
HcmV?d00001

diff --git a/bsnes/demo_mode1.srm b/bsnes/demo_mode1.srm
new file mode 100644
index 0000000000000000000000000000000000000000..6d17cf9d15fb9f4a2358a2d079f3b8c755d005fa
GIT binary patch
literal 8192
zcmeIu0Sy2E0K%a6Pi+o2h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
GyblZ@00031

literal 0
HcmV?d00001

diff --git a/bsnes/demo_mode4.smc b/bsnes/demo_mode4.smc
new file mode 100644
index 0000000000000000000000000000000000000000..a1811a01b430b754b4e4e89581eff3a90f25b4be
GIT binary patch
literal 131584
zcmeFa2UrtJ|Mxv9kRT;NR6v0Q3+l0e?FdI8K~(IZ*jqq7VgXSsfIv2g3LZhQVkKbj
zpdJq@LV}=RBX(?%07{1h0wf{X%sav3QSbM;p6h*|>$(2_>;B(6f$V%|W;dJ9ZuU2Q
z03aMefFM8+AP5iy2m%BFf&f8)AV3fx2oMAa0t5kq06~BtKoB4Z5CjMU1Ob8oL4Y7Y
z5FiK;1PB5I0fGQQfFM8+AP5iy2m%BFf&f8)AV3fx2oMAa0t5kq06~BtKoB4Z5CjMU
z1Ob8oL4Y7Y5FiK;1PB5I0fGQQfFM8+AP5iy2m%BFf&f8)AV3fx2oMAa0t5kq06~Bt
zKoB4Z5CjMU1Ob8oL4Y7Y5FiK;1PB5I0fGQQfFM8+AP5iy2m%BFf&f8)AV3fx2oMAa
z0t5kq06~BtKoB4Z5CjMU1Ob8oL4Y7Y5FiK;1PB5If&Xj*Hrh(|edfjFB;a@voFX}%
z1fW)C?wF!No-Th+$CS2Hy}pL``61j9g?A+wjRH@R$9MTH#;2$*3X*y{UL+-f@fTy0
zx{tp|O)_%47?DIn$4@dfL=1JTbYbrou$u&IyV(0oc5*D+Csv?m^JCd7(H14^Wk_q?
zbrA21Hc2FJB+1?v$w?INi}^`ZgEaEK$WJo%Mu#&UZ}_ku(+Pe~xBOeWfUk#+K!;vA
zV5QU90ZBHFXPuI49jgaCCs#Y2b$Ud3PCq-~k>EL5Ko-ah$sHXpi2%q?>g!nhZTq}g
z1W12}eBC~84oC;!6cr=_$E(coE?V@))INT$E*3LEN=-mI<9`*Iz^o5Al>&a+A>fqD
zzXbee-<`y_CkPM(2m%BFf&f8)AV3fx2oMAa0t5kq06~BtKoB4Z5CjMU1Ob8oL4Y7Y
z5FiK;1PB5I0fGQQfFM8+AP5iy2m%BFf&f8)AV3fx2oMAa0t5kq06~BtKoB4Z5CjMU
z1Ob8oL4Y7Y5FiK;1PB5I0fGQQfFM8+AP5iy2m%BFf&f8)AV3fx2oMAa0t5kq06~Bt
zKoB4Z5CjMU1Ob8oL4Y7Y5FiK;1PB5I0fGQQfFM8+AP5iy2m%BFf&f8)AV3fx2oMAa
z0t5kq06~BtKoB4Z5CjMU1Ob8oL4Y7Y5FiK;1PB8E-w7<=wEp)^?9IP#+RP3M4Pk$E
zBgk|L03-n5-_GFsSs5aL076U53~ZV?ih3&e?V{OJZ_OJqDSpeOi6<~2(<gG(7KlO2
zXyco0^)V&<Yy8g}e#MyM<sL)$aU10PM+=v4s0%!?34jsX%A*DkNF3p~!7F&(u&B`7
zaJu8v!3uuI@?)4=&~$$B772eEzdWkMt;X&u|LT}146ID#KeRd9quVO5dO*kyrc-2Y
z_yD&Po1#Kjn7IYntO(&his{A&!3Sr@m@QhjXk8M2A-yg#D8^<52pGRWwG1rb_83n;
zIJ+b=0y{Nm+P1xX)v{oI!3I;lV{j6GD8DY|MELUHU&5w^U5NZ;TS80{-wNxtjXioj
z-xws!GG9~}0s05?r;K?N`Ed30wMu>&W)c=0Ha;Mj@3mn?gwvM5mA~-MZ@CzAWnwTt
zcv~4}6gh31$u=+{i!bWIUVUR5#HOxsi~2nDd|-T}KNf5E#V?r8UKtlLjsIW*J6MmM
z*i^jbLd>3xN&KqOXCfR|1Nwoj!0+|)>Dx|k9<psZzdFKZMbfrwe77Kok-@}`Q@6Ry
z9J=*M<nEY7>yr6Vp>9FJ`~!<Jx1C<#xOwk3uay%1qIDr#FGPX>)iNf=HcLWR<55gh
zsF2w_k;&g1mbhkx>!x`#wjEf$&SU)Mt8TNVrfj{nXawdKz9{O_mgH@3*RSZ|xWvfg
z;3At9QzwS-gZYkBArsvZ*xxq@u^|W$1PB5I0fGQQfFM8+AP5iy2m=4V2xv4q{Kp+S
z)jvt7*Xq?j#%r|jC(XfF!XM*BQ1p|A7{>WAo+FZCKWf5H5FiK;1pey@==BP9L$h9w
zYrcNAUSFeZY(W0bzt2SvKX=yX;kW0ZUN2MC)j++v>-nd~d)2sUK<|g;YzISnwc5lY
z-L`kP2xF<#p!M2jt4N#A%rr%pgq?ckyC9kTv#M5Fj^l4?cWvJu@!<n^DNq~R=<ruc
zL3YGt0PVSIwY~!CTAL0SgI5rYUkU(Tt-~L@J-Tw(b_h<9A*gU*VDybCDdgt#baOoI
zgdi7iTb#j(#(L1A5P>w0T<8mIPNa~HTLg?5C({H12E%b?D9`{5+yE;m82EyFUwihf
z@8_L|=#9N6m?Z+Et3^Osc%BJAADOU7kgJgyuaQ1wFPD>Sf<Z42dS%r<?kI4Aq6Y^+
zOK%mbmz=Nczk<^5@sqWUS%QJi9GI3$`jcHllI+j}1w9jTPW;lkisDo9IHH>%>pYDE
zXImWci583j?PTW->aH423di1l=ztre*PQhCH}GNynfn>7p|&2xfzqHSL@#9qvt2q&
zrYO7OflO{*YBpv2;eab$`^zDet{T>JR(vv-Ye)}Z<St_w7o&@S*r1tADLdq{8!bLw
z{52j(BM<uOsgqqqUHhjuwY0Du_TTKaZOS7<da^7fv{$=h_G-SM>w?ebL6YsI!~3mz
z#dPh@?5<DQxjF>Y8GYR!NZC$f#&jDRyENs4VShF-?hhcCw&eKKcU>B?`@#_+!zmN@
z?Kfz^E(0ath0||>5RyT!swcTEUhL{)e#q>TK{G2|#{uXQlhX8ji9zpAqmZCC^OxW4
z%@PfoYOM$NzysGx`X<BqACJAvmCl$!4M|8?ycohL?H|*G9YDG!7$krwq^XV-0aK)0
zs!>8hR38XgE0?kV0wT}}!og?IrWR-~*3r*jy~-7ZgcLU_+T+e~HRsV66HNml{Tp$G
z&hgGgU<1uS8;UPhw(X_Q11h=_m~!`nu^=;<R^;5z()P&Fz~A?s9uvcnBxf^fOl(PM
zMjQLRoQy${FRy0EEUOdy!&c^JjUD65Nez9)sGAr<K1ShLKJMag_)c98!?3@7-!`Ie
z9>W$L>?e(aIOv~n1Ob8oLE!(4z)vL@2yyNI{xDxH{`WKj(f*s?74l)%Gk?<XPQi~F
z!?MzU)W}Z29e?Qc-@`C$<%*y61{M4v9<?|v{~k}e4<MbUQv9>O4nmp=w*8}#1*0*5
z**C32XQQH-QNL++OSeiY6wqMD*RtOW7j;LcT7~Ia@h;mZBk55dh^A6&Av!XIp5pe}
zPMkqgD89x|m}qUSrA{)olA5`SlVnQL@8lS&R-D<W8m*AzRlx}>F)GNDi<J!=cX>&b
zG6!hMH?$&dn|Ko^Evcr8zA!tR1FEZgm8VQEETnCn^$8IXaYe;&dJe!9Dl-$*@Cl&P
z*dCw_r|yc|Du941de3bD7Y=BFj<jS+XQvYMb8Oa=%+8!)hX6g=UrD;bY&NR_a7J$Q
zGH64!y2)<7OC1dRyU6+pYJi!lj4~07DEJ73z<Si_MX{q@T;g(!cTbu2s)4Pt$)Ogx
zJax_4?MsG(l&`ESy+_>8fw)*wAx<jzSWC65*xLeK_#oO?4@NVY%x=B^2;7<UP&R8s
z#`TRGfrjb3<~+TIUCoYU-U5*t;A=xFu1UIIcy!j;jL3};)Bu;gVZhD!ns^!53yO;u
zVPG87&oXw-T$ditnE(!e;~Kb_Ktzh6{>eQ6i$C-RDI7quj-Hd^a=>pa_yRJy5WIE0
z3?yu4ar#=jd*I298&zrDFfJ#6N57Ds`{Xgu+c$5C<j6VF%H{TUfTZ6Zr)1Dr5{TK~
zuR@4oz|cUPlF1Wt&V;9>0m$VFxQH7}W?E$fA#4WRua-5``twR*8n8t9Dv{yp163b!
zAZSLp2a(vIt*xnVA|j|&I|^9?jdcKOz>6ZFt_tB6sf#+*P~TB&+(W&AzAJeLN{sGd
zdQAgJ29eY#y37Xs(DX7HGT}lF<T*Rb8L368f!Q3xVTD+xRFZj~Q<};VVLVi8AP;rs
zggQfOm9>b2cHm`(N}N?bQcifOAvxg)0t5kq072ltfdKwJFJky~t@>xJ!GFrTpt_Nt
z<4MP_M2pp(N?kiL2gpKv&_17j<T@_zXjOL_GCg1Nqk~T>nyaBo196lC(eI$RWZ!F&
zb+)KAI;0)VckkX=DW1%A+)wThtl4cAWAeI^L+^0(**_TBL*GElGJ#;}sw0BFIVs}L
zp@YlWn91Fp;ez9Zq5A{iJa+e&H*Rnb4;yCB-k%ad$r6c6f%dQ#K(>^OQ}DP=*4?$+
znZc+?e*=<1z0R%)+0J?|DcHXhC&xxtB_6*yZ1woxYMM^)ENoUe0T;Gtvg)@7bh&pL
zvjo(*+!OA*J%FPAGSF^DvBSVs0<%^0_l&qn@5mzs6~?w=2&h!1FHb6dHMGg;9M{3^
zDB$?M6iBUF^K%8OmfcNIaj0x_9#2Mc4|b{+tn4#F3zlc4BMW{2ECe~+OTig={j}#r
z12Gz$&lA#=ISxW8%lg3l`B2D^TT5t4QQkOs^XAyGocYk2Q>x5a;@)Q*Z&c}6;aItK
zcs6a?zm~ZFRsZW9^{??iW=suf|5g9L0{$hz{L=G`(vJmNl~$!xqS_vYZ)*4xd4pUF
zRa%3d&pPnxqqgCRT&~nYq-(4fuaIc94cZ2j9BIN41PB5I0fNAPCV_*3y8JH{Ev-1p
z4H!&|BEI;Au1eR^sew8}enNe-?h$O%x1pAtuAGQg*HNrBq%^ebpbfpJc>9eT737Sw
zM*}S1gDX9o$oGMWtfH!9k&_n&bHD<DSagcqLmA87ZMp9X*XIHUHPqNu@WG^`>jh$e
zaDQ;**6{-ZhA?m2WSp9?`+h&aNK~HAwj7Rf5X#*cs2Du>?OK;0@(3(l!KUxxfVUuF
zOz)jC4lli&L}?>u1a4y5gn5xCU%0r{XA~)8Y<DGn8!3EpCb&Ruqo|Dq6@g()?pFGW
zix<NmxOj(jPXlt0JaWXtd89u^O}M)_F0dkLC#kHD)gLC^|0wKd8XjLmNiMIVyo+^6
zIMA<ok2J_<=N_^{pBJ`qaW<7kR@z+37Lx+U>TXfH!kNrx-|iYz^^W?AbG}JvkjQnt
zb$L*%Nc2Mj6v*LVB10VE2m%BFf&f8)An@--py;qfA=7oV>(r<{1LY8|=P4w*nif@C
zs}4!1Z$AIxVQocAr=nA%HRLeVv0~|$dbM7qP#ba-a1Ogi+`;ElZMaAM`&?i6HjynQ
z#fZ1sC{tcqt(;YDRu#LxX20KI=G2cS3x-6PzqH@8IUvonKeftfO4gDdcVoBxd1k_;
zapR_rS$5IqbGAJAeoE*i=vvfsat8FKUb9_q-T3PzOOBv#IHaGcnNq#K>G3|x38DxA
z2IkqE27Wy+C=@ed?Wv~WdLy`L*dkFU=n!aac805I8t;3H3P&cj-Pmcq(`Ey0)-}ld
zeOy_+F97^%TaXAkS4coMb1sX;6Jk8)<RYIUVZZnIAs$O8;z(2FKAF6@vYizy7AD2y
zq4Au7zI*)7#~g~1@;I2#c`U|BK0S>VxwG!y?RpdEOAsIk5CjMU1cCn>1nwEnFS!Xz
zv@f8%Q!dx*jdOaQf=^-o+agK3LSBjA-O;TqQCU$ge=d_iMN_5t4u}*8WUq^hA1Gvs
z3fT<Ef&HPkezROsDzbUo5j_Hma}Hwes<=->gyQFno05_dZPV@*Twc;o7XY2#gY6a;
z>~$cP?MinM1hEIZKzTv}tjBViEuj(%SfopMItuH+4&{)Vp%VO3vnRaYrw)@tYbT&?
zh2|ZlSAh>R2#qWkkmfLfNs`M+H_5v&YuvM?r7^4N?XNzW@>$yc&0)FQafdgnUOsDh
z?Vs8A{l?^cj=6IEfuSD`Mv-rUz2x0qGp$JUKC;1FS5!rS891V<01->dLOw%10*1a7
z2b1!om_Z}g6)%-ac_=|wh={`xiBJ-QCLBS4AV3fx2oMDR?FcCAG%YF|SL$)pV%?!{
zu9K-WsFSEht47@w)UcwtMg<kHqeBA~EjpF9wyjpBLW4Tmb)BtkoeC{%d!H|@J?|*D
z4q2J~Lfe4tvDHhhcfne@33L)Mp#ZDqu%(fD>)MXv?}s;UHU&0LW7+2xsF^1FS50=A
zC||2(E#r^9hFZoaJa{0L7Uec57R2{N0|RPuY)}tK*U}yh=ik@Pg(V9_H7hXoPUdGS
zJLBl%$JD9?UVTA2oGEoLDS`Eokp~);%GQy(8>OZIs_X%@iUY7%MZpJ^!WOy;)&yHg
zpN?(MBK4DrNAv`NyFzv1p$a1wvhB`7mOL3t4rPQU%cYo5gvMi_-g=lbmWgHZ4D|=R
zP$-wnA$p;#0E-vOz(k>$T`%W<yX#GyFhPJIKoB4Z5Cjkb)GH0@6s<bBysElVS&uBf
z8n14bSIT5~Rg>&XZJQ2n*L<n1#ubY8)(TA{8mOW8+)}M*#lN&xRLW)g^6~T51>J*Q
z4cD=iSQ2Ez+unAUy|1Ksl?aZ5Fe53)$g=91&Ur|z)zcoPW?MZ;J$#0XotYT{jh5@E
z9VRbcw76-SJo%Ta_QTEc$(nBM#o4{?<XbGc5W+m}m(6W&n_pgc(0zJb@msgh=W4I#
z{ok!R$elj2xS!kh=l#9tk|&=V$xdTc>?uat5=hrmVYl|&@x?A!y54BSA1a`2>uI}u
z!dQi%Zewyuj;FZLh2BEtDrjp2$slKfn4X-OEKf#u-#1i({&~<~^I<0DEOO>#W^zQF
zOl0*#VJH@g$sraRDwl`KoeeK%Wd5B)MWMt^L=Yed5CjMU1c84?0+m&ADAU14g}kky
zLEi{<$nwi&RaJ6XgRBLa_!dR0Oed>VXgcuLT3My6LfM2;w5dB3tti)^Z^7Xf5gRtc
zf)g8Vp4Ua`$hyZ|DX;|YXq+6)pF$&pt7Ol7Es%o1?Fn>&fTTM%AfHXG2ZH_Vp|90c
zuT5ecgH~{d*0`Zcs@3IjIY0m!!8k5XbscR)B8}9Mwh4}}9M-)K(7_}y(u*YCxoxG@
zel8h2>2aIeOC<jE5qj}fh<2m1;2)|39MB)+aX)dl0!Lty;2Har=?PfiFS?J5HFE`s
z?Zp&V^afrgeQ%T0PCW%Y$b&3Q2!+s@Cz5b{Mabr(Dgg-Pp_sw+%aP3w{pxsVD4&#r
zY(B~gpy~jWVL-2c$7@cUGeLkLKoB4Z5Cm#fnrggKDtl4i{`jxm@tqwNZ=b(ylgLZN
zZ`%$YO#RX<lZc;)6*6V<lcx<ApNkbOV%dGMSX?Zw|9mn1k4r$=vwq>Vf$vT)`O-UH
z%|Rmq>6Hsw+3G$%HDBU`xPlFF_P~fr0~eURZES2X5C=e|*(LCfIiWW=BI61`X+n7M
z*q2uqoOdmXh(8bvLGjT+tnQp3v71gC5nx7oyUIxhxX7xLKs@z8z+14&5?Bj{u?3We
z@gTsA-0mXjG&1RsxP&D=cdoL-L1i#7qU+7vTd}wA$qtmZ1Efy0Zvo0xII(4*4a7|c
zMxX<@2+W;KNOl}#^I1~S-!GQbP}oNe{03XkL-_zHlwwl!_RmZ1E0;)lJk&Lyt8;*q
zxPu4+1Ob8oL4Y9e-%dae_5X4XKWn{VMB#U55NAG0(<^UWeVKxW33^=_H0fY`%5#sC
zQ;Yxl^~0jNy5Ym03$CQ!=Q;twLV*~}26t}nsS<}MESXLV&;CxG$Hf(l2few$BTATW
zU7jU)gH88tShIEr0QcIp2M^Y+RVrtY#O&a4OyK7Q$iNPmnUlewD^{5$tK(fwGwcP^
zz4In#Ps-{4v9G4D*Y=nhr=<C-pZUzSVSao9;fB^sxqAQ`2n2(G3l;Q56Diqy-XEEI
zX`G~hIpM?#b8}!nw_#0cAdB817)xH$YU)|GtVcxSw$*CQpEuU7BateaE@gD5^x8?L
zP#=*FlW3OC^<Ld~_KGz&qCO$1Gz>-s>hmY%2o3LOD?;M|k*SwLVV8rVE{TG^Y7vBA
z<E3beUIzD_CgCFp5CjMU1ObA;e;olmG>r2@b06YrZKVQgapdjP;F^|Jt+GbdSdHuS
zx=xL*v#mv^Q`f$zM`;by;G^k>bPBnmL_B{`zoK*sDQoA^34=ZC00;<F>vD2VpXRR`
zv1Q$+iVCivA2oe~*^HB5`}VU(92}Mvy9eC<>@bUOcZ{xeL~|Q9>UA3vr<@Voj|(^&
zGiGXI;{o5@caoo+4rHI+UQ?M3tonW;Q+nF;{$yvT9uNS4m6SZmXzVbp@e*!)dhKe{
z(IdBQ1g}g!*snOz0(+&8c9%ROZG8Npy}^!?Z;^f&h+W90dsmz(v;n}iXw4LgIDWF}
z&gBnvg<?SwSi_#2O)p?t54Kn^FLqglXyeJ7+9#4B&ehfD&-wa(n%)#jp;&QB3yeAQ
z7#7aaC#Ci@npLKp_R#a1v5-@~<Qa}3n~%!**gsbc%@Kg)KU(xP_6Ob7KJbtJXFtO8
zKahYShy0`aIsc4?*Zz}0BoaavRH3e;UmeOZLY6dq;CGFhn53$)-!#foqIRc&LEkj7
zB?u4%{!<AU9wVJPRcqDX&lB`q(V-dS+N=Ja2N@OIah*odi5q79K@P3tphFWsE2?B!
z&-XrrRk;xJXwZ(3V)HUyTxfpD>$#`}?kr{N8(!@#f1g_E-D*D~_hKpI`TCb4nW)&C
zX%9Tauc!(TCFpoNmm3m-i}+2~{Pn4K;NZct=DvLySjqe_r>t{R7WNis>(|Wj%s4Zd
zOk(XHuNn-rmJgW~U?Ito+6j`vqC(n0jQx?Iyh1(i<R8JucWtM(Wwakb<LB-+wc)|a
z7$(EiG}YT_!cIC*P@8J9i^`x{r{5zdj)LHit-+*uubqrB^*mU!c$=hSVdClEE}0KY
z#%5nUs2X*z{Sgl@vV8kGDPrd~;5~6q$SjI-9JvhO@!P<(#2k{+DAWJ^(SoS>sCX4E
zlwlaN2Ny1cFh>-Q)u0x9D23AF9$HRL6sD>{UH2d=+DF;uXhqs^l`2Rsmm+7NNx1(R
z1T^@YkKezE9%^(Cew@2puYooBKgMfy58fGchg#Cy`7x(7`q^`om)7F#@MT4!=u-6H
zToQ)kTCH0BsWl-jcK#Da<`i6~RkyUgs<``^PcrZ4Z+bpRf|Z_^h%$XSX!IyYB$BHz
zRknzO?k;q<p;0ZEYW~=4kzCF*+>Ii5{ygMmW{NW9z9?2o)E|An9)yn|@b60i#|<TI
z6*9^OXRyx@*P~MQR}J+znr9eCGs=I}XoD<#r$*5N^{V$B#q9}taDgT^FQI5<HIkHf
z6?ABF#5T<Q2<1)ZoqXqWut$fu<{a$6KYhrLJ?BRX+^(Y}_;IO!upu|R{g>BaNm900
zFYX;B5V0@`yDiLII)a4t|7|Idfr+@Jx3;jE4DzH;VYUdZed9t}#atGvCxOA1lkvp0
zTY?79$%)!wTWH^V$a732do$K@LPJ!lTf6L-bC2nJc@2`tOxs4Z;!n`;+BzL2Aa-Di
zpSkUF(r-3`A=EFl0$iUzP1&<{#fd|EeQ!p5EWq>9xi@=NuINqMJ9Cng?WiVc+`S0=
zBEDmrL(X-_1q|6PSMSlxbAja8Q0la{KKCRkn2RVdCLfQ747rk#6D7pfUt7BDPEPnH
zxk_%$D1y%VWjc3Fq*7T^qoODo3=zYDrQ>KZC9FYDTn;L|V}El-)$)e&`%hZ*EzYnt
zl;;iZ$1uYGe}{lx|Lu1FdOV#T&0_h3LqCGQ^RHh6(GLXu5OlB|udR>mFut(x!aWL_
z@e++gZLE&1nV%uJphMF>z|MAUU1#1)y;}7m=KzYwTlAe@V(X0^>AQ}s6m1{(R%h+^
zan1gi?TYYMbk^x{I^BUD(%(nNWUUD5=$|%w-`l9sj>n!H^WDBj^}#mk3?|Tl$D=nG
z6}t6U=YOVg;DUh)P70RdNs5V$q$#zpKAz`|6=E}eaZwbm)S8aP;!r0~iAWTKX*4Qj
z6^j=i%G$fkmluP>NHk>y{Fi%4gw7a4|KFU*km83lB7^!te@jPf2?7Lx|3(5j9m?zL
zzMlZH*r-nZyVfHM{-efGRk~JJkAM2~UUo+frI0JNw(nkF@$zALx!^+l`~~s0J7)mc
z+)|vMAHOf%S(Gh%QnRd5{q$A7{`SKN8dG9%-7cfw8&x3=F1#P*bQehD_&xf*IWk>7
zdugO`{|DXn<UerM_Z`(Q*JVCl)>8%D-?ZlSqt8tkRGPlnvE%}I&Sl%68L_D+((SHa
zpFRU}KdHuu`TGXnyFY1FdZQV4a`=jFgPMPt)-Bg{X86skA~>XBOS`$>!8PgL`v!q!
z11Af@Py7;6ljJfiqTMo@dzDj8xpH~aE(V#oz#?lL@INrnUmka?H-4{l%uKn+_my6Y
zM>SAan2#T{{}z~>HFUp`KP^WO188C%ms6l)s916aG~bDe;?54sME6umIVyzHHbIyy
zEa&5xQj2C1khhoyF&G$2@2)dgbE%Xe;lLlChY~0fq8j;suuCLDA&2wB^U_dp%K0an
z@cdsRpodz`cLT21>+nu3-umtEDEEr1^-%SXMkQrjjb@qDsXkxIJo$cOe?F;WLtAmX
zLW^f4U%Vq)|AOIVTx+IkX_d9d?n*lJ8Hd8`aqbHJXYC*RQW{<i4>M=a?Ej=_;7e-R
zu8~Z%Sk@;P*ipk~YlrUG{($?2O6j*IZbgB*rqnCyeP*_{lZ>A{%$h}W9e*2~ahZIa
zssr8Y4y{R>F<GdFGRVbZAqCRlh&53nYqac=4wc(gD!Kecywsl)im_tcwa9wQYgmpx
zV`~^v7DtCgp>HE+)G#D0DfaDap~b~e$zAwe%ArIq6vBTJ817kAYX3)nPf7R)0tA8o
zHUj8*Rnr2izkWU{T<bNOW`*Y4x`Kx4b4`P;=zIAbSL02n{kuaCTU7dS^YnjWdWk9u
zO(FB3_))^4;I=11fgLkHp+!~lp(OWVlh+ej)hoBV``S9+*4<2Km^1ZHQd&cg-=66D
z9~H=ZEANXU^z2s$GD5tM>FJ3fyZdKQeO`nPDlhT57m67}o@W{_LVvFnKD!NU1uA-&
zU|N5<<#S5<^t_rfkd`bw*O^+dxcRc<fWp^9b}Fr#!`AyO&b9OVG-(QK*KLYe<?&L-
z$vZUz4jfsyV3%F2?U`sGSfsLHqjeB5Pzh21o0|_>1TwT9t)Z73ha;7QijpM~DV!vL
z_V#|v=iKZ2@++Qa0e}fk3jCOgfELn5OBaDcE@sUpP4pT%Av6DCnDIm?=Ws|@RdBrj
z<OOq9_so_vIMS<EXHZ}GO<uVmCg(Vd0a=-pi8B;|i^h-V7BUCc92(4JZ=LeW&WIdK
zK1Gf{KW0`(?H-GU+S-=zs7R0ac=I>4e<nH<Kei<?D8FYwQ6H<K*wcNV7F+Z%?iM)U
z>-EAg4hM?tm%8!4X;iA`*q0rVe$yDrCfM2e{rOd+ay%NR$LITZ|E3Mwl9H!Sf7Z|b
zSvS%U&an7A`p0-r&m!X=bx@Ei>t}77{i9~k{O10sQ&TT>t%v+A?9q$Vb>IAk?W5;A
z(E5PiT~qnG;O`2;hlTPZ-}UZ09F3>xcfIGxByMiTcU_fc=@~!nyWVvj6L&ZHs?~VK
z7k&8UW8?qU8r<_?8R_?x(8CaqYQkZz{b{%6F|aFMukXbB?7H+OM*vI;9;zy0be%&^
zw&t$v%rYiDeQ<JnchcNgbMRrIWJWo=QM&i;icn|e$*uYrtV!4JRbf_9@IE!E1GsS`
z1Qa0DZSlk3z_*+rJVQk3h+nx*Yor|H>Ufa3$T)XO)U*I)a;DSzpr)LUx1N@+k*+(w
z(s9nv7tNLt)CS|e<S#~TscK9i%F5(o`67e;PG&HYMXdGf@tB+(gZ;)f@oIRI5>MPc
zC(>ZQz2j6gUs0w7Cx$bw%YH*t>;8i|Hdtp2`%1;|E|sAC<WC6<RYc$82_He=e+q%F
z1!R8sGCE!7PxWo6Jo}TzQHkz*@``3NaQygpol()(W2NJFExyj#7xaTpDY-KAc-gmj
zy1MfI9mn58zG;%c!+uWMv7z7e#(4QNdH3vL-!x6#oq2J02x{L(XN^}?ynO8DhMw<!
z2Hm0G_SD_{;Z8@#Ga^I%phhK{1NUh6c~GGit#GVwQCkWonR)owfH^%>Z?qdn4UtL;
zcZhyvSSa6Z`(sx^uh%XhYWZ$%%LaF|ha<5U?Rq#3R>G~YTaBIb(FnR5IS~|+T!1ks
zwkj)oIkoJWm}?K-PI{N3EjZUV*TZGxiGjKPxA&}D>s}mqcHMil)=odw;!OoNi}B*c
zX%EeolDNo<&m7JKPaZy<Ro_k6Yn<t#sW!|}E;m)zerbRGEL{i29BjT>;xj#Zb*{7{
z>d*5F<uA)D@$MrwOUbo>OtmVWYBKUyM@M+qx_#3S=OLlfOG;dNzUuZWVBXZjuV4GQ
z+;Gfl*tbAkYTvE%x*D3Id3IjjesgNu$>^${F~)rX-)is9o{JK8yNqAJ?z8cgi-3D`
zyixwDj99RD{oeI_&vNLH=K0C}o;!cd<X^gt>|5cu|3#2d|B2%Z)?E1IQrHbg?*7@U
zCiWjt0QhB7Kdo&Dt#~+T>ZeN!_n6*;zuuoU_o1X^LHJvh>i1g-btjfaUw!0+ISijy
zyiIiL^2N)dKKlpn-sQMxfc@M*xD>LL_@?6x?hSB*d(+Wh?5Wq6FDn<O@yc0g%gQ~|
z#&cU|zubRd_N)B|UcTHPHoJfl_VQ(StJ$x*ADI2J`^ecRS5CzPJ+8bqz1Y8?N8E_`
zTid6{T+lD~Zq&W{n4{JIb!^|5znaJAr>L`@6uf$+|7#E!`{<$Bp!ezv1y4#-^?&_B
zFE<))na^NSLr9lS2l$7+^mOiN`JuT3SA-4NB0RvX9xi^-NB@{*R~fL;l4V7sxB#hT
zd9y>$+O=+LIHPFVT_cWK@3x>&ckWi$jwgjft`8SfceLZ{)`hJ35)-bRnHNYqyvy9&
zmL9t1{X&J{q3deKuEXX=_U55$K6>lT51UcDMfGA(w(rW0^&CCDGbm(5s<NX)*&rVp
zJY#|`JLq6r+NR|s%5jrW$5iG`)aycJ5)r{LIg&7Bc|!M6)dFT)n^n(2^kW|~Vy|DH
zLYK=;y46p<Uiy2Gr_;>$4(qh*;B2iOHZN_eFk|0=zw(z*KT~^x1c9<202(-zm3ORT
zd-UtWDeo6zUi(`c&-^}dOYjgf=6z<;Dfi!XU@4rhZN?sc>8+hAWuL%Rm-d3?;58}s
z=+c!-m$n|rJj#1J(TGhtmSsvO73<1Z1*~DeJgset8la-pHw<7`sH`8iJC=T_@sP0k
z6>FSC^t=EXg>I7IVybxb=)-`lb#_4;HZiSkb0Sw=&oi}q<0TTA?nw?RDM_{PwK%xt
zOVrpXSPEC@oAnI+xkk**=hf*^G;6DD<Mqb99C{?8>?E?^5Pq}S-|Y84y32lJ$e~0A
zC+)J|SeKu8BMAJ56KK)2x5(>0DnC3fE>7B!ncu3`wSKNHe%M~P^H$vMIn7En>}+U<
zZ((h2*53S_2`w5;OJ{vSWp!bK_-W$0h7`eIwhPmJ^o{*CAdc=k*_ZT*y!TRq_prw?
zU(76e@0Kuy<MROYhWBxS@$Of<1u5)}uCAlO{sRF4-S$kIba=<rvz6d%?6Z7k-xV@3
zXWT-YZAA@hU;gTT?ynPqDvsPwwQbmA)jQ4BgMFg~9Lf&C+5T*H+}_=P{Q9e`O3L}O
z$C@>LEcfg&GxIpI3#~j?^XTxOSDH7wyu6uysjd#fs6=={wE&Vufvi(?EHnwc@s`mP
z${y0*$45?@L_)aOujHYT(IRm2q?jvQ0bpXLn{DlEl`DJssOv$Ys5)<uYO1QYoC%jJ
zLFjP^{jCbAMszy;q#!^4NC1Qrxg$mt#Fac9YSwVBaj~Ds<7nbzmks^gl-=hp$#wIU
z>tf+}B?a0+G+W&JQIIv6ekbAi^JgX&-9*BP{&LYC6Dk;Na)10MZ>|tPv)0Y^_cwO5
z9vbEzkBLyvA{C@7$4E2apr>q+5NWt)51>w->_aP7qX!>UD4tCpIVw(IF+;!sut)ub
zZU+vOQ2aOOn|x7heZ%~7(j9qR1^X(OCx@^B(!z?lE|c=_7rc;SNY^vSt9B0F{?r>#
z3Mt-HlJR!n?h&065fufaqT08#x2f^|>GHu->GAR2-p_o@jCSmDIw!yM_;EbN$LHw;
z3+hgRYIO3hn8yH;^!2Yveo^#k-Y<_wqgGkHerRK4u1^tX)zUa!zCjQBERFH*=dwN7
zEEd%=K*%y?n7pzIOkWwxj@@Z|X#4eEG*ZlzygZHvE(+V$+S;K{{FHV$9Sl5Mb-Ek*
zSogeZ(Y+lk0xOWtpqQo|&il)K^2oj?Nl(qEn)El#VmMlCH%kDUHimDBh*sCi<?HoL
zxT4aE>Erd($JIGAGtcwHiBv)AA)kp)r??J5lk;VsNIbOtYM6PN<8ep1%N2^lAgXN8
z?Agm(C(ZMgHf1i2IrPRqC@f5GG4GOecJtm`k9pA(M$Zp#O`CU2D$(D|wV&7Hsh}`5
zi)Lc{%h3BXxIDo6)9%%)oe#XKX6@K@($IbDQ=HcS*{<vT-_!4<U@Q*jb(Z#3Vv)-Z
zzd!CKVmuD3P;h*hXg+kQo)lU#qzynDYlq+kn_<U@6Mioq79mFRbrZ0xx?iCM25K}A
za;&#FW=>~<*RNTeM=0;hpmpB2wfuAR<NL<O3P8pIH20W!hO)=zmfO19DH^ngYBEe0
z*}${dq}xmlx-P9ZEWw%dmnr@F0l!Wh!ZnkZ*bN-WFnPS)oTNR$xSewA^!axwekwor
z@*5AT8?|_$hzCiqMehXrX(u$)u5s)!!KpukmXH8|C%>SG&Yru)61*$+AHO~J+IBA2
zx$4wVVba)LS8w@q+=kxTE0IZto}lPs^)#Jx>LA#S&EC=jkc(r(Tw+PPc8SHCd|#D$
z<<6aEWb3`SU!Q`H!eJh0dZe7)lCsQklEu#Bpf8MJ$m^1xnKXnxac=PS@OU=kYUW}S
zhKZ@E>5x4?)OQ%}DZ&v1{?iDcLEFfo)@PjtbrUl@X;E7nG_*c<>QRs(02P99lnjSz
z9g^tJP-cdBCwc&!Ipa9o#yXwD<p`p^MR6<M_kH&`nUT!HMEqzi4C{n_73M;k+*c%w
zhEXC#OaC=Phgw@ZJ3H{B?_r$Hn}GyC3f?E4gBiG^dRX+Xhxuq+6!IXAF}k!?#Q9tM
zqLa}*c+iy)1px@uwg1$Tc4`f&E+D)6)u|2V55<zdCH&fcK8XHJ>vTZZyE}$`(>$pT
z9$EQavxGVwweq{>NTJTi=v!*^d}RUAoYmj8u`vhh;rx^44D$J|k>%oC+3{URL;%<y
z#O8hrF`(w-KWq071^>hw;Je$z#(q!V?-ieK*z2n^GrM^l$scs;X;GeGudj{-KJLlO
z`ySug`bcb(z~TBzoc%>vsBQz_)RQ3(VEc&}OES|9q^)mF2JG|zq04lM&~O{DY%e6R
zSX^)~Q6NB9MsGm{=n`}t9laZ)R*<e1fUXMzA-U7s1hoekl60jZ>CDXxzOJyYtr$2D
zQj?$EuLCV3P;cd$Q4R{3sl~WAEl*!q8uT#WLh81Osv*59s6hD@nWNdrzKH@7=~JP(
zIfS*f6WL)tgH$)J-@c9dLm)>zW>vAeqvLwc9UZz?^YaC-hfG_2_sG6TH^aRRJWqjG
zQqifo`#e1i@n|?8nMzr;CrN9PWE3J4Mn-PX?GH;nal$e|_oYjpVAhj`$B&$lQC8SO
zVRVG$$vw+YBm|NYK}DcY*x6}pQ}1_}%f38kajhKPX=4AX520#X=WL$|4UGofeKun+
z$(|BlJ4f-^@OgibS5Y=H{rsj+sFERj%%NBvu#)()Sed>&DTKjm<CIbUzMN#=%w&TO
zSvzg9&kCO+XAzdk5klCuD%^Upx3x8cAxUPjAPfvp{ZykCnyKx8KRDmy)_+>i4Z$cs
z`IBa`m@W17-*>ov$x+(ygFf_!V~Y%N|K?ugNb=iJzTunOApkhNNc~U6UwS%(LD|)H
z-)=ahb@9%!)^B<QTaTyG>T18;f$P^ti)mVtK85$Sryc++^z~>JsQEQtf61t|C_s*y
z$ih?GzP9`WJNGXdz229mR2t3!07{?JAHBy>wEbA~=R;^=kr@@bPI??_MOZlc-C0;P
z`0jznMOw%?&S0P&EKE(OEk+ePTCC6cctiZRZ}N5f{g?h#M@Ro04^aQWAD!Vh@S{UZ
zQ~cztt$&h`R`av&I;Wq52t^S1FC-vudj4Gc?3Luj^UqDK=r<*Ac=@KhpiEN!wz0aS
z1=qDz*FNregO^rH6qT(lI(<!bzWBcQQU2rmO)@mVMJJlcY9XVavuo5{H@9fbJzsxG
zIeOCSHMt&<QTooP1r-u0GDv!lJ8p0rrp=k=B@>f?ULWP=>YC@d?Kh#6BVtK~EFm)W
z82a8qDGT+m5=w<4401#e6G?dn$q^zC2PI(%rBV({$U=^X@&s6?w!WsNvkI@#l)li&
z3!t*?bA5F~gA!L2d~BCLX;7#Y^$n^jC2XjWJdiwTXltvG)mMJ0Xm5G->cNAe0<$Z_
zGLIj5a5hu?tfsL{-x^{jdb+T_u(WJ@(R=v3UT-%&@u^?M{oOlm6^q}!YwifOa4?%U
zp>q3nflB=9d0myu=AG1NF!onx9*vis`5^x8gs8&!`0&4=BpfCOCAZ%)6~K7yuVW?h
za8)vAzzn?rfcQAQr!bkriKq26;&^)MZ|Cd@=uxxx%cJ`;%{`BMFmp|$zhu@mCH|?p
z&7E`9rtVIZZq`ECW%cXN9lGcbi_8X*n894-X|<y9bL&=fGc_r+S=W2}=xx(IABQD{
zC6SGrgVnim*sJIl4Ihy7<W7FbiHK&Lw*Kxii0m<qygoR`byYBxT08mb;HGr%4N{tl
zmg!)JJGf^!H8?NaS-Nqcd|7g?2d}L4+JnUz-Nu&HWDEHs(NbyOz6tc-fwvcpW?`|^
ze(6$UopI;&hk7`+z~t7<tjqJZQmHft)C=Nxst6iQKQo&|qSBnCxbDD^-0bPTgKkoR
z8jK&0>q;rlb_&2`5KtOKv)E^{yC6aN=-&NqAf2^ZIBP_y>P{}6+i`7%&UrPHVY%_e
zbB`GOQ|4jI5+NFgpUl`e%fsz_{ORq3>ChAASAePt54Q6NfAeDi+F^OXK?`H^_r3UB
zSn>o}5a{4gL-r=kvRgUt@<}ws0Du)$HGLLZ`LE`l7W7?38<Sw;(Q~Ych4EFYgLPrS
z;V-`gCHv2K+N^1*Zf$#!9<Yaet_VwFIrO@5l}Yt|G8%Z33n)Nf3$oH}Y%EhAK8yrK
zMQ#zD9@`>vB3z4Hi>SLE7X7A+@fZhl^4<;tkQ!57<euXJe~Zbx11ABni&|YB9qsCR
z*L9m~z*gq2@n#bym<@T})8GC5Z<CgqjY-5N{y9Wm-XSg3^32jVPxrkxeY!KJ{IB_k
z79X>->BqLAXB#&R;W;epvADNWN8hTCUbTv_t+&EdHkK~udTm@#=iIJTXxntHt<lw#
zZY#I0R<|}~-FUsQ_0Z;+?&Mg|kFAj5Ssi|1%<7c^$7MNlUBja`Ha~eiv9&H>$j<9?
zH9@H#b-E9o9r_KcyaXFJ#^j`;@g$38b<CGVdI1X%z&>ywG`QSP{k%Hh`G)kAX@bYs
z_jHVZ`m}(OcdtHe&5l2FT5e{&*s!|oueKq{S<)R6WoPSMKmQ4he<?fa0r+#rty^tb
zIzNBz4nfU8t|4<MuB~lrz&~$W!5-)<0>A~-s2g>PnpK<Cu7>QT49MiV+N#EY;G%(s
zyd!i*vqaa*WC~gS0~2y9jbe6Wfz)I7J=rl@aV0dfFgDh*a<1v3vOHW|Ox0%kNj;-J
zUJk+WtWT0+GBBZ^JHr`wchK6^zu9oSvFM`|40B&{kM+zw*N*cbUQ1eu!IL70uh)HA
zBHlrRq@x%nI*FGxVs_Yr9RREX7*=*NX6f*uW_GRB3M+NKrak7KgfUzKeRWSY&CAbq
zDwjA|IL}-rg67>i)B&BXN;}L!!dowr7Mf826?C+oup4fXY~hUZB&f_ILXSTdS_Q({
zH`JifN{}qblVtj$bs@Smhr{DQsV_s4Dfwy|(8G_H>C9n?gkLrBP7wG%BVg!tZm`eD
zgm-1qaTI{O28Fbt7cMI78)TO<ycx<_T>)KtIYdYFzD0S|-+ig)C%n9j|0$An%%?L*
z>v<v?gC19!muP?cSoI1HwDaWiW0nlZmn`t?J$34M@=`l{I}f{SS41KXvf_HwAKNWr
z<6To*q(u<R%ex&BdG|N{uy;^oNWtN|VSkSKP04+TVo|9n&(qa)gUjvP5q{;BX>qS1
zb>sP6MU3rsf7Hpfsd3M6TV9bqd%o?KT3u&RRnEnuCl`KxHeY3VVD;Mi%DA|zyG>1c
z6<S-z^wg~0ye?{kfHUFGJP%xV&ElFQIE3HsyR21mFB*MqdC4+eNE?6s!_Mr8yE?pi
zW{Eyx^_I=<bM9|<b4BIHnHCnMP5im^fqsEQd-gM?96#+T%KLr(p|MM!*k6s;T94;D
zi=;GrqdpgfeKyWNw_+eea%RWQoi*MUcbk)@jsJt(myF|_=%HWUvaK_7C=BiM!FnxU
zr^;7A`S}B?h5dG+l2bJ2Nxq(aUZoV8Fz)y2?9@e<-&e3{Gzukybh@uCKXK4i+r5$E
zo1Z%x8)5Xa<oCjHTiYXBJ9X{VO*kgyohTcdx)J8Jw&^~j%Q%Ssn@w2v4I7lLrEOn6
z$3&N()Ok$0<(|*G$IH8SZ#}~y4Tn!^xO|pJURv%_=}ZSbp8GL2I>4TPqD++Q3+?Ur
z?tHTX?nyfbyQTIH7Or=rFUJ>+Xp0}ah6HY09;_VQ^k?Qf%`{eO`}sZckijl)kLC{a
zU1(FvGZMw^VZPlwI+2>r_MJ?l4H)1=84P;9XSlYt#Zg<(@;(Kf@5I0U;`y?c^|(`^
z|Mc|v+b0sT)5y;i_~Xe6#V4JjwCUqxa(6%ha0+aB@<{zWKmUxYJ;j&~$@_a}o%r3<
z-=;&=w{i{2Bm5z6lCNE>i_T8HZ=pe2o_K9|=lV}Gb8d8hiK9A*y$#o{bgnI1+K0K&
z(vlw6*U6aM=bkl*q-yc5PN%w~ySP(YQx(o<8dc4#AaB54+iY8S{z{^St*uw3hPl~g
zOIFzI(;10W-MvNbWsJpVJXxN)vJ=uqhvP?&>>c$bl2gWCT88B{_SU+8?E4BoFXTk?
zmo9OS>D}AirW=_HmUP|!SB47FG`{{jCKS^u`jVz!|79rW1eSSlb2Mk%px<)?<4jwH
zx$@BY3mn{6J3JWcc$J*7%#PzckZNPIh92_!enBrl?-;*;DmcZ}={%PBUOPNcsoch*
z=S;|jxSbBeoSK!|-oMeOD<<L40Som!r*CgLdF1j162S3KOXS08#v5RC%m<h8jspv9
z9;O>FS132}b#wZTxE6nWQqbI`xAdDfMMs-e4cwS~e$ukJ?fXl^H|eA8&=vHjoS`nB
zbvtFS_~sIC_7PC~rB&&9-Fm}^l9z>1W9(pk?bhg<+9+kA_O<eQ=aF8um0LTM*_-A+
zeL8_V!o>vOiY=ROXQ};k%QvbEM$aGEqT3SH=GGpuQWXP@$_7cd>LXe<xkhbV37dk?
zKHT8E6>iuP(Xm0be7QW>gDL=ge(MHT7q^W@HkX#O)g=G*vf!+K#m9`W@?ZF}&v7Bm
zx6h?sao<s6w`kCpic^mHbzgQ!?qwR6-?P~kuz<bT>q0scOgB5bLz1>$*qcSG9qya?
ztLL?3hO<1cdG{vQY&pg$Wvs_oq3iVyMwXmA^5J@p1>ahgc`bAAH8PVa-D_<fZ^5z-
z6-tJW+`hmmTIY^iz;GIdIdd-O50v5}Sf+2L#bdnT^5bWD@$cV5yt$c%Wip(dKklYb
zjvtjuo15clzP_2L$02&cahx-Y!mX^5<&02<uMqVz$dt^dMHOU9(D(qfGz3d3P4+GF
zsX|XfRx*Rf<FT9>*0gEf|7TBqVlRTg-vsoXYN$m6!*v=hY63tG)tRd`xK^V@T8VnQ
zp@mp+4eG7lsYd<xl!j5}>Mn<N(J9qtp=r+RErz>cfFY=%`E7_nIo9&b3vL1dLt&ke
z3Gt97{94J(1Odv$ZxFDh98OG3+Fom00dkm4=7#uLwlv7Vgj#AGWymzHxAgoWRpxw-
z)X3;W6fH5Xp!9ue()=3dP$NBn;XNoi8cDU2MoUgMLiNrKiE-WutGj7(mYkCd0|bK8
zm85*EzAi++$az&j0ADCrF3w*I*R1=X?WYVtpMTO$%vrm(akY)jFMR_70I2FK&i5Ic
z%yFK7gw7GCgCT<fm@iD_(UN(q0|Hp8KoglPb-uNf;k@8o08hrTK7^|8S!1nBX`z$T
z0RU@FWWZ|Ag}J#ELE#_!v#h4iwj9n{FAvU$ZCK&#3=_?w*c=Pb;0YO`6+zBA7QA_Z
z{o<i9HX#<p_hSPPwPyJ6v;Dj8c>32Nfq9^|!6$jh#~|LN(gBw;u58pmQ=iNpkaR!g
z@}R1WJ6L3uGMmL5YHw4rYYh8g<snN3<@~_c?{GeASt4fKaa@q!Rslbi!Cd~QVVPS+
zJ$`*(psXF*mg~MO=4vK?Ygk#v?phh`SKM8{BxG1>F96O7)Uv@nd|3=e;P0<*4()5-
z3&ZcYNitI*90vIx8Md#n=t+<vu@;%1JpY6yzipf635qxjYwIB<TbD01nKLKXeG<v*
z$g~sJld(;<55yud{4_bt2XD(vhMUeF^U8llTD#lZNyjP4!?2UtUiq=WGvPj2mY%#<
zxk)VW1hF7|NL^cdN3{&bo}P2b=FT+o{rcv%T3yrbI$hh7vnT4J^|kW0_9pGc*KNG?
zs_t1_4yxXfHP!Bpm2m+miq+kJ9Q%;;I#wX~Vq;-(WG~e;JbYth<fgsJHoaAAOj1o4
zJ`<<-F7|IB_0}50&_I(m-x*W97SC!CIG~Dvv{+NqMEaEb8`3??N#z+N(#LevcR`qQ
zH&-h4^z_XClD1e&CuRPTy{}yC=_%%%rS|!3VU~PJ*;ZZ-IRI$SEY6wHxJ(q9m$4}=
zFgEt`Zjw0o8iwr^g^UUe<e%KVR-7M=hYU;BJB|v(04!S~=3Kjm58JzUm}5l+y8kAN
z#R)?O%!?lz2m2qWxlcM9bT(6)_oty9rtjLbix&%Q^_S&;rK0w@oW91pYtD=Ze1~qj
zgW>%4>sm4ZdT{iNaMF@tES(molX_HLuj^q4Su={(^Oc?H^E4eTnm%$~^^B#f!j&zc
zzC-QRlTKq9pQn9ZsaN+vxhSobw$U@gUCVb%7TO7d_Y}%|*nL)MT5?2k-ot?sRn3#n
z+P~x)T%?i8sk}_y@f4uQ$heV}bBE{424eALfxJ)qZ(|o!IK8Yme{gDH@m{j`fgFEj
zsIy$YxK#4zyCi$*0oA5C&U*PLe_df!zX2pq8=F^t&co%;yt!0xfK*nXi@F=*p@xvl
z5sQ7ff`F)P5w2JyD)mB+_&Fy)Hck}L895GV4tjoM1qdTtJzUkU=-Gw%%UuEj2Gzt*
zYaR~up6Ch*fP>@NdF5IOs)d(I^F4VLj-39%AIghVdMK>`Fc5PrpFe3_A7dJd&j%nc
z(9uyIlu8Q{+DNnM0`5XrfnYv|5hP6Q#1o2zTfzGP8BawMrmEiI3Fz~kCIM(|9Yl+d
z|M0Gu&gI@Y5+D#U#`-#HtK?o+>SY(+^lp&XNPKZ2E^lq!lz498PAHd7)8beYY`qz*
zyibpH2=eircJgFXQ~7=XO37auPCpSnQs5dby~47GwTOD}PVT$6P35>=1Dm?ft;@-~
zc;M5;r=Qw7v<ezN%lr1ErkyXvb;W2VjutXG*DL4V*QYp!{qMI3=idqb*XjO_B{u(Y
z1l0euSfMh#Vb&P+KSS0~`Cf;sQ3d+nP*4ILu7C>kYc;s8;=jJH)KGt*)1~Y?6l=5G
z`>m8sMlndIka~0<rgdYJ0R^SR9|#6FC*6*UVwaIghIZx4mn;FBJ#-KzxVPjs$L2gY
z?y0@!<RNwf%<cpS9bFu~v_TzH*MtE~=pztewSs56BR<rXV1fWUjEg3C2kYs>=$c|Z
ziDd&IvuW*{A=%lp5|@+ofK@G1cg}Jj72fj1nXd;jnGC4azcEK)FSZP?Go+UR8tBD5
zKk$jy)&Q2wZV?^Qw@P>=H(!WnR>@fJeM8^X-kCdY2WZP%_nrkF4HknzN9L#nGygg}
zWg<)V_K})9mPsRD2l{hrE(B*MX1R`8Fr8&%**SL17ywzTkDT8bUaoA_=ZfH62u}Xu
zBOai5`}}3+N#0dC1f>ho(|x(;1*I=jm=`W6&6c4G(12?p&w33MuJWasDPyHlZosS=
z2Zj%~vKsi85@cj>K|nyshI4sVdk2Q1^!Z#M1j*!}Rinr^oTO~O@FT(t6r277r(Le{
z_Fzjl3=|!?@QL+w-JO2IvT!N5kl^Q+kYMJ&FvNDZ^%p5SoPB{wL#yMRb{uOtYu3K?
z5w%W=-&Q8g4YnL(dyTPv-yl`G^CB(2`AA%+lJ{sIaCWo+i#BWu15MkcAJ^?$FAZX&
zy$7(ngRt2P7eY{Y=)i3=w<%M8Gjnyg=LX=8R~LAR^D;i(Y2uahq9I7GWq|2Nb~O$=
zK2yG=69Vh~5q{Rp1KUGPCQn|nAm5W4Di|jodG@vG$eX*2Z+hnYiN+NwaFwgo{_?0B
z{Cx17DFzCc(IdC=v`>EBn(rx30jSf+Tjq`Ki>7uXLr}p3klVzz+BrRX1{F<s0HBZ*
zII2C$er$~BWHv<kG!h65jC$7d@Rp#HCsDK)38Vr3<d_~OsBH&1VrL%<j)V;YDt%Th
z>V81X@li=cykvpsVU)A<E`tMn2ksLjv&iZFwli4dX&mvpQY;<SP_q}4XZt&$&o?1i
zKt_jMD}8MyQ`Q?m8VPDNu)FD0spr<kzUcE>T2MdvZpKp={d#h74g?l74LT<PuF%7n
zGfZl1VmE-j)ZI6jkE<WNR|eVC(6xzMjl*wnK78~F#Fo~eB@1Y%4P|OT`A6>}6;@-@
z+RYefNaF@|yo~h9_fpfg=W!$QZAhmFSup6+&1mX4_lTnWpbteQA8TW-jYF+1Ua<nN
z|EIk(k80xD<M>So3HTxb!3qjYR8Zg{#vKJsz@Ug0aRCc11f^(Ipnx7MXfm?6KzK;4
zf|UZYsepiBsR}mW0uN;qi}(aXA{5aOKyU#AnchgLOxpAQdw;z5=5h|1@BQY^@;RBg
zcYgPmNqJ?9Sb0Qd6*fo{fpVDaxsChu>7G5gR)|EIY0tmqh`#vBgq{>*FF~^WR%BsV
z=Q%l&FRMF`fHHHKwZcDvP7Ke<k9mSfTFhX^3Lv3E?R{2uhV8~AqX<(C!~Iu`TaP5$
zd|}+~RED%iyck*ODl_?;D7PJC`&E!4BdZhYc9`tXjcYd^$|RG9Q7<5KnWiN>iGeRW
zNEy*HpV_^hw?p390<gNGl_uuHWwCPv@50IhFpxM^$jS04lFqsHuBO8U10zKhz!Xdc
z{&Rvk|8mAaQN|4ZjA>ySv&0#Z)pCI43v8Z;yy@?1Za&{KG=Kpcn+no`fzE7kXkzJ*
z0s{{NpQCh8jn=I?efr@;MB+7xiIBdZH8qFZpi>+zLCn1KR~9u_#AIDH{PBDv0?h7`
z!Rh&w_DdQ`wT~_%61ydLI6^>&^H_^1-=YZts`w>_aidP$^*OsLFCc*<fFXRSGhe2A
zHa|*$a~rCNWgVBbtfH?uF(H5hXAeZ89~a%5uB-cv-r(=w0A;fgc%Q+TOBn?4>ZfV}
zbuXj-1N@|nR=|+|+(5<$+Nfr;MWXfVMF<=j2|oJ2|NFRcwF)&U7_W)t|8D}Ly|^kD
zYP6{Ocvb&Arr~qtV8kEJ0>IIMszCiwjp@fz^fg*Ym6v8TkYK-#Va*$20~P!n_fs&I
zs?wW^X>H**d}jt}Cx84Ldm7PbeoO$~Pu{sx<%e>G*0+4`QA?=Dv^lFK1LmFEo3W-B
zCfWY9A&KpPFx%au>8&5FGhm?+3Sc{H`r*xID3d8PiY4p?Ie_(8i~rWaR>OGXSC2p~
zKyUgiyIRn_s?D}=?KUtU6|g+RZ{~&V;Oj28(1NED{B2e)5Nh4yHtHVGRrL+~CEIPS
z*X!&KIjwzdSu4f0D>o%IK3Vzheed2NWTws0OILmn3-jJ9`%9SNvuA6v3Ja5xYJ`br
zUC0Ky6(nmA%IZ7ZI={s5{5l{1@`bj^y#@1vO%?@jwOO(DdRY}cq(I4fJ$Y#3@QPgL
zy}u-Lc$Y7&U`^56<hI}XTX+ZN=EkSSL=3cJJKJ}k;@Tb56C8`|KQ43a>5*Z1#{<RT
zr4fqb-`^M4d&qie*8>Gs@G1B^BlfyHa1;bap(wBeP12c7Tc&TBzQeP@_}8Z>_TqCa
zerst*N10rA0Aov~XO16_pLV1hGw!V*!+bFiL?V%LEm71^%K#p|6o}#<YSy7YCB00Z
zJ#X+kFs$V3E!CTs-d`U(MbQ<0t(fnf;Go-<ekS%+!?LcyLJ;6us=?BIj-HRvpF{(N
zV8r%jYK^RQ`J!XLS~Sk%-cMaIf_2GZw%Yq=g2ySp95w!MOAJFx;Y%jE-iWFEC)3#Q
zMpEueE2|Q!6A9*hgU1ZA&c4XFcIncQ#%cC|?G@;CQzY;i2>0*LLaMB5V!W-q1WSVC
zYpUJt5rhtIJ61&^Q}p!_Z3$BXufk{PM-F6rEPK9@5q4Bi!osN754$fGl$_qGtYEag
z<nxEAlZUg+i*7#EVSL?&xdH~2Mt!EanjB0f!Q<zHzwa`7q`x5JN}Qe3jKU2kGQX53
zOw^Yr>{DEjimxm46x)#pN7r14JeRxPqa5wxIXgLpPIq@$Zh3(;0fh1f57o^ln;y}v
zA!|NP2>}B@x<A!bE(>=bpl3I3CQX!@3O!N+_N6>TC=3@W32ssw{x<P0a)|yrswcdE
z2cWU~?iW0tu)FOq;5;+@YZ`X{(9u@gy-R_7790`>-1vRl9cpTnK~g<Za0md^&TE}F
zaU3{-KA!<0Y~T7MuBJ6gbZ=3V1hi2$q?XDGl=6!g^E>=rD-i`d^=CznEN|puV$ZXl
z4Q(P<W`53xSJ|1}QNG+X*ct;?7S)DgVH_=*x)b5C(*$;Pvb|#V5^>$N;CBDGbY9QW
z34x|_n%T#ycn)*q9H2w@axtYF7}!%XNRt2$oU^_@_@FhB5^eU#!CUhx@(-_Aw%pSE
zUgdYM^F?7;%G4Hyowil&;;5?LAa6{k+-d@YVWOo;v8Sgo0T83B4jit0)!lpG4J$Cd
z&#2+t>d!rnbbiC%Taqf^6|OqBxcZKlOGl5*#gvUaH@89w)7{}9Cy2L)d3I77V1PcR
z&z*Ih_iy)eV<TQ=OX5$RYz_;0+Yow4k^Uy28T~q;GGxnZ&&^(8uOyd!FG(7BJn_c&
z?(UmCoeR@EVEb}Tf5*XY#FQ>Pyc*0-KXo!eB45r%n#!<%%x&En>o2F=ZL~ZzZGPF$
zz6a=sB2GFw%gaT!&vgCmqbXM`sNlNc!tfrQFmmlF)Pj5)cG@Dg^4Jc=h=I&E+mWo&
zHh!yrQWUSLD%fHR`+YV$XNHbW?NJyzoaLkmM-K1-Kyw4*>)9d!EUN2aeL+DlBVNEB
z)A98My-0yKqM8*|`EXc(F<|_k4d0>CL?H<LHxnptAI;<)JBB+Fyhh8gkD0z>ek6+b
zK`}lDw|D_wFIb16V{KKh>b{v1pFiH`k?`6g8^ie<^zgphcD$Z!gx93|`1a=0@jeL0
zpT}G~yauJC=l$3|a^Y2EY+3aRq~jHanX2hO`J;Cee>4JbM&NkwQ=#|aHGoq<pIi*1
z!<pmpn#&!pFf2lC{VXTEAM?j|FGlM@p6V+2sT2$G8eNCseH8D*^gdic)%2fywf%E@
zf<GSJB)kUo_~U0X)qJ@WM_f+FYx*SY-})d9xBHlqgx5e#!)Y*FNfY5DhNj{*VB<B1
zgV*p58&^`9IEkSWyhhZv&uhc`%v3dvmvG39uSmNwG&H`(l7-jcEQa&faPU44&P9%I
zzo!qcK_Z6pwO}l8{QDi(;nx?fgV$y*`0bxD!29FZ^;gUIvlYYC^<T9i>Ieb^0fGQQ
zfFM8+AP5iy{&NIi5R51U0fGQQfFM8+AP5iy2m%BFf&f8)AV3fx2oMAa0t5kq06~Bt
XKoB4Z5CjMU1Ob8oL4Y9eKS1C&3TxDT

literal 0
HcmV?d00001

diff --git a/bsnes/demo_mode4.srm b/bsnes/demo_mode4.srm
new file mode 100644
index 0000000000000000000000000000000000000000..6d17cf9d15fb9f4a2358a2d079f3b8c755d005fa
GIT binary patch
literal 8192
zcmeIu0Sy2E0K%a6Pi+o2h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM
GyblZ@00031

literal 0
HcmV?d00001

diff --git a/bsnes/g65816.obj b/bsnes/g65816.obj
new file mode 100644
index 0000000000000000000000000000000000000000..f333479d5eda2636e8723eb7bbdf85a2892678cd
GIT binary patch
literal 289767
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
F{|E3XASD0*

literal 0
HcmV?d00001

diff --git a/bsnes/gui.obj b/bsnes/gui.obj
new file mode 100644
index 0000000000000000000000000000000000000000..6d84676e8f835ccecc732b7478f6bbf5a09b5b86
GIT binary patch
literal 67128
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
L=Bizx4D0^_*Jd7x

literal 0
HcmV?d00001

diff --git a/bsnes/libstr.obj b/bsnes/libstr.obj
new file mode 100644
index 0000000000000000000000000000000000000000..7518ffe95403f512c4c65b98d52b0e450fbf9962
GIT binary patch
literal 38996
zcmd6Q3w%_?-S*k+5&}ea(G{Xby1)uZLRbkZvRl}M5D}t;J0cP;2?_>C!!AS{Lm<Q^
zIfPQ{Yke(RYAv<iO089EElmI;7ey{sp?E=SEg1FXq5`7uKL43Hx1BwksIPwC{5-RB
zW}bQGf15dTE|CJq2g<JN{+v@jTT!k{Qdr6=E-#rISz5x+6s0c;F28mremi@VtVl^k
z#8e$Xc|Z)#=P8_(Ra`PBdW%0_gL+Vy4%`BPb>Muo$CDe&7e;*qn5PBKiE}%?y}-QJ
z1|P}y5iseOp@2l{+VKT|2@9N^d_MFa1I&VU@Kph`rVYOJ;JXi)p=59*7Y;l5W&u+s
zaCY*MzIOogs0nAs_cSnDO}Kde@PTg^FrNrqBKsxvQ<U>@P_mPc;vijM7!aAAe3`(7
z+QFCKPQEF?&1-|t2YJeXS!=@C$#*|6kD74t>=y>#)4+TxaEa`f(qB>1a8R<dpAT)l
zfyp)D?Bpu|W`+qDPd<v5dBEH&aEau56qx7R!M7EdPuszlayj(HLCH>ElCL)~69g{N
zdQb*TbsKzP@HGIl!-TW5-)q3UZ^GHx?-O8p4gfJyBKr*nCRgC>^eqHO0Wj;@!M72Z
zrZ)I|;M)PrhbEkzzMlf)%0LGsJNd{TU4a=caEbJt0L+|r@Rb6yt{r?EfoW<7-wt5D
z5V%C~l9s6`{c%vT)7OW#!2&}#N_O^}0Nk85_{e^xz^pUj?D#eS^Na}>Fa9WAnt<^P
zB*_$|BMv*hDZtDVxJ3Gv0khVGv*WuTm`6>xc=D0HPXqJ5z$J>8Q^2HTkrwv;Ainc~
z$rZRnd{cm#*9Ko0d}Y9F6u3n3vJ05E+u*AP-(g^G9fSf>BEGwTxmV!q{6YGz2WGdx
zCDQkOU_NbwFATo30)rw;cK#iX!EYb|knH3OqiveN5RQ@^-+jP6(gt54`acCs(iMz~
zjcdo33QW2Q7cc&ZuP-o5O*lKgYGBryaPjzNf$x4`z7V)X{^&Xw*99Du?CiG|ZT$s?
z0g>6s_Z)EB+Tin{|6X8@n{ak~Ujmbw%}2G9kNCO+bCn5a#}@{s(1eR;Ke$$z4ori<
zC9>axz&zOwzUP2B+z!4kfk_>bSl=+|3(OROOEiBYz^rP6kMvz5FnnZt|84?qR~vjD
zkn9KMunA}9kK@23UCBpH<lj_aG6gP?Kf=Hiw!z2zD==;8+W_4CZSax44+HbG31_G8
zCSZ1%aPi{L2fqEloD#T1`leom^#undJNp%)t*^i^ATm4omI8NI8+<<WUkl7e6V8tB
zd0=*!aCZ8>2F#}>oE_g;V7gw-wXoBd{F?^MXn{*)zZt-kwu5geFdN#z_dGB=+TaUA
zzSn^94&{0zn!kgA$rU&|eK&%pKwvndy??(1F7+CYvg7lixjQgdnQ(Ug2m@1S!rA$E
zIxu&baCUsFfVszni^oU)eGr&k0+-0Y?*VhX9eiH`lR1prB@tg3m_mWGvtJlA(}B5P
z;1c=wIbgQ6!B+;py#m7}wD)gr5ci=tDA~#9L)#2sDor>$f7}Jky(XNUKh^`YTi_De
z?|ooCZG$fi`OXRqiY(d5H#~&>9}Y^1^qmGwg$ZZJw-T7UO*lJ!*8%ggz$Mc65HLsE
z;9CpXzYrLv2r@hQ8h(hl!a*sKz7GSl)r7O-+Xc+qCY+tVhk;2O&c{upZzeDyfwPmZ
z5H$G$!x`=My%)F*ZSeU(vJsfwCY+tV{{-ek6V6WGPl54|;L;`1cPKEU1<p=i^6vzJ
z;f(hBz6ad#Hu!uX`4X7)FlVE2?ey&n%vC0woxWjU$^<TvzN>(_rwzVY3f5;}&YEy`
z@}=Y;u5eJYv!4%by@AO!;q3SdfSF;!+37nEn0o~-k-m=t^L!h8vmoDAVEnl#AUSZ@
z$(IGpa1$<`d_MFa4a}`3oE={|Fe^>Cczglytp?@=flEpt-)>+I2^{GWk1ve+4}lpl
z5(T70`VIjm&xDJ|=L5$Lz$`N1?DVYwrp|<m$4C0!4a{bNOQi4Xz<kgKUl@ExfeGZH
zfRsqzVZe+r;o`~X1IHv_A|{-jzE!}iG2!Czk-ql<vrXU<>H8)yAGN_p>(%E1gCa|I
z^4&EG^9TneyLj=SZ9Om>O*lKg=YiQ_!o}0q2fo*U`BdN%>6?;|^#undJNagzt+&7s
zj*^{xD}lSa4L;I$9WalZaCUsp0MlZ^+3C9*n4<!hNMF~rxUaxLDUrTC1%@N-^{oPK
zO&ffq?|r~LV#3+!`xG#nO*lJ!Uk2tQflH*XG8)g7aZs|;mmWA@49vyjIIa(V?BuH`
z#QK7Rk{w?d0^JSF-U%Gn1wWi`c4RiMV!0D}c%rF-&OL#qc<-G@0yj}$?ZzcL-wez`
z6V6VLWx)KzgtN2r&w%-(z$LQti@^M&4ZbqS_m045THDDtZjz!D;h>aA-}%7YZo=8|
z)d2Hz6V6WG2Y~sTz$Mam4>0ex!Pf-YTY-6OGHH?cz1rV_c~#)-^!0(`05GRbI6Hlv
zQxxR_9F*+%sNqszE}hD8iS)e!m>hw#<MV-LEHJm3aCY)VfvGj&;`yT*1N{^j_l;b>
z4*0R-%K>J*z}d;?fr2*ybK6aA^F08}69Q+)N6Wyo0>c^Y<?A>@QF`E@WXDJH^#bOK
znH*=gZjhgTB`_SRtsB<$g>b)a2aeXE-^9bsS+Ydqr(cpgHdWiKR~x|hjNr7>*9QTc
zfH^dav!>$5&cD-UW50`olEyc%xMbe!XlbN${+wY2*X54%nJdN><lT^S{iumPb&}te
zz5O}rwC_-G^OEG8n$y0@|IsU!C8?XYtThsia2aJt)QJ)<5ICl&5r4{5wbJjorpguR
z*LbaCV&P$GR=cYEr;eY<%iSli-<qx7`kwVwuA7QxYU~#R>c-(!dLi%1O7v>}JXS)c
zTtgWW3`0&)$RZebK?<inx}e)j`7T=K#Skg=$t@VZMIVBx;R1k<<JC(jD1OR#Vv13#
z&`M3NZHjc_+SF`yO%ePq5R-IV!tQ#BNPa*W5~vv4MJRVv)I5L6M0JKgWlCe2Lmla@
zkN8uAE$*5XXq`NjtMTI$b*$%F^|1O<{f|?E%}Wcz!RGR@eDKE9S|Y6<nL3_>$9mN4
z=693SJ?g3EBT4lmT_=94?x=a!dE#N!DXc%%rA|zRZ+tadQ|r6bPxPoGQ`9c?r7ONv
z$9i+r=K8VTU`u&T(ake&+Coy3-d-hyoc!ul3XpSqEk?=k#(JDlf;Xs((h~=_S1Lt8
zYGc0RnrppFI#1zx)oe`(F7uRkD9Ub{xkYsssjfegU&!m!lTj$*)hlu0KSk+-gFKwZ
zwLQAPG3BLv1{E$yCGQ#@wX*q$f+yyK{wOmaxYV#$3%j)hNZ}|wq6ZpCMF%n@*@O}!
z#4o*s<9<~O{H{Xb76sZG{noCfwTg7%T9TBMn2Pwl8b?Qk;v#j*RP{{F_H)@yaG2-#
zlWM-}<euw-+m?17uLWHS>eQ}<6ZuH+X%YNJf!zx%G$XtUy}0D_2L<Ly`o(B$)^N{K
zB+}ehQ^spE(jqbWnUL`%&Or;)Iu%+oo<f60n<o}Nl8~k*w*t)ugPkO&#KgldZPW$(
zB(SGIR@e9mI;~zXTX^l-^U;g5UxJdsPIZ(t_OU24b`NAv)jT%I?}5(>$t-b4A`g<E
zyewMzIQ?*Lj57#llqec072+_@hu|{T((Yn1s2v*${OK65E;WD^Q0>u>=l2%XxdvO8
zD%gy);$9_A@k*L>VZk$*jRB#VF7PMUAdaz8O~#`5;~LP+BM$E6z9>=BG?<REO<WE~
zSgLyvsalLShPnk$E$uwj2-D=LV*NM8C`Ca4tXv~{a5@VIAAK}Rl(aZ4LRrkLHsX|!
z@#C~a<M<YFYOu$~=>miO8^@`^P9C8I-?Buj?f+ez8so&qX+#^xH5L9;hh{e&e-hp;
zQkzX7!`41+-ExTK?{=+c3ax!pwW&0eEno=lcsy&@lJ9x+p}<P?3$KG#QL1nt=CpZ&
z-Gq8nTo`Bg)16xid4MfYCW_iTe`X;siauHdW@-x~VvZu3BE+lE8boWhSGg29pS=|K
zd=}9B;+CQpf)qVoWjJzLuXu!AhY}@ti8-nUWq65J!91)cw0@}F^c6&#bu^0!$vG}Y
zi4r5gZygT9)8A|s8|<;OxRJACt)q2<BurJik-!s#!{8}xN!8?CyS4{<^}*p)e8>%U
zx`tBH)`+`NX0m%h>4EH6QTYXh&WW0hs$H$(j6`b!d4;d8G$tQ66D4EZAvmMdf&VDK
zz%O5$QgF=-YS&CJ)}xW^nt4<`y|nWbzUzb-kRq+NDe76E=ymMMIax!vf+w-(di~BG
z8D|?)vl_iuqeptqxQ0B(xw@Ql(PJ&H0m{v$kRq|ylB9esBk6ezjY5e>7z#>+G9;&P
z{yLPut*?oLM^db>f32~*Cen7?qbd!ahMo;OhV6^~VAb|W_l818!%PP|ch@u})wCq7
z+8%v#W_Hs}TP|suS+oBf+e&~$5ihl9Ua~9A2924`b+89i$Jgg3<`I-3Y0QtI%q*fY
zNBmxGDWQGT*B^yE(+#XVj%X~p=2L<fm^K?x#+YK((mseZ(gOFJj(P!DjWMsM0g<#Z
z|BSNX`H53B9VhwI)T0PCuUIuy4Db17N<(kjxAB=o*LFjiX*i>VdCM&DJj#%UX+Bl`
z!Zd&A%6?WofEu=b2M<I#70qP#gEwu-K399N>UwoY#_<M6D5vt`(Ddcq8@yeIZH^3f
zZ)$RH+FR4)3vQ0S+S(^H8?AR}tzOZ3m|FkX+F_WhYxL1;bAo3opDkk1M=nDm3F|3C
zf|xL!qWm2P^OXxm!gA8hcE3tUJ}<N@6;l<pTR8{%lg8LlCXLsYJku`K4V1yr180;p
zj_oKj|4DlZ@|eD`nfOQ}TG_Z4Xjf{mQynFyB7S$_5bV-kLQMg`zJi*s%5+`f>~u9V
z*e}BwC5?R_%8b2@J+J*pq)WU#Fx{aW<7)d;?dq_fjVqoEoMl1Af+~A&?e?k*8(f1C
zM4b>s9b7(aeshC+DqFD~Mkgge84@-H%mHtq%ru}omc!I?BMgy(UuxlAr+XesY$Ji+
z_i(U2Y-JJiP4l~csWY^qHN#+|Yd$5-|NlW*JP(+v#?@subh%@Bhs?Hg`G_$gnk8MR
zCB81lv_4-$7lSQUm(Lj+dlE5OzvaZGv(leN)Bl(@`PDta*O&V;j^jCnw<3+2)g6sP
z(y~83u^~d!z>8-SRflV~ohzDo^G(ceg<z%xt1(5+pbQ^if7sUSC1m{BOAZx&Y-9Es
z9I>;vgU0bKX0O3cbB>ZWzd9T2-+1;K?6I@gt+9V6v)33mcJ_MNxHTW8V$t+Wq(I@<
z2^J`R3Kab+p`H$&sju|=mfxc8%y_jPkx_ATs|x|+Ye@A}pYC0U&0wTM_33`mEZP^U
zN8OuBJ&y2-chA9!!6Wt9okh9^x7^v4*9VV8j|aC@CaEpzt03_=4)IuH?zbZ5aBpc|
z4{4Pmzx-PGMvKCWxCPr0g@lYBg*`b(JFX!HM{E@K(Kx<E6dLTYQP|&L|He^hu*XK>
zK#l!7i9%!C*eD###zpwihSpel*<yrSLJC9vAc9I~)Fay3g&4ZB_T$JEwR@`u)=%<#
zYd@~K2(g!@ZpqlGe$~)@nAZ_?HF)Z}hsQ;a(f%ucG{VpueM4W%$|#hOFw0p;T&-Dv
zCWH%I*o_z)2`v!mnoLL@MX~pKA&ui}Kd~`(bq0Iv{y&G?D$bKcGR|4UP{BP_#;#7?
zp`OWZI<cW>ru)BeC%|UV2&Oq($Jrv6&*g5%3?gLw88lYYU5bAD{ge6Lkgj3|doLlO
zwgwk6c7ETZg$XTOY{Q{`VXRfb118=7U+icnb33%dmV}IN%jukhZszGO2Jxufceme`
z279j<TNZJ4u;NLKc6TttkGpF=$@C3EaF@xJ8OPK!&g14tqV?EFG)RsZ2`e*mTrnT1
z9kw83d|S-t9N)?o279j<TP$MiEUxfkgKzv`Z($2_T<tX30;^0ju4m)bQ_iEfU;3gU
z8C%_pu+_b=p&M?O0_NML9j(1^yL1uuj=b>#^WD-Dt*&8?=<o7#8eMK&61Dp!67r`p
zwp_yP&<<M?GQKS<ILEiLrNQ1S#+G+7_KB0#QueCjD{)5vbFzJ>$(ZV~;ECmzPngWM
z`Uq(}ySYT&nSCx}7w#O+Q(sh1H+Tbep73?ilP#`63R|<aNE?Vzjdeo1^VRkOE4ha4
zuo5BTTj?j9<6BwDVDA-UrPYl6`>>L+0>oPBXI#T}Sc#DFt#mKv_*Paj*n7oT>6eV1
zzfINOnwjRMzD8khdUp8*6SN0?6iOX3PS&}4($l<5uo`neEXL4Qr}bQec36Rs@vZP%
z&hf3RV6gX!vBIN_{r|!W#;lFC!XLN>?XUtN<6Gfr&hf3RV6gX!vBF;%d(8c8_Q%<u
z8&4a24X%qrfl62Cnko;LVpk}?Dg~=<r_j9R9q7Tsp)nO<1}RSoU9-&P+TGecl!J0U
z%G+Bzhh~@e3e8(~sq6Q3*d(gEXv0|3;<}9PU-lj9a(GPb-aDI$)EDVKSX+lk$T}gZ
zW|&Qy9rSyDd{D53o?}o8x1Go6!%ADUK40VB-(ZWq_ut0YWLxcJwxWItmRJurSEtZ5
z+&o9eRP^HJxftf@o*7`8yZ_MQJlr_snK64lfd228^e4e*FzMOz7^c`OnjVtw)DmC!
zy;`5Ip}WBrtNR;_P1fBMCtUG}D|AJa#RU}a$rNW*7i0$1U53;1q4j$vt-0q(ZSip#
zJ-T3uy{YLT=}s;2b$?gu^EGrg*kX16fU&LkXf+nMiIb<QFZkD?#IC^E2eUtB-bZY^
z>E^wDhTjwITy*nIE4C7R3q|{sFn@H0jt`?wJ&M3>=olIpO>N2ZU*Px~=#^GqsEVH_
z@pDfoBifM{I}l6>mip7&jRQO2?}J@~vbT>y`!d>1(WrH)-LXvyMEh1(IVz%E8uOF*
zh^?2PvKuPrpz?+!{`jvonZM}6i}W6lr1~`O=1%T!?O1&}DVlV0cm1k$^qOR3OI~`q
zqqPddB#%1sIG#%~DULjZQfQ#N_9wt-!?(D)E8ofZNl+Db>cZ?a>PTN2yUJaA>$!91
zs48jHkqfA5K(yk!6a_+z3=JfEINh~(Ve>7-`2~uhLEqQdE_ZEbW9&<4?90Bdu{*eH
z*C29*-oHXI)c5-uJK0@(zA<(m8oToQ8oQ&rmbPL-@86*qn)!W=o#L*&*cdy5#tyk_
zYcTDGx(2yxyQ1Pd4f?!6j*+8y*mrW*(jAj9!+I1$!`-#3HBm^W?@N@<(G)I5YdWn2
zGtX!%K`Y(Pd+S_Xb7(<ii{<KlUz|Hff_)e3)0C0y2J3maLBT2-{O8gkjjQ~$ayArr
z)2mN+igr>*yVStG4_Z^JPj`-X<!7JN2U_yH>EYa(CRcD@`98L52)?~EyKyz|oHryr
z<cxM!$GhBr=vLpY^}LV^eI40*PyWbN?`T1DIKQUZ6+BV?n##xfJBbi{XX)6+r~T{M
z_#upsMctX)I*1l^S4MJc-|EvHqA6gxO5NOgQT6HMsH;zMD;_X+jJmoc)8d~JP0CKb
z7CW=xnerEA8dorFPexyJ(0e|wvJpAoCB29eziz&Q65l-pAP#RGg%WSQ9wpxTSG{$&
z-nw6Jy&AKd_bot)_nm|i@B1gcb(`M0TW=kN6_NMNLy7k-K#BK#OmA({Tes=0{csiG
zeM2bmzIiC|z8m${7xmUx^wuD*$h>bMO1$qhlz89Wdh5US){php^OMcrg`UFMZ(v85
zgKcYCQRt}Dd{oFE;m*>Yp=2LqTMleB(h%#O9DZ5HHyHd83!)K0&z|08oUSj$p1WB+
zseXm8T=9wPHui~Y_I5nm4K=tf5A~0_u|-K68Qj0rO@ytTLYGH7)E<m<9-9-~QTZlH
zUhPqWOMi7xNc$Rm6+&+x+^cSfoH+MnA4JUzf3bVbG}JV>GQjRSm*+1ArR!XQzZf&L
zn2)y2T|0m<sTqw!GSn^Ar!NOpdZcqhL55=_&Z3{IXEIJTPIZVcVqS%I&AJYg`FFYz
zzh8YNV^@poBL3a-Wc8?c=#knu$?uzTD{QH7g2qaJruN7L1L0X*V}ZjV3^&Q2i6`WK
z^>E{ubLv-Wv#?Zl6NVXc;$id+XphDlBmRKe+!z{Q#+V?`j$ZFHMw|}k9;oZf*oi0T
znb)C*&YQ81i;vdEyl%8W`6oboe~YU>*8?OKcn}?^+3Fol{zGGN5c^8^>POCEL4(cd
zd3zf6U^wN@F;q`cTj-Ha&DKJ3H|2*B_`F?(5`E=>;DYUWU0;+a&b&$%a^4z5=~EoZ
z3OyA+hQq7ejGXuQ1SO8^g}KN3UXBv4yQ~-kD9SKYPz<xa_&th(^(8c-l-;~hOZ-jz
zX|2!K*u)!bv77j_jLqhS`VZ-adPXD|8W_1cG$4{48Wb56x-60r>Ko}7s*Lmr&5ZmY
z6pAJf%^U29To@W2?O0to*fBiPneKnLun)6~*oPjmU!jsM=1_(N0bmt8y+t117Ss~o
z7AabvuVD*=E!Gz2F}9kI@M;pz6a7<F{c$4R7$UU12x0tqjJF=@fsB0!<g|+UQ}Ftz
zzq(WXEPL;X4bc$|*DH0C>FS?`7nK*NJ8}ty(@f`P`hKmy_*w)-AMQ7P;M`KPHMQ<~
zg$8l9wsr>6n>z}9yi~%3Nyqz@2Ow1DOqxB;7l|ZI|J*JWmnD4T!y}ufcRmiU@`PSO
zLHR2Vtj_w&C)zzSd(+D&>7!`#%O^r|`^Ua~>LDza#+TxNwiL4$x&d5P_gt6#vGJmW
zo?&ApOvmz^M#@25pS$is2!&U>sBds(g?i(b(Suv#e$j!@(W8Fl-c*p~7{zXpgWE9g
z{dlk2O7C^4I=Bt*bzAXX_kUm)`ko-rn4X1?-A}*?LmRr(IbnW!F^0vSZGcc5;@mR<
z8V3sb5{M6_@!fQ4os%r;Jgoks)iH|Pf~9Xr@UVMLF>b1e!1+4srGJ%<kNwE#X)yX<
zpa8e{|L7$Yl(RT+?b0ot-foK%GQP!WaiNPJS)BeVf|g+Di^yO$A2JyxHyQjGKD0<@
ztG{{*OH20N;5&G$o(|)C+&`t)yTKDx(=xVD+*J%wM=8XJC_YLr$8ib7*Rsxi*E+YL
zkEb;$Hyni1st&?5Wa@MpHRFUj3R^O~Np+qK9$o60qFohJ;L?acGoRm7gRzOWgQp-5
zO(l<e4Snc|m+_zAQULP;jXc<lJX7tq{3a5laYz!L(C<YTAEcr8{AuJB{B4T3YKuQi
z!Qf1s9nNFUBS3qcTUs-KCLgkv{Dy8+jTt#A+}f=nHHjK9-SS6KbvXD^<x0{8wSGhf
zbZBu6=GPqU+h3EnY2!Btvfqxwt2}@_m6d3=@k>Do>>6Tqx1q!@0610dz?nH7`U+pB
z3ttY=F2$App@tjD5|}i!_)JyFpMLJo!{pDV;9Hmy9#}NZ{Zra>2T!=y+>f!a10cKl
zD<WzS*cKS5&A*#S=ig0a!b0iv-9%-Q_T2<%`iFz3Bi({8M!L8+g_3X*J<&>EO;p0}
zJK+!(80W!KY552X{Ioj4L0qM)){&g3_t990ifdU^q&YuhQNcf`#%mWA6#*?OXks!w
z_GUNH)UMs`UUP_~zq%nc*&^-DOxpdBHd&K4c$(ymcrd)@P7iN^yhrK0(xq-`?WJzR
z1|wsq^MrbYZ%kf+aDKkc*oOK&SaiHhZmbd+I}v^E<prc_;}8cT?;!N+kI3sMVri&)
zK;Po*)HW+#^@Q_vXR~^s^<u#K6Ju_;p;KMKfOD-W4XKX0)B(9+v``=hg3a#LJ}fAc
zr_$HI%#Yf95fPTYB^&zl*rE@_cx;_SiO1F%J+>T(9wWBsj~P1xg}pmlI5OBdy=<-Y
zd-3;pXsX6XaxX<Y?m3);7Z#t<6nM^u>Wt>b(dX#?L)rJQ+IJ$!i2W;CUC0Buqpt(<
zeSAo#eWnZ$`|~aO#Q+!#AJ(yvuw=SceB=QQ)}>piUOe1;+@Fa`M7H`BEdeRw5xRTT
zOQ>#K?f2tnA|e%!NwY$ixoazN-hib&zxs3_np<6&<;cQHo|lz0thq9PhsT*{bpFYK
z*2?bHr>|Mw&6W04=g&V(YQ`-ZE*)vDd6|Kl7AGrSL#V-o8rU!?%kihA>MsJ7Y1Lm`
zv;2aF=0A3JrG0)RX*0fAX5iH7BY}KeF49_)1|KA0ile=ul?QjEv|y>8MqCvpm{h}6
zqjg58f}?0>tszs!GZeqR5bCPXoam**)rdt&Ln->@JEir)(2{63%V1cc(^nmgTn|Cu
z!Sv9QhzlETpSD6kQLG2zqIhS&jAr#z^%)0wS&4LDKZUprrUjn60frwJeXBZ@wFIj=
z&HH<p;m1#Cy-ejkAngjrw|0jux}z((1v+)dQ-vOi{^tiNVoQ|I?zDo(+$;03*T&ym
z-n?Qf`Cflhv6eoa%t2%%vvB0A;StpF4K!UR`39OkMH|j=7ox=Lu0n~T%B$RkQjoPa
zqBNA1eu+{M`g@f_ddY{+J1?t1B_;ttdH7}h@p~l-9hDUyc>#uA>GZSOpN1b=b+vD%
z_cM=8#5$XKm{`=u{b4}#u=VI+OEabM9)AEobQQ&VHiK_m5WDoo>;K!>^(Ts5zZR7V
zV^>GD8M{8j?ie1sJ`ubA__6Dc8@m*Y%n>Yb53#_dCs{sRpVJYwmrxKRWc>(PH^nK1
z?F0ntC5rx9R*KaLh*jFPt=LMzV8kje=$F9feQ<b{-pG02(wkf!xXFO?z)eMo2Pv&;
zJaFlIGF~?kB_6oHL5T-0y-($V`)8DR;C`%^FofbogpR_mwshySh|QWezqEv!k<Q|!
z;4O}Y^OwvWgg?Gs5-HD`TSniKh376_Se7-vIJr+3<s2|h#r$tFU=YRW=t~5aWd8RP
zFcdHW(cY=}k{8$w89S$&1xiVZ4~O~xl0oaf(?M?)X$(q9?C)sI%<NXf5k?!Kzr3Le
z|EF*beJN@vxfpZNyz&xFQ-#++#YJ<==qiXrqZcilU0S+$F0WuUW_j@7C`KNaBoEto
zF-=M58y-9KOGBQZ;7yj8*(KGYX|lwe!bbNYC+7aUZl7r|PeKi)6p6VLYOOX*k(fI(
z%zETx%?}H9959#{qlQvviJ87Xw=#E@m}y(V{q8_%!&l>8F__n&hEl4;Oxq1BbE?El
z3%}FhLr&HhvvLeVo5rB@EdRmZ5|dBO9;D5UmAR|LO!3AsL{m5HBz8p_^M0yA@<`0|
z4ZfAxBQet#mIm|tJDzyMVE&9~k<OQx>92FF%;!tYv=`&nAW2(`7T;trcN4;UC1(0-
z6DzY<Vy6E)fYT91PIf-==}nmEf>5CqiBfloxd&>k%-tpCG=}jZCz=Vb98(SEae_Hb
zV!nv=GOr0~5;HwM;8901=ky%#V}p5tV7^#lzC>caSYl4MFyFqX;$?$*wO~${m}wod
zS|eRz?x{07QK}3+fk_|;m1jhur^NgNiMgl5>|>ZPa-vE8?1bN7rtb<U`6T9EsI|)M
zlbCxm46W*9=Pm<O)2e<#F!z?2`$){aC1!|-(F+B0w}E@FG-Rgh7$rYrE@Er=><F)m
zo$r^S+Ny<L8jG%6#@w;S;T2-6zLFOGB<8*nbAN`>>|>2Xdc#7gzr;*`nPio@zr>7-
z955QQH4YaE<^d9OhQvHTVy4{)XO`peKEa$RF%OiOGbQFMhVdb%l)JdH*zoCJ1ap?e
zJP25;HL@gTvV(Dz`In>9hX(UL!5om7>3e-Eb3kGq%rF#(bcOEx+IcMo^KrpESYoDI
zYb*0$iFpXa_>enrY)y{f(n2Ll7m(?ZhDgkq1~JS-B<8CaMvD#WtQ;(uuacOrmYA=S
zn1@=JKPmjxzYUqE3Fe^^^EDFlP>FdM!-Ofv@uOe71Gj6|pie$14U?E@KV`M^Fo~IV
z)=oz?<v0#>7>wzqG1FT~N+F5)hp4qOha~3V3=`kZI|TD^iFt&?JX~T9GYsXFCfpU?
zVaWW6U=B;nIlx+F4ol3r3=>99$+_;?xdw9=+WaBqO3WisYh})rnDZEhW{LyH(bX@P
z8_e|K5T!hc8Jo5k<~)fxpJ6oSAK$QIp}{;_Fy~9m*GkO!67y(=nT4FD@(<J3<4HP6
zPpMomkCvFPL#x#qqb24s46~Mqkh*SrcZI?HbHO}DVjc^um3fTBT);3s<Rt0LpRfC^
z!TdYHTp%%D&w6=8FZ|%~S_kCjJE<FR?sWK&6SKeLpjiepy?Li}gTy=zwN{yLkeJDL
z#?|V&bD#X(V18FH7fQ_ICFVkjd4h#`*~G`+Hke(cAkqYhc_M19GEb10>5hu;duhV`
z<<$<y4dy|Dd6L9DSz?|fG1C{8+!`n-kG_#<+N+Nj%u^)hsS@)PiFuj@GjjKv4Tj7m
zf_a+6e50ioPLyd9^K^#sA*Y#=e(x_<7|bgK^K^+BipAJ@y2Lz#VFJi0<rUv;ij9W^
z^9+gkW?-!zoFOsKv|y~(ct$YKl$eVwy>Oz;l$d8Rj1ReNjlF_-mc%@p^)k=FSrYRc
zhN1aFsp7&<aKqu?C&~%IJV#>2A|7LnITCX*!}yRBpLN|xPDT|{vBX@0TC1IlCFXey
z<3mo&)^($gV4f#2-@<yCtuaqxzLjApHptG_bz`_-zExtLFEQULF)y$%Ti1<Qf_Z_&
ze4E6)Kw>Usm@wrytm{UDU@n!IaY>7@bE(9<h+#G&r?l+7$38S-<1xX!NMc?Ltkr{y
zB<3=P@gaBMu*OD{U@nuGf5dv3Jy<3&V-tYUeaMN~8XNBj=5mR739wd~%Oz&I;j_D@
zd?}bC5_42yj!4W)EzH)~@X>7m(o%_e8EUOEFO`@p7$!_P4r^=_2<8fj`F7UJZ08Dz
z`3{C5KT`7Tc=JC-Y%CVccSy`X2G%O`9TIaT!}yRpaQt%bVO*A}L}{g9u9TSXM5~p#
zQev)Rm;iE`-PZe*UkT<aiFvuiTqQAAGfWscrR8h7G#fHE3+8Hxc?GamnX4t{l?>xU
z?!aN4DX$CWl@fCe>t*)fN{M+D!)Vs9J}dZ4Ft3uBYbEAY67yXQvlcm}$8YTWN5dKy
z(L-gVyCmkHpw?=QyCmj1hVdbntuaV2*GbIv5_6rzjExIMk8h1}g1JFr#skC{nHwbL
z)eKXJoKnhvhTz7Rq^A@S%&R5lMzmV3v07qY!!SPN#Al6-p9tnP67x@4FOTSjA7zci
zOun<T#>0Ynt;GB@*2~PiR${)JVThm78-wPbG_27gnD3UDe-5nG8h1;~_b`kPxonMp
z3g&wx=KqqI?~$1AWtaeRS~sjS<&<E)S7QE!#C)&Bd>_NiLQXQz*>>xrhBYqfges)_
zB<BA{t<@U$NzC^%j1M_6TVo?2nD3XEf6028J$S#wypCbwTVtGHUMDd>ATh6#m>*=A
zS;$Fdt2LGg<_9I_U$I_hnIDvx*E5U{IWb$UQ7@R+OU%D!z0Az(CFX}1CcZU(FPI;a
zn13TNKO`|f%rIf(B=g?CUzE#BI8k;9=7%Nb-=ftT8xKp&8yLoioS3cF_?KYbATj@r
z^)g#ygT(v@!^F2nQfD+GJt8sx9<^4PACZ_bF@OmpCz-9*=qs2Xm6#u6z05K{DltFK
zFh1nOY_&#6Fh4FaKf!vLnID&!pJbT$)|erfpOl#YATd8FF>hp;wa6)*zi(SVBQ{nD
z=8Y0FF2gZ)-Y79YWx?FG`^sJh^UnqIQxfx^EWL1|JS8zd%`iUXw2E5q=${bGPfN^y
zX1&aIep+IFhGAwQr<8H?iT;MnFAL^pB<5#<wMN}D67zEwjMW-%3+Cq}=D%2a;Y4{(
zVt$@se8^>MoD$5>OU!>|z0B5lUSfWMVP+wx)F=0eEW;W-y71Z;B<8=N!D@{cB<4*P
zjMW;K3+7D{Gaj$RFmIBWn;6E2T(-tY!Q3P<H?v-5YcxsBn;C{)ru0E+_D37fH>@#7
zFmINaw^*3}<{NRvW{G(#!-OF)(ft0#9H+s&OfYX{%tcGe%I7bN%mWO`2OYDDjelX`
zMbzQ1M_3zH#{oS?a4S$ngWw^I^}B)=)L8wsRg&-}3&!fNhXnIWlJ46qy>OzuBr$Ji
z7$0)kUw;$K+a=~5te4qe+a>0m3{!@j()@~S+(0|{iSm|U-YGG^420DhJ0<2<EEuab
zJ{QcdNX)w|y-1K(B<5Ec#)n+CMvqifBfTmy??$av=2s==Jq*)?oR~9jt0^+9@k7D9
zM`GT~dYSFKM`GT`Fh1lC93`bUnpTOKf_b0B{2J?JX5J?;|AS$OmSo=WhZ}Giq%kPf
z3+8`F%&()>YK?zL%x^G^4>|E!Wqw>RzacU2XT8iazacRnV3=yqc0j4$rpRGK<^zKH
zfW-VyiTQxUe2`;c3S$2C-KE&%lJt~L3Fd<m^P6b3TH~O^{1(F$5)o40mH%CDFkf^Y
zuYF5mej5!2^Yp@3mb@h~zr!(*nWn|Fhws7TF-_(y!TgS3HrBC2tQYy5(nJ1LxV6&G
z3Pi6%XtAz-@1n*@UwpH4;;MWMuAR*my$ECN^&V=BHS@D&v*19jS5)*O40@UV?U{eE
zUYaI2LDG6Pie7}VuC(u?#;_Rmc}KF?zZu2{GID9*9mnzvi#;Hi|1B(5GADYAKc9F$
zV7<(d`ESPDgdQV`ik6nljVvxNDlb_w|BjMy_{N;EW5d&x5%~PXsG3%oGZ_{07u^yL
zv(`l=%WzI;Q_D1TTUfG?K1ZY$b0@(#ySUieQaXQ0L{Nh7mJ*y;D0OxdkdMtPOkiF?
zGR$2ZUBrmS#&j1_lxdRZ>FwdLeVb`$$cWD>tty1Wg*kbmcbvw6U6Y_q&{;?5wr_(g
zpm}ZyH>BAEV@HY3Qkxh?2h5$#jA!m_5>jr|HH>Z2<=4$)i;y(5LFyWomMkJS7#`L=
zD76SNg!=OrEh#CFr=VuL_yB$2c+G~QiAZ#mu53Hd0n=<;xOk~Fu@W|m5p~Smg=Miu
zGkI2S)IA&9q^qKP))t{FtHrJj(lD?gWu7L$e4|e1GbE4KYTr|mUGA<!^ue^?k>n6i
zUHa0+%Sza~i0Pvl$6Oc77^h88iXo$AWfGyeE|xG(o0YI^@e&aPx_ON%oz0LwPNQaA
zsYy4Srn)^sA4%wGhtw?#K+%ulNUm4vj27ADW|Q=>jq&8S#pvT18rWcU9r%TZLL;C_
zp;zg2XuU#E#x@%AX^1%`x6Id8LfxO{N;9osjnixp3(R~oNGG<`#$k@vE>V{(Vw(Ug
z-8!#P6^B%6lo;n55S`Lg7l%`Bl}Jmm-&siU#@r>$Vy=us8>d;~oo@yi;+kvYFk5<w
zc8R(?p2+6PIK*+9CEodFkRh_UHV(6;mz~JBmQ-kSTA0|V(K+o}grK6ixMXe&l~EH*
zCAC<o<`{EIkQ+6zR8otHs*JwkUN}2)Ym8vARU?W<hKmA&uOBsXTzG_kWPb4oe@;%A
zZNg2^*pcNX)6inzl0}jE5w>Hc`6iU1j+Taa%<%wb{<6~fG21BKsxMy&0I~aSg7US~
z*mcHXvxUU)m6w#2&Ymmnl{Cpjb1WO%$g_2IQFLKsvG6O+e!frRPuIkXpj!;h({azi
vJ$Oa_$Z<L05myTLiORx)F*)IYrEc(;yn?aJ)fJZd0D248#~V)ApO5*!iYByD

literal 0
HcmV?d00001

diff --git a/bsnes/main.cpp b/bsnes/main.cpp
new file mode 100644
index 00000000..b01c7881
--- /dev/null
+++ b/bsnes/main.cpp
@@ -0,0 +1,97 @@
+/* bsnes
+   project started 10/14/2004
+   author byuu */
+
+#include "base.h"
+#include "main.h"
+#include "timing/timing.h"
+#include "cpu/g65816.h"
+extern snes_timer *snes_time;
+extern g65816 *gx816;
+extern ppustate ppu;
+
+vfunc RunSNES;
+
+void RunSNES_NoDebug(void) {
+byte l = 64;
+  while(l--) {
+    gx816->Run();
+    gx816->Run();
+    gx816->Run();
+    gx816->Run();
+    gx816->Run();
+    gx816->Run();
+    gx816->Run();
+    gx816->Run();
+  }
+}
+
+void RunSNES_Debug(void) {
+  if(debug_get_state() == DEBUGMODE_NOROM)return;
+
+  if(debug_get_state() == DEBUGMODE_RUN) {
+    gx816->Run();
+    if(debugger.trace_enabled == true) {
+      disas_g65816_op();
+    }
+  } else {
+    if(debugger.disas_op == true) {
+      disas_g65816_op();
+      debugger.disas_op = false;
+    }
+    if(debugger.refresh_mem == true) {
+      debug_refresh_mem();
+      debugger.refresh_mem = false;
+    }
+    if(debugger.refresh_bp == true) {
+      debug_refresh_bp();
+      debugger.refresh_bp = false;
+    }
+    if(debug_get_state() == DEBUGMODE_WAIT)return;
+
+    if(debug_get_state() == DEBUGMODE_STEP) {
+      gx816->Run();
+      disas_g65816_op();
+      debug_set_state(DEBUGMODE_WAIT);
+    }
+  }
+}
+
+void InitSNES(void) {
+  snes_time = new snes_timer();
+  gx816 = new g65816();
+  gx816->PowerOn(1);
+  if(*emu_state.rom_name == 0) {
+    debug_set_state(DEBUGMODE_NOROM);
+  } else {
+    gx816->LoadROM();
+  }
+
+  if(debug_get_state() == DEBUGMODE_DISABLED) {
+    RunSNES = RunSNES_NoDebug;
+  } else {
+    RunSNES = RunSNES_Debug;
+  }
+}
+
+#include <windows.h>
+int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
+char fn[MAX_PATH];
+  strcpy(fn, lpcmdline);
+//remove quotes from filename, if neccesary (if path contains spaces, quotes will be around command line arg)
+  if(*fn == '\"') {
+    strcpy(emu_state.rom_name, fn + 1);
+    emu_state.rom_name[strlen(emu_state.rom_name) - 1] = 0;
+  } else {
+    strcpy(emu_state.rom_name, fn);
+  }
+//create save ram file name
+  strcpy(emu_state.sram_name, emu_state.rom_name);
+  if(strlen(emu_state.sram_name) > 4) {
+    emu_state.sram_name[strlen(emu_state.sram_name) - 4] = 0;
+  }
+  strcat(emu_state.sram_name, ".srm");
+//located in win/gui.cpp
+  __winmain();
+  return 0;
+}
diff --git a/bsnes/main.h b/bsnes/main.h
new file mode 100644
index 00000000..21446257
--- /dev/null
+++ b/bsnes/main.h
@@ -0,0 +1,34 @@
+void __winmain(void);
+
+/*
+  *1 - how many instructions to execute before saving sram data
+       to emu_state.sram_name
+*/
+emustate emu_state = {
+  "", "", //rom name, sram name
+  1000000 //sram save tick count *1
+};
+
+debugstate debugger = {
+  DEBUGMODE_DISABLED, //default debug mode
+  false,              //trace enabled
+  0x7e0000,           //debugger memory start pos
+  true,               //debugger disassemble op
+  true,               //debugger refresh mem
+  true,               //debugger refresh breakpoints
+  0                   //tracelog file pointer
+};
+
+videostate render = {
+  512, 448,                        //resolution
+  256, 224,                        //snes internal resolution
+  false,                           //fullscreen
+  true,                            //show menu
+  1,                               //frame skip
+  0,                               //frame count
+  { true, true, true },            //bg1 enable
+  { true, true, true },            //bg2 enable
+  { true, true, true },            //bg3 enable
+  { true, true, true },            //bg4 enable
+  { true, true, true, true, true } //oam enable
+};
diff --git a/bsnes/main.obj b/bsnes/main.obj
new file mode 100644
index 0000000000000000000000000000000000000000..e04557fb60faf02d8cc6218513191e03c8ce5b33
GIT binary patch
literal 11653
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
Z!ijb@(bUo%jmFe)3x0CLfk;G!zXAShNMry2

literal 0
HcmV?d00001

diff --git a/bsnes/mem/memory.cpp b/bsnes/mem/memory.cpp
new file mode 100644
index 00000000..5d2072dc
--- /dev/null
+++ b/bsnes/mem/memory.cpp
@@ -0,0 +1,516 @@
+#include "../base.h"
+#include "../cpu/g65816.h"
+extern g65816 *gx816;
+extern emustate emu_state;
+extern debugstate debugger;
+
+void g65816::InitializeROM(byte memory_map) {
+  memset(rom, 0, 0x600000);
+  map = memory_map;
+}
+
+void g65816::InitializeWRAM(byte value) {
+  memset(wram, value, 0x020000);
+  memset(sram, 0x00,  0x0e0000);
+}
+
+/***********************
+ *** SNES Memory Map ***
+ **************************************************
+ *** 00-3f  0000-1fff  First 8k WRAM            ***
+ ***        2000-5fff  MMIO                     ***
+ ***        6000-7fff  Expansion RAM (Unmapped) ***
+ ***        8000-ffff  Cartridge ROM            ***
+ *** 40-7d  0000-ffff  Cartridge ROM            ***
+ *** 7e-7f  0000-ffff  128k WRAM                ***
+ *** 80-bf  0000-1fff  First 8k WRAM            ***
+ ***        2000-5fff  MMIO                     ***
+ ***        6000-7fff  Expansion RAM (Unmapped) ***
+ ***        8000-ffff  Cartridge ROM            ***
+ *** c0-ff  0000-ffff  Cartridge ROM            ***
+**************************************************/
+
+ulong g65816::mirror_offset(ulong addr) {
+byte db;
+word a;
+ulong r = 0;
+  db = (addr >> 16) & 0xff;
+  a  = (addr & 0xffff);
+  if(db >= 0x00 && db <= 0x3f) {
+    if(a >= 0x0000 && a <= 0x1fff) {
+      r = 0x7e0000 | (a & 0x1fff);
+    } else if(a >= 0x2000 && a <= 0x5fff) {
+      r = a;
+    } else if(a >= 0x6000 && a <= 0x7fff) {
+      r = (db << 16) | a;
+    } else if(a >= 0x8000 && a <= 0xffff) {
+      r = (db << 16) | a;
+    }
+  } else if(db >= 0x40 && db <= 0x7d) {
+      r = (db << 16) | a;
+  } else if(db >= 0x7e && db <= 0x7f) {
+    r = addr;
+  } else if(db >= 0x80 && db <= 0xbf) {
+    if(a >= 0x0000 && a <= 0x1fff) {
+      r = 0x7e0000 | (a & 0x1fff);
+    } else if(a >= 0x2000 && a <= 0x5fff) {
+      r = a;
+    } else if(a >= 0x6000 && a <= 0x7fff) {
+      r = (db << 16) | a;
+    } else if(a >= 0x8000 && a <= 0xffff) {
+      r = ((db & 0x7f) << 16) | a;
+    }
+  } else if(db >= 0xc0 && db <= 0xff) {
+    r = addr;
+  }
+
+  return r;
+}
+
+ulong g65816::convert_offset(byte read_mode, ulong addr, bool mirror) {
+byte db;
+  switch(read_mode) {
+  case MEMMODE_DP:
+    addr = (regs.d + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_DPX:
+    addr = (regs.d + regs.x + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_DPY:
+    addr = (regs.d + regs.y + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_IDP:
+    addr = (regs.d + (addr & 0xff)) & 0xffff;
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
+    addr |= (regs.db << 16);
+    break;
+  case MEMMODE_IDPX:
+    addr = (regs.d + regs.x + (addr & 0xff)) & 0xffff;
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
+    addr |= (regs.db << 16);
+    break;
+  case MEMMODE_IDPY:
+    addr = (regs.d + (addr & 0xff)) & 0xffff;
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
+    addr += (regs.db << 16) + regs.y;
+    if((addr >> 16) != regs.db)index_bank_crossed = true;
+    else                       index_bank_crossed = false;
+    break;
+  case MEMMODE_ILDP:
+    addr = (regs.d + (addr & 0xff));
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
+    break;
+  case MEMMODE_ILDPY:
+    addr = (regs.d + (addr & 0xff));
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
+    addr += regs.y;
+    break;
+  case MEMMODE_ADDR:
+    addr = addr & 0xffff;
+    addr |= (regs.db << 16);
+    break;
+  case MEMMODE_ADDR_PC:
+    addr = addr & 0xffff;
+    addr |= (regs.pc & 0xff0000);
+    break;
+  case MEMMODE_ADDRX:
+    addr = (regs.db << 16) + (addr & 0xffff);
+    addr += regs.x;
+    if((addr >> 16) != regs.db)index_bank_crossed = true;
+    else                       index_bank_crossed = false;
+    break;
+  case MEMMODE_ADDRY:
+    addr = (regs.db << 16) + (addr & 0xffff);
+    addr += regs.y;
+    if((addr >> 16) != regs.db)index_bank_crossed = true;
+    else                       index_bank_crossed = false;
+    break;
+  case MEMMODE_IADDRX:
+    addr += regs.x;
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, (addr & 0x00ffff));
+    addr |= (regs.pc & 0xff0000);
+    break;
+  case MEMMODE_ILADDR:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
+    break;
+  case MEMMODE_IADDR_PC:
+    addr |= (regs.pc & 0xff0000);
+    break;
+  case MEMMODE_IADDRX_PC:
+    addr += regs.x;
+    addr |= (regs.pc & 0xff0000);
+    break;
+  case MEMMODE_ILADDR_PC:
+    break;
+  case MEMMODE_LONG:
+    break;
+  case MEMMODE_LONGX:
+    addr += regs.x;
+    break;
+  case MEMMODE_SR:
+    addr = (regs.s + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_ISRY:
+    addr = (regs.s + (addr & 0xff)) & 0xffff;
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
+    addr += (regs.db << 16) + regs.y;
+    break;
+  }
+
+  if(mirror == true) {
+    return mirror_offset(addr);
+  } else {
+    return addr;
+  }
+}
+
+ulong g65816::adjust_base_offset(byte read_mode, ulong addr) {
+byte db;
+  switch(read_mode) {
+  case MEMMODE_DP:
+    addr = (regs.d + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_DPX:
+    addr = (regs.d + regs.x + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_DPY:
+    addr = (regs.d + regs.y + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_IDP:
+    addr = (regs.d + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_IDPX:
+    addr = (regs.d + regs.x + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_IDPY:
+    addr = (regs.d + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_ILDP:
+    addr = (regs.d + (addr & 0xff));
+    break;
+  case MEMMODE_ILDPY:
+    addr = (regs.d + (addr & 0xff));
+    break;
+  case MEMMODE_ADDR:
+    addr = addr & 0xffff;
+    addr |= (regs.db << 16);
+    break;
+  case MEMMODE_ADDR_PC:
+    addr = addr & 0xffff;
+    addr |= (regs.pc & 0xff0000);
+    break;
+  case MEMMODE_ADDRX:
+    addr = (regs.db << 16) | (addr & 0xffff);
+    addr += regs.x;
+    if((addr >> 16) != regs.db)index_bank_crossed = true;
+    else                       index_bank_crossed = false;
+    break;
+  case MEMMODE_ADDRY:
+    addr = (regs.db << 16) + (addr & 0xffff);
+    addr += regs.y;
+    if((addr >> 16) != regs.db)index_bank_crossed = true;
+    else                       index_bank_crossed = false;
+    break;
+  case MEMMODE_IADDRX:
+    addr += regs.x;
+    addr &= 0xffff;
+    break;
+  case MEMMODE_ILADDR:
+    addr &= 0xffff;
+    break;
+  case MEMMODE_IADDR_PC:
+    addr |= (regs.pc & 0xff0000);
+    break;
+  case MEMMODE_IADDRX_PC:
+    addr += regs.x;
+    addr |= (regs.pc & 0xff0000);
+    break;
+  case MEMMODE_ILADDR_PC:
+    break;
+  case MEMMODE_LONG:
+    break;
+  case MEMMODE_LONGX:
+    addr += regs.x;
+    break;
+  case MEMMODE_SR:
+    addr = (regs.s + (addr & 0xff)) & 0xffff;
+    break;
+  case MEMMODE_ISRY:
+    addr = (regs.s + (addr & 0xff)) & 0xffff;
+    break;
+  }
+  return addr;
+}
+
+ulong g65816::read_indirect_address(byte read_mode, ulong addr) {
+byte db;
+  switch(read_mode) {
+  case MEMMODE_IDP:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
+    addr |= (regs.db << 16);
+    break;
+  case MEMMODE_IDPX:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
+    addr |= (regs.db << 16);
+    break;
+  case MEMMODE_IDPY:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
+    addr += (regs.db << 16) + regs.y;
+    if((addr >> 16) != regs.db)index_bank_crossed = true;
+    else                       index_bank_crossed = false;
+    break;
+  case MEMMODE_ILDP:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
+    break;
+  case MEMMODE_ILDPY:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
+    addr += regs.y;
+    break;
+  case MEMMODE_IADDRX:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, (addr & 0x00ffff));
+    addr |= (regs.pc & 0xff0000);
+    break;
+  case MEMMODE_ILADDR:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
+    break;
+  case MEMMODE_ISRY:
+    addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
+    addr += (regs.db << 16) + regs.y;
+    break;
+  default:
+    dprintf("* Error: Invalid read_mode for g65816::read_indirect_address [%d]", read_mode);
+    break;
+  }
+  return addr;
+}
+
+ulong g65816::get_dc(byte read_mode, ulong addr) {
+  regs.dc = convert_offset(read_mode, addr, false);
+  return regs.dc;
+}
+
+byte g65816::mem_getbyte_direct(ulong addr, byte access_mode) {
+byte db;
+word a;
+  db = (addr >> 16) & 0xff;
+  a  = (addr & 0xffff);
+  if(db == 0x00 && a >= 0x2000 && a <= 0x5fff) {
+    return mmio_read(addr);
+  }
+
+  if(db == 0x7e || db == 0x7f) {
+    return wram[addr & 0x01ffff];
+  } else if(db != 0x7e && db != 0x7f && a >= 0x8000 && a <= 0xffff) {
+    return rom_read(addr, MEMSIZE_BYTE);
+  } else if(db >= 0x30 && db <= 0x3f) {
+    if(a >= 0x6000 && a <= 0x7fff) {
+      addr = ((db - 0x30) * 0x2000) + (a - 0x6000);
+      addr &= (sram_size - 1);
+      return sram[addr];
+    }
+  } else if(db >= 0x70 && db <= 0x7d) {
+    addr -= 0x700000;
+    addr &= (sram_size - 1);
+    return sram[addr];
+  } else if(db >= 0xc0 && db <= 0xff) {
+    return rom_read(addr, MEMSIZE_BYTE);
+  }
+  return 0;
+}
+
+byte g65816::mem_getbyte(ulong addr, byte access_mode) {
+int i;
+byte r;
+  r = mem_getbyte_direct(addr, access_mode);
+
+  if(debug_get_state() == DEBUGMODE_DISABLED)return r;
+
+  if(access_mode == MEMACCESS_DEBUGGER)return r; //don't report breakpoint hits from debugger
+
+  for(i=0;i<16;i++) {
+    if(bp_list[i].flags & BP_READ) {
+      if(bp_list[i].offset == addr) {
+        if(bp_list[i].flags & BP_VAL) {
+          if(bp_list[i].value == r) {
+            dprintf("* breakpoint %d hit -- read match access [%0.2x]", i, r);
+            bp_list[i].hit_count++;
+            debugger.refresh_bp = true;
+            debug_set_state(DEBUGMODE_WAIT);
+            disas_g65816_op();
+          }
+        } else {
+          dprintf("* breakpoint %d hit -- read access", i);
+          bp_list[i].hit_count++;
+          debugger.refresh_bp = true;
+          debug_set_state(DEBUGMODE_WAIT);
+          disas_g65816_op();
+        }
+      }
+    }
+  }
+  return r;
+}
+
+void g65816::mem_putbyte_direct(ulong addr, byte value, byte access_mode) {
+byte db;
+word a;
+  db = (addr >> 16) & 0xff;
+  a  = (addr & 0xffff);
+  if(db == 0x00 && a >= 0x2000 && a <= 0x5fff) {
+    mmio_write(a, value);
+  } else if(db == 0x7e || db == 0x7f) {
+    wram[addr & 0x01ffff] = value;
+  } else if(db >= 0x30 && db <= 0x3f) {
+    if(a >= 0x6000 && a <= 0x7fff) {
+      addr = ((db - 0x30) * 0x2000) + (a - 0x6000);
+      addr &= (sram_size - 1);
+      sram[addr] = value;
+    }
+  } else if(db >= 0x70 && db <= 0x7d) {
+    addr -= 0x700000;
+    addr &= (sram_size - 1);
+    sram[addr] = value;
+  }
+
+  if(access_mode == MEMACCESS_DEBUGGER) {
+    if(gx816->map == MEMMAP_LOROM) {
+      if((db >= 0x00 && db <= 0x5f) || (db >= 0x80 && db <= 0xdf)) {
+        if(addr >= 0x8000 && addr <= 0xffff) {
+          rom_write(addr, value, MEMSIZE_BYTE);
+        }
+      }
+    } else if(gx816->map == MEMMAP_HIROM) {
+      if(db >= 0xc0 && db <= 0xff) {
+        rom_write(addr, value, MEMSIZE_BYTE);
+      }
+    }
+  }
+}
+
+void g65816::mem_putbyte(ulong addr, byte value, byte access_mode) {
+int i;
+  mem_putbyte_direct(addr, value, access_mode);
+
+  if(debug_get_state() == DEBUGMODE_DISABLED)return;
+
+  if(access_mode == MEMACCESS_DEBUGGER)return; //don't report breakpoint hits from debugger
+
+  for(i=0;i<16;i++) {
+    if(bp_list[i].flags & BP_WRITE) {
+      if(bp_list[i].offset == addr) {
+        if(bp_list[i].flags & BP_VAL) {
+          if(bp_list[i].value == value) {
+            dprintf("* breakpoint %d hit -- write match access [%0.2x]", i, value);
+            bp_list[i].hit_count++;
+            debugger.refresh_bp = true;
+            debug_set_state(DEBUGMODE_WAIT);
+            disas_g65816_op();
+          }
+        } else {
+          dprintf("* breakpoint %d hit -- write access", i);
+          bp_list[i].hit_count++;
+          debugger.refresh_bp = true;
+          debug_set_state(DEBUGMODE_WAIT);
+          disas_g65816_op();
+        }
+      }
+    }
+  }
+}
+
+ulong g65816::mem_read(byte read_mode, byte read_size, ulong addr, byte access_mode) {
+ulong r;
+  addr = convert_offset(read_mode, addr);
+
+  switch(read_size) {
+  case MEMSIZE_BYTE:
+    r = mem_getbyte(addr,     access_mode);
+    break;
+  case MEMSIZE_WORD:
+    r = mem_getbyte(addr,     access_mode) |
+        mem_getbyte(addr + 1, access_mode)<<8;
+    break;
+  case MEMSIZE_LONG:
+    r = mem_getbyte(addr,     access_mode) |
+        mem_getbyte(addr + 1, access_mode)<<8 |
+        mem_getbyte(addr + 2, access_mode)<<16;
+    break;
+  }
+
+  return r;
+}
+
+void g65816::mem_write(byte write_mode, byte write_size, ulong addr, ulong value, byte access_mode) {
+  addr = convert_offset(write_mode, addr);
+
+  switch(write_size) {
+  case MEMSIZE_BYTE:
+    mem_putbyte(addr,   value,     access_mode);
+    break;
+  case MEMSIZE_WORD:
+    mem_putbyte(addr,   value,     access_mode);
+    mem_putbyte(addr+1, value>>8,  access_mode);
+    break;
+  case MEMSIZE_LONG:
+    mem_putbyte(addr,   value,     access_mode);
+    mem_putbyte(addr+1, value>>8,  access_mode);
+    mem_putbyte(addr+2, value>>16, access_mode);
+    break;
+  }
+
+  debugger.refresh_mem = true;
+}
+
+ulong g65816::rom_read(ulong addr, byte read_size) {
+ulong r;
+  if(map == MEMMAP_LOROM) {
+    if(read_size == MEMSIZE_BYTE) {
+      r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)];
+    } else if(read_size == MEMSIZE_WORD) {
+      r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] |
+          rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] << 8;
+    } else if(read_size == MEMSIZE_LONG) {
+      r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] |
+          rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] << 8 |
+          rom[(((addr + 2) & 0x7f0000) >> 1) | ((addr + 2) & 0x7fff)] << 16;
+    }
+  } else if(map == MEMMAP_HIROM) {
+    if(read_size == MEMSIZE_BYTE) {
+      r = rom[addr & 0x3fffff];
+    } else if(read_size == MEMSIZE_WORD) {
+      r = rom[addr & 0x3fffff] |
+          rom[(addr + 1) & 0x3fffff] << 8;
+    } else if(read_size == MEMSIZE_LONG) {
+      r = rom[addr & 0x3fffff] |
+          rom[(addr + 1) & 0x3fffff] << 8 |
+          rom[(addr + 2) & 0x3fffff] << 16;
+    }
+  }
+  return r;
+}
+
+void g65816::rom_write(ulong addr, ulong v, byte write_size) {
+  if(map == MEMMAP_LOROM) {
+    if(write_size == MEMSIZE_BYTE) {
+      rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
+    } else if(write_size == MEMSIZE_WORD) {
+      rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
+      rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] = v >> 8;
+    } else if(write_size == MEMSIZE_LONG) {
+      rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
+      rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] = v >> 8;
+      rom[(((addr + 2) & 0x7f0000) >> 1) | ((addr + 2) & 0x7fff)] = v >> 16;
+    }
+  } else if(map == MEMMAP_HIROM) {
+    if(write_size == MEMSIZE_BYTE) {
+      rom[addr & 0x3fffff] = v;
+    } else if(write_size == MEMSIZE_WORD) {
+      rom[addr & 0x3fffff] = v;
+      rom[(addr + 1) & 0x3fffff] = v >> 8;
+    } else if(write_size == MEMSIZE_LONG) {
+      rom[addr & 0x3fffff] = v;
+      rom[(addr + 1) & 0x3fffff] = v >> 8;
+      rom[(addr + 2) & 0x3fffff] = v >> 16;
+    }
+  }
+}
diff --git a/bsnes/memory.obj b/bsnes/memory.obj
new file mode 100644
index 0000000000000000000000000000000000000000..ca0afd4a5a1f84a4d8c01fb8254184649984b321
GIT binary patch
literal 11196
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

literal 0
HcmV?d00001

diff --git a/bsnes/misc/libstr.cpp b/bsnes/misc/libstr.cpp
new file mode 100644
index 00000000..a9ba0b40
--- /dev/null
+++ b/bsnes/misc/libstr.cpp
@@ -0,0 +1,393 @@
+#include "../base.h"
+#include "libvlist.cpp"
+
+typedef struct {
+char *s;
+ulong size;
+}string;
+
+typedef struct {
+vectorlist list;
+ulong count;
+}stringlist;
+
+/***********************
+string library functions
+***********************/
+
+void strresize(string *str, ulong size) {
+char *t;
+int sl;
+  if(str->size == size)return;
+  sl = strlen(str->s);
+  t = (char*)malloc(size + 1);
+  strncpy(t, str->s, size);
+  free(str->s);
+  str->s = t;
+  str->size = size;
+}
+
+string *newstr(void) {
+string *s;
+  s = (string*)malloc(sizeof(string));
+  s->size = 16;
+  s->s = (char*)malloc(s->size + 1);
+  *s->s = 0;
+  return s;
+}
+
+void memfree(string *s) {
+  if(s->s)free(s->s);
+  free(s);
+}
+
+/***************************
+stringlist library functions
+***************************/
+
+void stradd(stringlist *sl, ulong num) {
+int i;
+string *s;
+  while(sl->count < (num + 1)) {
+    s = newstr();
+    sl->list.add((ulong)s);
+    sl->count++;
+  }
+}
+
+string *strget(stringlist *sl, ulong num) {
+string *s;
+  if(sl->count < (num + 1)) { stradd(sl, num); }
+  s = (string*)sl->list.get(num);
+  return s;
+}
+
+stringlist *newstrlist(void) {
+stringlist *sl;
+  sl = (stringlist*)malloc(sizeof(stringlist));
+  sl->count = 0;
+  stradd(sl, 1);
+  return sl;
+}
+
+ulong count(stringlist *sl) {
+  return sl->count;
+}
+
+/****************************
+string manipulation functions
+****************************/
+
+char *strptr(string *s) { return s->s; }
+char *strptr(stringlist *sl, ulong num) { return strget(sl, num)->s; }
+
+void strcpy(string *dest, char *src) {
+int srclen = strlen(src);
+  if(srclen > dest->size) { strresize(dest, srclen); }
+  strncpy(dest->s, src, dest->size);
+}
+void strcpy(string *dest, string *src) { strcpy(dest, src->s); }
+void strcpy(stringlist *dest, ulong num, char *src) { strcpy(strget(dest, num), src); }
+void strcpy(stringlist *dest, ulong num, string *src) { strcpy(strget(dest, num), src->s); }
+void strcpy(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { strcpy(strget(dest, destnum), strptr(src, srcnum)); }
+
+void strset(string *dest, ulong pos, byte c) {
+char *s;
+  if(pos > dest->size) { strresize(dest, pos); }
+  dest->s[pos] = c;
+}
+void strset(stringlist *dest, ulong num, ulong pos, byte c) { strset(strget(dest, num), pos, c); }
+
+void strcat(string *dest, char *src) {
+int srclen, destlen;
+  srclen  = strlen(src);
+  destlen = strlen(dest->s);
+  if(srclen + destlen > dest->size) { strresize(dest, srclen + destlen); }
+  strncat(dest->s, src, srclen + destlen);
+}
+void strcat(string *dest, string *src) { strcat(dest, src->s); }
+void strcat(stringlist *dest, ulong num, char *src) { strcat(strget(dest, num), src); }
+void strcat(stringlist *dest, ulong num, string *src) { strcat(strget(dest, num), src->s); }
+void strcat(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { strcat(strget(dest, destnum), strptr(src, srcnum)); }
+
+ulong strlen(string *s) { return strlen(s->s); }
+ulong strlen(stringlist *sl, ulong num) { return strlen(strget(sl, num)->s); }
+
+void strinsert(string *dest, char *src, ulong pos) {
+string *s = newstr();
+  strcpy(s, strptr(dest)+pos);
+  strset(dest, pos, 0);
+  strcat(dest, src);
+  strcat(dest, s);
+  memfree(s);
+}
+void strinsert(string *dest, string *src, ulong pos) { strinsert(dest, src->s, pos); }
+void strinsert(stringlist *dest, ulong num, char *src, ulong pos) { strinsert(strget(dest, num), src, pos); }
+void strinsert(stringlist *dest, ulong num, string *src, ulong pos) { strinsert(strget(dest, num), src->s, pos); }
+void strinsert(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum, ulong pos) { strinsert(strget(dest, destnum), strptr(src, srcnum), pos); }
+
+void strremove(string *dest, ulong start, ulong length = 0) {
+int destlen;
+char *s;
+int i, sl = strlen(dest->s);
+  if(start > dest->size) { strresize(dest, start); }
+  if(!length) {
+    strset(dest, start, 0);
+    return;
+  }
+  s = strptr(dest);
+  for(i=start;i<sl;i++) { s[i] = s[i+length]; }
+  s[i] = 0;
+}
+void strremove(stringlist *sl, ulong num, ulong start, ulong length = 0) { strremove(strget(sl, num), start, length); }
+
+ulong strcmp(string *dest, char *src) { return strcmp(dest->s, src); }
+ulong strcmp(string *dest, string *src) { return strcmp(dest->s, src->s); }
+ulong strcmp(stringlist *dest, ulong num, char *src) { return strcmp(strget(dest, num)->s, src); }
+ulong strcmp(stringlist *dest, ulong num, string *src) { return strcmp(strget(dest, num)->s, src->s); }
+ulong strcmp(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strcmp(strget(dest, destnum)->s, strptr(src, srcnum)); }
+
+ulong stricmp(char *dest, char *src) {
+int i, sl = strlen(dest);
+  if(sl != strlen(src))return 1;
+  for(i=0;i<sl;i++) {
+    if(dest[i] >= 'A' && dest[i] <= 'Z') {
+      if(dest[i]!=src[i] && dest[i]+0x20!=src[i])return 1;
+    } else if(dest[i] >='a' && dest[i] <= 'z') {
+      if(dest[i]!=src[i] && dest[i]-0x20!=src[i])return 1;
+    } else {
+      if(dest[i] != src[i])return 1;
+    }
+  }
+  return 0;
+}
+ulong stricmp(string *dest, char *src) { return stricmp(dest->s, src); }
+ulong stricmp(string *dest, string *src) { return stricmp(dest->s, src->s); }
+ulong stricmp(stringlist *dest, ulong num, char *src) { return stricmp(strget(dest, num)->s, src); }
+ulong stricmp(stringlist *dest, ulong num, string *src) { return stricmp(strget(dest, num)->s, src->s); }
+ulong stricmp(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return stricmp(strget(dest, destnum)->s, strptr(src, srcnum)); }
+
+void strlower(char *str) {
+int i, sl = strlen(str);
+  for(i=0;i<sl;i++) { if(str[i] >= 'A' && str[i] <= 'Z')str[i] += 0x20; }
+}
+void strlower(string *str) { strlower(str->s); }
+void strlower(stringlist *sl, ulong num) { strlower(strptr(sl, num)); }
+
+void strupper(char *str) {
+int i, sl = strlen(str);
+  for(i=0;i<sl;i++) { if(str[i] >='a' && str[i] <='z')str[i] -= 0x20; }
+}
+void strupper(string *str) { strupper(str->s); }
+void strupper(stringlist *sl, ulong num) { strupper(strptr(sl, num)); }
+
+ulong strpos(char *str, char *key) {
+int i, ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return null;
+  for(i=0;i<=ssl-ksl;i++) {
+    if(!memcmp(str+i, key, ksl))return i;
+  }
+  return null;
+}
+ulong strpos(string *dest, char *src) { return strpos(dest->s, src); }
+ulong strpos(string *dest, string *src) { return strpos(dest->s, src->s); }
+ulong strpos(stringlist *dest, ulong num, char *src) { return strpos(strget(dest, num)->s, src); }
+ulong strpos(stringlist *dest, ulong num, string *src) { return strpos(strget(dest, num)->s, src->s); }
+ulong strpos(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strpos(strget(dest, destnum)->s, strptr(src, srcnum)); }
+
+ulong strpos_q(char *str, char *key) {
+int i, z, ssl = strlen(str), ksl = strlen(key);
+byte x;
+  if(ksl > ssl)return null;
+  for(i=0;i<=ssl-ksl;) {
+    x = str[i];
+    if(x == '\"' || x == '\'') {
+      z = i++;
+      while(str[i] != x && i < ssl)i++;
+      if(i >= ssl)i = z;
+    }
+    if(!memcmp(str+i, key, ksl)) {
+      return i;
+    } else {
+      i++;
+    }
+  }
+  return null;
+}
+ulong strpos_q(string *dest, char *src) { return strpos_q(dest->s, src); }
+ulong strpos_q(string *dest, string *src) { return strpos_q(dest->s, src->s); }
+ulong strpos_q(stringlist *dest, ulong num, char *src) { return strpos_q(strget(dest, num)->s, src); }
+ulong strpos_q(stringlist *dest, ulong num, string *src) { return strpos_q(strget(dest, num)->s, src->s); }
+ulong strpos_q(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strpos_q(strget(dest, destnum)->s, strptr(src, srcnum)); }
+
+void strtr(char *dest, char *before, char *after) {
+int i, l, sl = strlen(dest), bsl = strlen(before), asl = strlen(after);
+  if((bsl != asl) || bsl == 0)return;
+  for(i=0;i<sl;i++) {
+    for(l=0;l<bsl;l++) {
+      if(dest[i] == before[l])dest[i] = after[l];
+    }
+  }
+}
+void strtr(string *dest, char *before, char *after) { strtr(dest->s, before, after); }
+void strtr(stringlist *dest, ulong num, char *before, char *after) { strtr(strptr(dest, num), before, after); }
+
+ulong strbegin(char *str, char *key) {
+int i, ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return 1;
+  if(!memcmp(str, key, ksl))return 0;
+  return 1;
+}
+ulong strbegin(string *str, char *key) { return strbegin(str->s, key); }
+ulong strbegin(stringlist *str, ulong num, char *key) { return strbegin(strptr(str, num), key); }
+
+ulong stribegin(char *str, char *key) {
+int i, ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return 1;
+  for(i=0;i<ksl;i++) {
+    if(str[i] >= 'A' && str[i] <= 'Z') {
+      if(str[i] != key[i] && str[i]+0x20 != key[i])return 1;
+    } else if(str[i] >= 'a' && str[i] <= 'z') {
+      if(str[i] != key[i] && str[i]-0x20 != key[i])return 1;
+    } else {
+      if(str[i] != key[i])return 1;
+    }
+  }
+  return 0;
+}
+ulong stribegin(string *str, char *key) { return stribegin(str->s, key); }
+ulong stribegin(stringlist *str, ulong num, char *key) { return stribegin(strptr(str, num), key); }
+
+ulong strend(char *str, char *key) {
+int i, ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return 1;
+  if(!memcmp(str + ssl - ksl, key, ksl))return 0;
+  return 1;
+}
+ulong strend(string *str, char *key) { return strend(str->s, key); }
+ulong strend(stringlist *str, ulong num, char *key) { return strend(strptr(str, num), key); }
+
+ulong striend(char *str, char *key) {
+int i, z, ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return 1;
+  for(i=ssl-ksl, z=0;i<ssl;i++, z++) {
+    if(str[i] >= 'A' && str[i] <= 'Z') {
+      if(str[i] != key[z] && str[i]+0x20 != key[z])return 1;
+    } else if(str[i] >= 'a' && str[i] <= 'z') {
+      if(str[i] != key[z] && str[i]-0x20 != key[z])return 1;
+    } else {
+      if(str[i] != key[z])return 1;
+    }
+  }
+  return 0;
+}
+ulong striend(string *str, char *key) { return striend(str->s, key); }
+ulong striend(stringlist *str, ulong num, char *key) { return striend(strptr(str, num), key); }
+
+void strltrim(char *str, char *key) {
+int i, ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return;
+  if(!strbegin(str, key)) {
+    for(i=0;i<ssl-ksl;i++)str[i] = str[i + ksl];
+    str[i] = 0;
+  }
+}
+void strltrim(string *str, char *key) { strltrim(str->s, key); }
+void strltrim(stringlist *str, ulong num, char *key) { strltrim(strptr(str, num), key); }
+
+void striltrim(char *str, char *key) {
+int i, ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return;
+  if(!stribegin(str, key)) {
+    for(i=0;i<ssl-ksl;i++)str[i] = str[i + ksl];
+    str[i] = 0;
+  }
+}
+void striltrim(string *str, char *key) { striltrim(str->s, key); }
+void striltrim(stringlist *str, ulong num, char *key) { striltrim(strptr(str, num), key); }
+
+void strrtrim(char *str, char *key) {
+int ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return;
+  if(!strend(str, key)) {
+    str[ssl - ksl] = 0;
+  }
+}
+void strrtrim(string *str, char *key) { strrtrim(str->s, key); }
+void strrtrim(stringlist *str, ulong num, char *key) { strrtrim(strptr(str, num), key); }
+
+void strirtrim(char *str, char *key) {
+int ssl = strlen(str), ksl = strlen(key);
+  if(ksl > ssl)return;
+  if(!striend(str, key)) {
+    str[ssl - ksl] = 0;
+  }
+}
+void strirtrim(string *str, char *key) { strirtrim(str->s, key); }
+void strirtrim(stringlist *str, ulong num, char *key) { strirtrim(strptr(str, num), key); }
+
+ulong strhex(char *str) {
+ulong r = 0, m = 0;
+int i, ssl = strlen(str);
+byte x;
+  for(i=0;i<ssl;i++) {
+    if(str[i] >= '0' && str[i] <= '9');
+    else if(str[i] >= 'A' && str[i] <= 'F');
+    else if(str[i] >= 'a' && str[i] <= 'f');
+    else break;
+  }
+  for(--i;i>=0;i--, m+=4) {
+    x = str[i];
+    if(x >= '0' && x <= '9')x -= '0';
+    else if(x >= 'A' && x <= 'F')x -= 'A' - 0x0a;
+    else if(x >= 'a' && x <= 'f')x -= 'a' - 0x0a;
+    else return r;
+    r |= x << m;
+  }
+  return r;
+}
+ulong strhex(string *str) { return strhex(str->s); }
+ulong strhex(stringlist *str, ulong num) { return strhex(strptr(str, num)); }
+
+ulong strdec(char *str) {
+ulong r = 0, m = 1;
+int i, ssl = strlen(str);
+byte x;
+  for(i=0;i<ssl;i++) {
+    if(str[i] >= '0' && str[i] <= '9');
+    else break;
+  }
+  for(--i;i>=0;i--, m*=10) {
+    x = str[i];
+    if(x >= '0' && x <= '9')x -= '0';
+    else return r;
+    r += x * m;
+  }
+  return r;
+}
+ulong strdec(string *str) { return strdec(str->s); }
+ulong strdec(stringlist *str, ulong num) { return strdec(strptr(str, num)); }
+
+ulong strbin(char *str) {
+ulong r = 0, m = 0;
+int i, ssl = strlen(str);
+byte x;
+  for(i=0;i<ssl;i++) {
+    if(str[i] == '0' || str[i] == '1');
+    else break;
+  }
+  for(--i;i>=0;i--, m++) {
+    x = str[i];
+    if(str[i] == '0' || str[i] == '1')x -= '0';
+    else return r;
+    r |= x << m;
+  }
+  return r;
+}
+ulong strbin(string *str) { return strbin(str->s); }
+ulong strbin(stringlist *str, ulong num) { return strbin(strptr(str, num)); }
+
+#include "libstr_math.cpp"
+#include "libstr_split.cpp"
+#include "libstr_replace.cpp"
+#include "libstr_sprintf.cpp"
diff --git a/bsnes/misc/libstr_math.cpp b/bsnes/misc/libstr_math.cpp
new file mode 100644
index 00000000..7bfedea5
--- /dev/null
+++ b/bsnes/misc/libstr_math.cpp
@@ -0,0 +1,181 @@
+#define STRMATH_ADD  1
+#define STRMATH_SUB  2
+#define STRMATH_MUL  3
+#define STRMATH_DIV  4
+#define STRMATH_MOD  5
+#define STRMATH_AND  6
+#define STRMATH_OR   7
+#define STRMATH_XOR  8
+#define STRMATH_SHL  9
+#define STRMATH_SHR 10
+
+#define STRMATH_LINKED 64
+
+#define STRMATHMODE_NEG 1
+#define STRMATHMODE_NOT 2
+
+#define __strunktonum()                                         \
+  if     (s1[0] == '0' && s1[1] == 'x')r = strhex(s1 + 2); \
+  else if(s1[0] == '0' && s1[1] == 'b')r = strbin(s1 + 2); \
+  else r = strdec(s1)
+
+#define __strmath_setmode()                       \
+  if     (str[i] == '-') { mode = STRMATHMODE_NEG; i++; } \
+  else if(str[i] == '~') { mode = STRMATHMODE_NOT; i++; } \
+  else if(str[i] == '+') {                         i++; } \
+  else mode=0
+
+#define __strmath_modeset()            \
+  if     (mode == STRMATHMODE_NEG)r *= -1; \
+  else if(mode == STRMATHMODE_NOT)r =~ r
+
+#define __strmath_set(__x)     \
+  s1[z] = 0;                   \
+  z = 0;                       \
+  __strunktonum();             \
+  __strmath_modeset();         \
+  array[array_size++] = r;     \
+  array_gate[array_size] = __x
+
+/***************************************
+strmath(str)
+  resolves all math entities from within
+  str, and returns numerical result
+  example: strmath("5+5")=10
+***************************************/
+ulong p_strmath(char *str) {
+int i = 0, ssl = strlen(str);
+byte x, mode = 0;
+ulong r, array[128], array_size = 0, z = 0;
+byte  array_gate[128];
+char *s1;
+  if(!ssl)return 0;
+  s1 = (char*)malloc(ssl + 1);
+  __strmath_setmode();
+  while(i < ssl) {
+    x = str[i++];
+    if     (x == '+') { __strmath_set(STRMATH_ADD); __strmath_setmode(); }
+    else if(x == '-') { __strmath_set(STRMATH_SUB); __strmath_setmode(); }
+    else if(x == '*') { __strmath_set(STRMATH_MUL); __strmath_setmode(); }
+    else if(x == '/') { __strmath_set(STRMATH_DIV); __strmath_setmode(); }
+    else if(x == '%') { __strmath_set(STRMATH_MOD); __strmath_setmode(); }
+    else if(x == '&') { __strmath_set(STRMATH_AND); __strmath_setmode(); }
+    else if(x == '|') { __strmath_set(STRMATH_OR ); __strmath_setmode(); }
+    else if(x == '^') { __strmath_set(STRMATH_XOR); __strmath_setmode(); }
+    else if(x == '<' && str[i] == '<') { __strmath_set(STRMATH_SHL); i++; __strmath_setmode(); }
+    else if(x == '>' && str[i] == '>') { __strmath_set(STRMATH_SHR); i++; __strmath_setmode(); }
+    else s1[z++] = x;
+  }
+  s1[z] = 0;
+  __strunktonum();
+  __strmath_modeset();
+  array[array_size++] = r;
+  free(s1);
+
+  for(i=1;i<array_size;i++) {
+    if     (array_gate[i] == STRMATH_SHL) { array[i-1] <<= array[i]; array_gate[i] = STRMATH_LINKED; }
+    else if(array_gate[i] == STRMATH_SHR) { array[i-1] >>= array[i]; array_gate[i] = STRMATH_LINKED; }
+  }
+
+  for(i=1;i<array_size;i++) {
+    if     (array_gate[i] == STRMATH_MUL) { array[i-1] *= array[i]; array_gate[i] = STRMATH_LINKED; }
+    else if(array_gate[i] == STRMATH_DIV) { array[i-1] /= array[i]; array_gate[i] = STRMATH_LINKED; }
+  }
+
+  r = array[0];
+  for(i=1;i<array_size;i++) {
+    if     (array_gate[i] == STRMATH_ADD)r += array[i];
+    else if(array_gate[i] == STRMATH_SUB)r -= array[i];
+    else if(array_gate[i] == STRMATH_MOD)r %= array[i];
+    else if(array_gate[i] == STRMATH_AND)r &= array[i];
+    else if(array_gate[i] == STRMATH_OR )r |= array[i];
+    else if(array_gate[i] == STRMATH_XOR)r ^= array[i];
+  }
+
+  return r;
+}
+
+ulong strmath(char *in_str) {
+ulong r = 0;
+ulong pdepth = 0, cpdepth, maxpdepth = 0;
+ulong pstart, pend, spos;
+int i, sc, sl = strlen(in_str);
+char *str = (char*)malloc(sl + 1), *str0;
+char *pstr;
+char num[64];
+  strcpy(str, in_str);
+
+  for(i=0;i<sl;i++) {
+    if(str[i]=='(') {
+      pdepth++;
+      if(pdepth > maxpdepth)maxpdepth = pdepth;
+    } else if(str[i]==')') {
+      if(pdepth == 0) {
+        free(str);
+        return null; //error! too many )'s
+      }
+      pdepth --;
+    }
+  }
+
+  if(pdepth != 0) {
+    free(str);
+    return null; //error! unequal ('s to )'s
+  }
+
+  pdepth = maxpdepth;
+  while(pdepth) {
+    cpdepth = 0;
+    for(i=0;i<sl;) {
+      if(str[i] == '(')cpdepth++;
+      if(str[i] == ')')cpdepth--;
+      i++;
+      if(cpdepth == pdepth) {
+        pstart = i;
+        while(str[i] != ')')i++;
+        pend = i;
+
+        pstr = (char*)malloc(pend-pstart+1);
+        memcpy(pstr, str+pstart, pend-pstart);
+        pstr[pend-pstart]=0;
+        r = p_strmath(pstr);
+        free(pstr);
+        sprintf(num, "%d", r);
+        str0 = (char*)malloc(sl + strlen(num) + 1);
+        memcpy(str0, str, pstart - 1);
+        spos = pstart - 1;
+        memcpy(str0+spos, num, strlen(num));
+        spos += strlen(num);
+        sc = spos;
+        memcpy(str0+spos, str+pend+1, sl-pend-1);
+        spos += sl - pend - 1;
+        sl = spos;
+        str0[sl] = 0;
+        free(str);
+        str = str0;
+        cpdepth--;
+        i = sc;
+      }
+    }
+    pdepth--;
+  }
+
+  r = p_strmath(str);
+
+  free(str);
+  return r;
+}
+ulong strmath(string *str) { return strmath(str->s); }
+ulong strmath(stringlist *str, ulong num) { return strmath(strptr(str, num)); }
+
+ulong strmathentity(char *str) {
+int i, ssl = strlen(str);
+  for(i=0;i<ssl;i++) {
+    if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' ||
+       str[i] == '%' || str[i] == '&' || str[i] == '|' || str[i] == '^' ||
+      (str[i] == '<' && str[i+1] == '<') || (str[i] == '>' && str[i+1] == '>'))return 1;
+  }
+  return 0;
+}
+ulong strmathentity(string *str) { return strmathentity(str->s); }
+ulong strmathentity(stringlist *str, ulong num) { return strmathentity(strptr(str, num)); }
diff --git a/bsnes/misc/libstr_replace.cpp b/bsnes/misc/libstr_replace.cpp
new file mode 100644
index 00000000..415ea3d4
--- /dev/null
+++ b/bsnes/misc/libstr_replace.cpp
@@ -0,0 +1,82 @@
+void replace(string *str, char *key, char *token) {
+int i, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str);
+ulong replace_count = 0, size;
+char *data;
+  if(ksl > ssl)return;
+  if(tsl > ksl) {                      //the new string may be longer than the old string...
+    for(i=0;i<=ssl-ksl;) {             //so let's find out how big of a string we'll need...
+      if(!memcmp(str->s + i, key, ksl)) {
+        replace_count++;
+        i += ksl;
+      } else i++;
+    }
+    size = ssl + ((tsl - ksl) * replace_count);
+    if(size > str->size)strresize(str, size);
+  }
+  data = (char*)malloc(size + 1);
+  for(i=z=0;i<ssl;) {
+    if(i <= ssl - ksl) {
+      if(!memcmp(str->s + i, key, ksl)) {
+        memcpy(data + z, token, tsl);
+        z += tsl;
+        i += ksl;
+      } else data[z++] = str->s[i++];
+    } else data[z++] = str->s[i++];
+  }
+  data[z] = 0;
+  strcpy(str, data);
+  free(data);
+}
+
+void replace_q(string *str, char *key, char *token) {
+int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str);
+byte x;
+ulong replace_count = 0, size;
+char *data;
+  if(ksl > ssl)return;
+  if(tsl > ksl) {
+    for(i=0;i<=ssl-ksl;) {
+      x = str->s[i];
+      if(x == '\"' || x == '\'') {
+        l = i;
+        i++;
+        while(str->s[i++] != x) {
+          if(i == ssl) {
+            i = l;
+            break;
+          }
+        }
+      }
+      if(!memcmp(str->s + i, key, ksl)) {
+        replace_count++;
+        i += ksl;
+      } else i++;
+    }
+    size = ssl + ((tsl - ksl) * replace_count);
+    if(size > str->size)strresize(str, size);
+  }
+  data = (char*)malloc(size + 1);
+  for(i=z=0;i<ssl;) {
+    x = str->s[i];
+    if(x == '\"' || x == '\'') {
+      l = i++;
+      while(str->s[i] != x && i < ssl)i++;
+      if(i >= ssl)i = l;
+      else {
+        memcpy(data + z, str->s + l, i - l);
+        z += i - l;
+      }
+    }
+    if(i <= ssl - ksl) {
+      if(!memcmp(str->s + i, key, ksl)) {
+        memcpy(data + z, token, tsl);
+        z += tsl;
+        i += ksl;
+        replace_count++;
+      } else data[z++] = str->s[i++];
+    } else data[z++] = str->s[i++];
+  }
+  data[z] = 0;
+  strcpy(str, data);
+  free(data);
+}
diff --git a/bsnes/misc/libstr_split.cpp b/bsnes/misc/libstr_split.cpp
new file mode 100644
index 00000000..91f9ff1e
--- /dev/null
+++ b/bsnes/misc/libstr_split.cpp
@@ -0,0 +1,41 @@
+void split(stringlist *dest, char *key, char *src) {
+int i, ssl = strlen(src), ksl = strlen(key);
+byte x;
+ulong lp = 0, split_count = 0;
+  for(i=0;i<=ssl-ksl;) {
+    if(!memcmp(src + i, key, ksl)) {
+      x = src[i];
+      src[i] = 0;
+      strcpy(dest, split_count++, src + lp);
+      src[i] = x;
+      i += ksl;
+      lp = i;
+    } else i++;
+  }
+  strcpy(dest, split_count++, src + lp);
+}
+void split(stringlist *dest, char *key, string *src) { split(dest, key, src->s); }
+
+void split_q(stringlist *dest, char *key, char *src) {
+int i, z, ssl = strlen(src), ksl = strlen(key);
+byte x;
+ulong lp = 0, split_count = 0;
+  for(i=0;i<=ssl-ksl;) {
+    x = src[i];
+    if(x=='\"' || x=='\'') {
+      z = i++;
+      while(src[i] != x && i < ssl)i++;
+      if(i >= ssl)i = z;
+    }
+    if(!memcmp(src + i, key, ksl)) {
+      x = src[i];
+      src[i] = 0;
+      strcpy(dest, split_count++, src + lp);
+      src[i] = x;
+      i += ksl;
+      lp = i;
+    } else i++;
+  }
+  strcpy(dest, split_count++, src + lp);
+}
+void split_q(stringlist *dest, char *key, string *src) { split_q(dest, key, src->s); }
diff --git a/bsnes/misc/libstr_sprintf.cpp b/bsnes/misc/libstr_sprintf.cpp
new file mode 100644
index 00000000..30a67a2d
--- /dev/null
+++ b/bsnes/misc/libstr_sprintf.cpp
@@ -0,0 +1,130 @@
+void numtobin(char *s, ulong num) {
+ulong mask = 0x80000000, len = 0, z = 0;
+  for(;mask;mask>>=1,len++) { if(num&mask)break; }
+  len = 32 - len;
+  do {
+    if(num&(1<<(len-1)))s[z++] = '1';
+    else                s[z++] = '0';
+  }while(--len);
+  s[z] = 0;
+}
+
+void sprintf(string *str, char *s, ...) {
+va_list args;
+char t[2], n[256];
+int i, l, sl, z;
+byte pad_type, pad_len;
+ulong num;
+char *r;
+  va_start(args, s);
+  strcpy(str, "");
+  for(i=0;i<strlen(s);i++) {
+    if(s[i] == '%') {
+      i++;
+      if(s[i] == '0' && s[i+1] == '.' && (s[i+2] >= '0' && s[i+2] <= '9')) {
+        pad_type = 1;
+        if(s[i+3] >= '0' && s[i+3] <= '9') { pad_len = (s[i+2]-'0')*10 + (s[i+3]-'0'); i+=4; }
+        else                               { pad_len = (s[i+2]-'0');                   i+=3; }
+      }
+      else if(s[i] >= '0' && s[i] <= '9') {
+        pad_type = 2;
+        if(s[i+1] >= '0' && s[i+1] <= '9') { pad_len = (s[i]-'0')*10 + (s[i+1]-'0'); i+=2; }
+        else                               { pad_len = (s[i]-'0');                   i+=1; }
+      }
+      else { pad_type = 0; }
+
+      if(s[i] == 'd') {
+        num = va_arg(args, ulong);
+        sprintf(n, "%d", num);
+      } else if(s[i] == 'x') {
+        num = va_arg(args, ulong);
+        sprintf(n, "%x", num);
+      } else if(s[i] == 'b') {
+        num = va_arg(args, ulong);
+        numtobin(n, num);
+      } else if(s[i] == 's') {
+        r = va_arg(args, char*);
+      }
+
+      if(pad_type != 0) {
+        if(s[i] == 's')sl = strlen(r);
+        else           sl = strlen(n);
+        if(sl < pad_len) {
+          while(sl < pad_len) {
+            strcat(str, (pad_type == 1)?"0":" ");
+            sl++;
+          }
+        }
+      }
+
+      if(s[i] == 's')strcat(str, r);
+      else           strcat(str, n);
+    } else {
+      t[0] = s[i];
+      t[1] = 0;
+      strcat(str, t);
+    }
+  }
+  va_end(args);
+}
+
+
+void sprintf(stringlist *str_list, ulong str_num, char *s, ...) {
+va_list args;
+char t[2], n[256];
+int i, l, sl, z;
+byte pad_type, pad_len;
+ulong num;
+char *r;
+string *str = strget(str_list, str_num);
+  va_start(args, s);
+  strcpy(str, "");
+  for(i=0;i<strlen(s);i++) {
+    if(s[i] == '%') {
+      i++;
+      if(s[i] == '0' && s[i+1] == '.' && (s[i+2] >= '0' && s[i+2] <= '9')) {
+        pad_type = 1;
+        if(s[i+3] >= '0' && s[i+3] <= '9') { pad_len = (s[i+2]-'0')*10 + (s[i+3]-'0'); i+=4; }
+        else                               { pad_len = (s[i+2]-'0');                   i+=3; }
+      }
+      else if(s[i] >= '0' && s[i] <= '9') {
+        pad_type = 2;
+        if(s[i+1] >= '0' && s[i+1] <= '9') { pad_len = (s[i]-'0')*10 + (s[i+1]-'0'); i+=2; }
+        else                               { pad_len = (s[i]-'0');                   i+=1; }
+      }
+      else { pad_type = 0; }
+
+      if(s[i] == 'd') {
+        num = va_arg(args, ulong);
+        sprintf(n, "%d", num);
+      } else if(s[i] == 'x') {
+        num = va_arg(args, ulong);
+        sprintf(n, "%x", num);
+      } else if(s[i] == 'b') {
+        num = va_arg(args, ulong);
+        numtobin(n, num);
+      } else if(s[i] == 's') {
+        r = va_arg(args, char*);
+      }
+
+      if(pad_type != 0) {
+        if(s[i] == 's')sl = strlen(r);
+        else           sl = strlen(n);
+        if(sl < pad_len) {
+          while(sl < pad_len) {
+            strcat(str, (pad_type == 1)?"0":" ");
+            sl++;
+          }
+        }
+      }
+
+      if(s[i] == 's')strcat(str, r);
+      else           strcat(str, n);
+    } else {
+      t[0] = s[i];
+      t[1] = 0;
+      strcat(str, t);
+    }
+  }
+  va_end(args);
+}
diff --git a/bsnes/misc/libvlist.cpp b/bsnes/misc/libvlist.cpp
new file mode 100644
index 00000000..d5825364
--- /dev/null
+++ b/bsnes/misc/libvlist.cpp
@@ -0,0 +1,55 @@
+ulong __vector_resize(ulong val)
+{
+int i;
+  for(i=0;i<32;i++) {
+    if((1<<i) >= val)break;
+  }
+//if the value is >2 million, this will fail, in which case,
+//just use value. otherwise, use the power of 2.
+  if((1<<i) > val)val = 1<<i;
+  return val;
+}
+
+class vectorlist {
+public:
+ulong *list, *newlist, size, newsize, max_size;
+
+  void alloc(ulong size) {
+    if(size < max_size)return;
+    newsize = __vector_resize(size);
+    newlist = (ulong*)malloc(newsize*4);
+    memcpy(newlist, list, max_size*4);
+    free(list);
+    list     = newlist;
+    max_size = newsize;
+  }
+
+  void add(ulong val) {
+    size++;
+    if(size > max_size)alloc(size + 1);
+    list[size - 1] = val;
+  }
+
+  void set(ulong num, ulong val) {
+    if(num >= max_size)alloc(num + 1);
+    list[num] = val;
+    if(++num > size)size = num;
+  }
+
+  ulong get(ulong num) {
+    if(num >= max_size)return 0;
+    return list[num];
+  }
+
+  vectorlist() {
+    list     = 0;
+    size     = 0;
+    max_size = 8;
+    list     = (ulong*)malloc(8*4);
+  }
+
+  ~vectorlist() {
+    if(list)free(list);
+  }
+
+};
diff --git a/bsnes/mmio.obj b/bsnes/mmio.obj
new file mode 100644
index 0000000000000000000000000000000000000000..090d59ad6bd3c0ee262caf61a8b43c743a65bf79
GIT binary patch
literal 81207
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

literal 0
HcmV?d00001

diff --git a/bsnes/ppu/mmio.cpp b/bsnes/ppu/mmio.cpp
new file mode 100644
index 00000000..4a515a37
--- /dev/null
+++ b/bsnes/ppu/mmio.cpp
@@ -0,0 +1,198 @@
+#include "../base.h"
+#include "../timing/timing.h"
+#include "../cpu/g65816.h"
+extern g65816 *gx816;
+extern snes_timer *snes_time;
+extern videostate render;
+
+ppustate ppu;
+
+#include "ppu_cache.cpp"
+
+#include "ppu_dma.cpp"
+#include "ppu_screen.cpp"
+#include "ppu_vram.cpp"
+#include "ppu_palette.cpp"
+#include "ppu_timing.cpp"
+#include "ppu_oam.cpp"
+#include "ppu_wram.cpp"
+#include "ppu_mode7.cpp"
+#include "ppu_scroll.cpp"
+#include "ppu_muldiv.cpp"
+#include "ppu_window.cpp"
+#include "ppu_addsub.cpp"
+#include "ppu_joypad.cpp"
+#include "ppu_misc.cpp"
+
+#include "ppu.cpp"
+
+byte mmio_read(word addr) {
+static word counter = 0;
+  switch(addr) {
+  case 0x2134:return mmio_r2134();
+  case 0x2135:return mmio_r2135();
+  case 0x2136:return mmio_r2136();
+  case 0x2137:return mmio_r2137();
+  case 0x2138:return mmio_r2138();
+  case 0x2139:return mmio_r2139();
+  case 0x213a:return mmio_r213a();
+  case 0x213b:return mmio_r213b();
+  case 0x213c:return mmio_r213c();
+  case 0x213d:return mmio_r213d();
+  case 0x213e:return mmio_r213e();
+  case 0x213f:return mmio_r213f();
+
+  case 0x2140:case 0x2141:case 0x2142:case 0x2143:
+  case 0x2144:case 0x2145:case 0x2146:case 0x2147:
+  case 0x2148:case 0x2149:case 0x214a:case 0x214b:
+  case 0x214c:case 0x214d:case 0x214e:case 0x214f:
+  case 0x2150:case 0x2151:case 0x2152:case 0x2153:
+  case 0x2154:case 0x2155:case 0x2156:case 0x2157:
+  case 0x2158:case 0x2159:case 0x215a:case 0x215b:
+  case 0x215c:case 0x215d:case 0x215e:case 0x215f:
+  case 0x2160:case 0x2161:case 0x2162:case 0x2163:
+  case 0x2164:case 0x2165:case 0x2166:case 0x2167:
+  case 0x2168:case 0x2169:case 0x216a:case 0x216b:
+  case 0x216c:case 0x216d:case 0x216e:case 0x216f:
+  case 0x2170:case 0x2171:case 0x2172:case 0x2173:
+  case 0x2174:case 0x2175:case 0x2176:case 0x2177:
+  case 0x2178:case 0x2179:case 0x217a:case 0x217b:
+  case 0x217c:case 0x217d:case 0x217e:case 0x217f:
+    byte x;
+    x = rand() & 3;
+    if(x == 0)return gx816->regs.a.b;
+    if(x == 1)return gx816->regs.x;
+    if(x == 2)return gx816->regs.y;
+    if(x == 3) { counter++; return counter >> 1; }
+    break;
+
+  case 0x21c2:return mmio_r21c2();
+  case 0x21c3:return mmio_r21c3();
+
+  case 0x4016:return mmio_r4016();
+  case 0x4210:return mmio_r4210();
+  case 0x4211:return mmio_r4211();
+  case 0x4212:return mmio_r4212();
+  case 0x4214:return mmio_r4214();
+  case 0x4215:return mmio_r4215();
+  case 0x4216:return mmio_r4216();
+  case 0x4217:return mmio_r4217();
+  case 0x4218:return mmio_r4218();
+  case 0x4219:return mmio_r4219();
+  default:
+/*
+    dprintf("* mmio: unknown read [%0.4x]", addr);
+    debug_set_state(DEBUGMODE_WAIT);
+    disas_g65816_op();
+*/
+    break;
+  }
+  return 0x00;
+}
+
+void mmio_write(word addr, byte value) {
+  switch(addr) {
+  case 0x2100:mmio_w2100(value);break;
+  case 0x2101:mmio_w2101(value);break;
+  case 0x2102:mmio_w2102(value);break;
+  case 0x2103:mmio_w2103(value);break;
+  case 0x2104:mmio_w2104(value);break;
+  case 0x2105:mmio_w2105(value);break;
+  case 0x2106:mmio_w2106(value);break;
+  case 0x2107:mmio_w2107(value);break;
+  case 0x2108:mmio_w2108(value);break;
+  case 0x2109:mmio_w2109(value);break;
+  case 0x210a:mmio_w210a(value);break;
+  case 0x210b:mmio_w210b(value);break;
+  case 0x210c:mmio_w210c(value);break;
+  case 0x210d:mmio_w210d(value);break;
+  case 0x210e:mmio_w210e(value);break;
+  case 0x210f:mmio_w210f(value);break;
+  case 0x2110:mmio_w2110(value);break;
+  case 0x2111:mmio_w2111(value);break;
+  case 0x2112:mmio_w2112(value);break;
+  case 0x2113:mmio_w2113(value);break;
+  case 0x2114:mmio_w2114(value);break;
+  case 0x2115:mmio_w2115(value);break;
+  case 0x2116:mmio_w2116(value);break;
+  case 0x2117:mmio_w2117(value);break;
+  case 0x2118:mmio_w2118(value);break;
+  case 0x2119:mmio_w2119(value);break;
+  case 0x211a:mmio_w211a(value);break;
+  case 0x211b:mmio_w211b(value);break;
+  case 0x211c:mmio_w211c(value);break;
+  case 0x211d:mmio_w211d(value);break;
+  case 0x211e:mmio_w211e(value);break;
+  case 0x211f:mmio_w211f(value);break;
+  case 0x2120:mmio_w2120(value);break;
+  case 0x2121:mmio_w2121(value);break;
+  case 0x2122:mmio_w2122(value);break;
+  case 0x2123:mmio_w2123(value);break;
+  case 0x2124:mmio_w2124(value);break;
+  case 0x2125:mmio_w2125(value);break;
+  case 0x2126:mmio_w2126(value);break;
+  case 0x2127:mmio_w2127(value);break;
+  case 0x2128:mmio_w2128(value);break;
+  case 0x2129:mmio_w2129(value);break;
+  case 0x212a:mmio_w212a(value);break;
+  case 0x212b:mmio_w212b(value);break;
+  case 0x212c:mmio_w212c(value);break;
+  case 0x212d:mmio_w212d(value);break;
+  case 0x212e:mmio_w212e(value);break;
+  case 0x212f:mmio_w212f(value);break;
+  case 0x2130:mmio_w2130(value);break;
+  case 0x2131:mmio_w2131(value);break;
+  case 0x2132:mmio_w2132(value);break;
+  case 0x2133:mmio_w2133(value);break;
+  case 0x2180:mmio_w2180(value);break;
+  case 0x2181:mmio_w2181(value);break;
+  case 0x2182:mmio_w2182(value);break;
+  case 0x2183:mmio_w2183(value);break;
+  case 0x4016:mmio_w4016(value);break;
+  case 0x4200:mmio_w4200(value);break;
+  case 0x4202:mmio_w4202(value);break;
+  case 0x4203:mmio_w4203(value);break;
+  case 0x4204:mmio_w4204(value);break;
+  case 0x4205:mmio_w4205(value);break;
+  case 0x4206:mmio_w4206(value);break;
+  case 0x4207:mmio_w4207(value);break;
+  case 0x4208:mmio_w4208(value);break;
+  case 0x4209:mmio_w4209(value);break;
+  case 0x420a:mmio_w420a(value);break;
+  case 0x420b:mmio_w420b(value);break;
+  case 0x420c:mmio_w420c(value);break;
+  case 0x420d:mmio_w420d(value);break;
+
+  case 0x4300:case 0x4310:case 0x4320:case 0x4330:
+  case 0x4340:case 0x4350:case 0x4360:case 0x4370:
+    mmio_w43x0((addr >> 4) & 7, value);break;
+
+  case 0x4301:case 0x4311:case 0x4321:case 0x4331:
+  case 0x4341:case 0x4351:case 0x4361:case 0x4371:
+    mmio_w43x1((addr >> 4) & 7, value);break;
+
+  case 0x4302:case 0x4312:case 0x4322:case 0x4332:
+  case 0x4342:case 0x4352:case 0x4362:case 0x4372:
+    mmio_w43x2((addr >> 4) & 7, value);break;
+
+  case 0x4303:case 0x4313:case 0x4323:case 0x4333:
+  case 0x4343:case 0x4353:case 0x4363:case 0x4373:
+    mmio_w43x3((addr >> 4) & 7, value);break;
+
+  case 0x4304:case 0x4314:case 0x4324:case 0x4334:
+  case 0x4344:case 0x4354:case 0x4364:case 0x4374:
+    mmio_w43x4((addr >> 4) & 7, value);break;
+
+  case 0x4305:case 0x4315:case 0x4325:case 0x4335:
+  case 0x4345:case 0x4355:case 0x4365:case 0x4375:
+    mmio_w43x5((addr >> 4) & 7, value);break;
+
+  case 0x4306:case 0x4316:case 0x4326:case 0x4336:
+  case 0x4346:case 0x4356:case 0x4366:case 0x4376:
+    mmio_w43x6((addr >> 4) & 7, value);break;
+
+  case 0x4307:case 0x4317:case 0x4327:case 0x4337:
+  case 0x4347:case 0x4357:case 0x4367:case 0x4377:
+    mmio_w43x7((addr >> 4) & 7, value);break;
+  }
+}
diff --git a/bsnes/ppu/ppu.cpp b/bsnes/ppu/ppu.cpp
new file mode 100644
index 00000000..a2745ecf
--- /dev/null
+++ b/bsnes/ppu/ppu.cpp
@@ -0,0 +1,476 @@
+#define RENDER_MAIN 0
+#define RENDER_SUB  1
+
+#include "ppu_render.cpp"
+
+/**********************
+ *** priority table ***
+ *********************************
+ *** p = $2105 bit 3           ***
+ *** o = tile priority bit     ***
+ *** s = sprite priority (0-3) ***
+ *********************************
+ *** p = 0      : p = 1        ***
+ *** bg4(o = 0) : bg4(o = 0)   ***
+ *** bg3(o = 0) : bg3(o = 0)   ***
+ *** oam(s = 0) : oam(s = 0)   ***
+ *** bg4(o = 1) : bg4(o = 1)   ***
+ *** bg3(o = 1) : oam(s = 1)   ***
+ *** oam(s = 1) : bg2(o = 0)   ***
+ *** bg2(o = 0) : bg1(o = 0)   ***
+ *** bg1(o = 0) : oam(s = 2)   ***
+ *** oam(s = 2) : bg2(o = 1)   ***
+ *** bg2(o = 1) : bg1(o = 1)   ***
+ *** bg1(o = 1) : oam(s = 3)   ***
+ *** oam(s = 3) : bg3(o = 1)   ***
+ ********************************/
+
+#define debug_ppu_render_line_bg(bgnum, depth, bg, pri)                \
+  if(render.##bgnum##_enabled[DEBUG_BGENABLED_ALL] == true) {          \
+    if(render.##bgnum##_enabled[DEBUG_BGENABLED_PRI##pri##] == true) { \
+      ppu_render_line_bg(depth, bg, pri);                              \
+    }                                                                  \
+  }
+#define debug_ppu_render_line_oam(bgnum, pri)                          \
+  if(render.##bgnum##_enabled[DEBUG_BGENABLED_ALL] == true) {          \
+    if(render.##bgnum##_enabled[DEBUG_BGENABLED_PRI##pri##] == true) { \
+      ppu_render_line_oam(pri);                                        \
+    }                                                                  \
+  }
+
+void ppu_render_line_mode0(void) {
+  if(ppu.bg_priority_mode == 0) {
+    debug_ppu_render_line_bg (bg4, COLORDEPTH_4, BG4, 0);
+    debug_ppu_render_line_bg (bg3, COLORDEPTH_4, BG3, 0);
+    debug_ppu_render_line_oam(oam,                    0);
+    debug_ppu_render_line_bg (bg4, COLORDEPTH_4, BG4, 1);
+    debug_ppu_render_line_bg (bg3, COLORDEPTH_4, BG3, 1);
+    debug_ppu_render_line_oam(oam,                    1);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_4, BG2, 0);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_4, BG1, 0);
+    debug_ppu_render_line_oam(oam,                    2);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_4, BG2, 1);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_4, BG1, 1);
+    debug_ppu_render_line_oam(oam,                    3);
+  } else {
+    debug_ppu_render_line_bg (bg4, COLORDEPTH_4, BG4, 0);
+    debug_ppu_render_line_bg (bg3, COLORDEPTH_4, BG3, 0);
+    debug_ppu_render_line_oam(oam,                    0);
+    debug_ppu_render_line_bg (bg4, COLORDEPTH_4, BG4, 1);
+    debug_ppu_render_line_oam(oam,                    1);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_4, BG2, 0);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_4, BG1, 0);
+    debug_ppu_render_line_oam(oam,                    2);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_4, BG2, 1);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_4, BG1, 1);
+    debug_ppu_render_line_oam(oam,                    3);
+    debug_ppu_render_line_bg (bg3, COLORDEPTH_4, BG3, 1);
+  }
+}
+
+void ppu_render_line_mode1(void) {
+  if(ppu.bg_priority_mode == 0) {
+    debug_ppu_render_line_bg (bg3, COLORDEPTH_4,  BG3, 0);
+    debug_ppu_render_line_oam(oam,                     0);
+    debug_ppu_render_line_bg (bg3, COLORDEPTH_4,  BG3, 1);
+    debug_ppu_render_line_oam(oam,                     1);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_16, BG2, 0);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_16, BG1, 0);
+    debug_ppu_render_line_oam(oam,                     2);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_16, BG2, 1);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_16, BG1, 1);
+    debug_ppu_render_line_oam(oam,                     3);
+  } else {
+    debug_ppu_render_line_bg (bg3, COLORDEPTH_4,  BG3, 0);
+    debug_ppu_render_line_oam(oam,                     0);
+    debug_ppu_render_line_oam(oam,                     1);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_16, BG2, 0);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_16, BG1, 0)
+    debug_ppu_render_line_oam(oam,                     2);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_16, BG2, 1);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_16, BG1, 1)
+    debug_ppu_render_line_oam(oam,                     3);
+    debug_ppu_render_line_bg (bg3, COLORDEPTH_4,  BG3, 1);
+  }
+}
+
+void ppu_render_line_mode2(void) {
+  if(ppu.bg_priority_mode == 0) {
+    debug_ppu_render_line_oam(oam,                     0);
+    debug_ppu_render_line_oam(oam,                     1);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_16, BG2, 0);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_16, BG1, 0);
+    debug_ppu_render_line_oam(oam,                     2);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_16, BG2, 1);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_16, BG1, 1);
+    debug_ppu_render_line_oam(oam,                     3);
+  } else {
+    debug_ppu_render_line_oam(oam,                     0);
+    debug_ppu_render_line_oam(oam,                     1);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_16, BG2, 0);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_16, BG1, 0)
+    debug_ppu_render_line_oam(oam,                     2);
+    debug_ppu_render_line_bg (bg2, COLORDEPTH_16, BG2, 1);
+    debug_ppu_render_line_bg (bg1, COLORDEPTH_16, BG1, 1)
+    debug_ppu_render_line_oam(oam,                     3);
+  }
+}
+
+void ppu_render_line_mode3(void) {
+  if(ppu.bg_priority_mode == 0) {
+    debug_ppu_render_line_oam(oam,                     0);
+    debug_ppu_render_line_oam(oam,                     1);
+    debug_ppu_render_line_bg(bg2, COLORDEPTH_16,  BG2, 0);
+    debug_ppu_render_line_bg(bg1, COLORDEPTH_256, BG1, 0);
+    debug_ppu_render_line_oam(oam,                     2);
+    debug_ppu_render_line_bg(bg2, COLORDEPTH_16,  BG2, 1);
+    debug_ppu_render_line_bg(bg1, COLORDEPTH_256, BG1, 1);
+    debug_ppu_render_line_oam(oam,                     3);
+  } else {
+    debug_ppu_render_line_oam(oam,                     0);
+    debug_ppu_render_line_oam(oam,                     1);
+    debug_ppu_render_line_bg(bg2, COLORDEPTH_16,  BG2, 0);
+    debug_ppu_render_line_bg(bg1, COLORDEPTH_256, BG1, 0);
+    debug_ppu_render_line_oam(oam,                     2);
+    debug_ppu_render_line_bg(bg2, COLORDEPTH_16,  BG2, 1);
+    debug_ppu_render_line_bg(bg1, COLORDEPTH_256, BG1, 1);
+    debug_ppu_render_line_oam(oam,                     3);
+  }
+}
+
+void ppu_render_line_mode4(void) {
+  if(ppu.bg_priority_mode == 0) {
+    debug_ppu_render_line_oam(oam,                     0);
+    debug_ppu_render_line_oam(oam,                     1);
+    debug_ppu_render_line_bg(bg2, COLORDEPTH_4,   BG2, 0);
+    debug_ppu_render_line_bg(bg1, COLORDEPTH_256, BG1, 0);
+    debug_ppu_render_line_oam(oam,                     2);
+    debug_ppu_render_line_bg(bg2, COLORDEPTH_4,   BG2, 1);
+    debug_ppu_render_line_bg(bg1, COLORDEPTH_256, BG1, 1);
+    debug_ppu_render_line_oam(oam,                     3);
+  } else {
+    debug_ppu_render_line_oam(oam,                     0);
+    debug_ppu_render_line_oam(oam,                     1);
+    debug_ppu_render_line_bg(bg2, COLORDEPTH_4,   BG2, 0);
+    debug_ppu_render_line_bg(bg1, COLORDEPTH_256, BG1, 0);
+    debug_ppu_render_line_oam(oam,                     2);
+    debug_ppu_render_line_bg(bg2, COLORDEPTH_4,   BG2, 1);
+    debug_ppu_render_line_bg(bg1, COLORDEPTH_256, BG1, 1);
+    debug_ppu_render_line_oam(oam,                     3);
+  }
+}
+
+void ppu_render_line_mode5(void) {
+  debug_ppu_render_line_bg(bg2, COLORDEPTH_4,  BG2, 0);
+  debug_ppu_render_line_bg(bg1, COLORDEPTH_16, BG1, 0);
+  debug_ppu_render_line_bg(bg2, COLORDEPTH_4,  BG2, 0);
+  debug_ppu_render_line_bg(bg1, COLORDEPTH_16, BG1, 1);
+}
+
+void ppu_render_line_mode6(void) {
+  debug_ppu_render_line_bg(bg1, COLORDEPTH_16, BG1, 0);
+  debug_ppu_render_line_bg(bg1, COLORDEPTH_16, BG1, 1);
+}
+
+void ppu_render_line_mode7(void) {
+  if(ppu.bg_priority_mode == 0) {
+    debug_ppu_render_line_oam(oam, 0);
+    debug_ppu_render_line_oam(oam, 1);
+    ppu_render_line_m7();
+    debug_ppu_render_line_oam(oam, 2);
+    debug_ppu_render_line_oam(oam, 3);
+  } else {
+    debug_ppu_render_line_oam(oam, 0);
+    debug_ppu_render_line_oam(oam, 1);
+    ppu_render_line_m7();
+    debug_ppu_render_line_oam(oam, 2);
+    debug_ppu_render_line_oam(oam, 3);
+  }
+}
+
+void ppu_render_scanline(void) {
+int x, y;
+  ppu.hirq_triggered = false;
+  ppu.vline_pos++;
+  if(ppu.vline_pos > 261)ppu.vline_pos = 0;
+
+//new screen initialize
+  if(ppu.vline_pos == 0) {
+    ppu.virq_triggered = false;
+    ppu.active_hdma_channels = ppu.toggle_active_hdma_channels;
+    if(ppu.visible_scanlines != ppu.toggle_visible_scanlines) {
+      ppu.visible_scanlines = ppu.toggle_visible_scanlines;
+      video_setsnesmode();
+      video_setmode(false, 512, ppu.visible_scanlines * 2);
+    }
+    gx816->nmi_pin = 1;
+  }
+
+//screen refresh
+  if(ppu.vline_pos == ppu.visible_scanlines) {
+    if(render.frame_count == 0) {
+      UpdateDisplay();
+    }
+    render.frame_count++;
+    if(render.frame_count >= render.frame_skip) {
+      render.frame_count = 0;
+    }
+    ppu.interlace_frame ^= 1;
+  }
+
+//automatic joypad read
+  if(ppu.vline_pos == (ppu.visible_scanlines + 1) && ppu.auto_joypad_read == true) {
+    UpdateJoypad();
+  }
+
+//nmi
+  if(ppu.vline_pos == (ppu.visible_scanlines + 8) && gx816->nmi_pin == 1) {
+    gx816->nmi_pin = 0;
+    if(gx816->nmi_enabled == true) {
+      gx816->InvokeIRQ(0xffea);
+    }
+  }
+
+  UpdateHDMA(); //found in ppu_dma.cpp
+  y = ppu.vline_pos;
+  if(y < ppu.visible_scanlines && (render.frame_skip == 0 || render.frame_count == 0)) {
+    if(ppu.display_disable == true) {
+      memset(ppu.screen + y * 512, 0, 1024);
+    } else {
+      ppu_clear_pixel_cache();
+      switch(ppu.bg_mode) {
+      case 0:ppu_render_line_mode0();break;
+      case 1:ppu_render_line_mode1();break;
+      case 2:ppu_render_line_mode2();break;
+      case 3:ppu_render_line_mode3();break;
+      case 4:ppu_render_line_mode4();break;
+      case 5:ppu_render_line_mode5();break;
+      case 6:ppu_render_line_mode6();break;
+      case 7:ppu_render_line_mode7();break;
+      }
+      ppu_render_line_to_screen();
+    }
+  }
+}
+
+void ppu_update_scanline(void) {
+//starting a new screen?
+  if(ppu.vline_pos > snes_time->vscan_pos) {
+    while(ppu.vline_pos != 0) {
+      ppu_render_scanline();
+    }
+  }
+
+  while(snes_time->vscan_pos > ppu.vline_pos) {
+    ppu_render_scanline();
+  }
+
+  if(!(gx816->regs.p & PF_I)) {
+    if(ppu.vcounter_enabled == true && ppu.hcounter_enabled == true) {
+      if(snes_time->vscan_pos == ppu.virq_pos && ppu.virq_triggered == false) {
+        if(snes_time->hscan_pos >= ppu.hirq_pos && ppu.hirq_triggered == false) {
+          ppu.irq_triggered      = true;
+          ppu.virq_triggered     = true;
+          ppu.hirq_triggered     = true;
+          gx816->InvokeIRQ(0xffee);
+        }
+      }
+    } else if(ppu.vcounter_enabled == true) {
+      if(snes_time->vscan_pos == ppu.virq_pos && ppu.virq_triggered == false) {
+        ppu.irq_triggered      = true;
+        ppu.virq_triggered     = true;
+        gx816->InvokeIRQ(0xffee);
+      }
+    } else if(ppu.hcounter_enabled == true) {
+      if(snes_time->hscan_pos >= ppu.hirq_pos && ppu.hirq_triggered == false) {
+        ppu.irq_triggered      = true;
+        ppu.hirq_triggered     = true;
+        gx816->InvokeIRQ(0xffee);
+      }
+    }
+  }
+}
+
+byte oam_read(word addr) {
+  addr &= 1023;
+  if(addr >= 512) {
+    addr &= 31;
+    return ppu.oam[addr + 512];
+  } else {
+    return ppu.oam[addr];
+  }
+}
+
+void oam_write(word addr, byte value) {
+  addr &= 1023;
+  if(addr >= 512) {
+    addr &= 31;
+    ppu.oam[addr + 512] = value;
+  } else {
+    ppu.oam[addr] = value;
+  }
+}
+
+void PPUInit(byte first_time) {
+int i, l;
+byte r, g, b;
+double m;
+word *ptr;
+  if(first_time == 1) {
+    ppu.screen      = (word*)malloc(512 * 480 * 2);
+    ppu.vram        = (byte*)malloc(0x10000);
+    ppu.cgram       = (byte*)malloc(512);
+    ppu.oam         = (byte*)malloc(544);
+    ppu.light_table = (word*)malloc(16 * 65536 * 2);
+    ppu_init_tiledata_cache();
+
+    for(l=0;l<16;l++) {
+      ppu.mosaic_table[l] = (word*)malloc(4096 * 2);
+      for(i=0;i<4096;i++) {
+        ppu.mosaic_table[l][i] = (i / (l + 1)) * (l + 1);
+      }
+    }
+
+    ptr = (word*)ppu.light_table;
+    for(l=0;l<16;l++) {
+      m = (double)l / 15.0;
+      for(i=0;i<65536;i++) {
+        r = (i      ) & 31;
+        g = (i >>  5) & 31;
+        b = (i >> 10) & 31;
+        if(l == 0) { r = g = b = 0; }
+        else if(l == 15);
+        else {
+          r = (double)r * m;
+          g = (double)g * m;
+          b = (double)b * m;
+        }
+        *ptr++ = (r) | (g << 5) | (b << 10);
+      }
+    }
+  }
+  ppu_clear_pixel_cache();
+  memset(ppu.screen, 0, 512 * 480 * 2);
+  memset(ppu.vram,   0, 0x10000);
+  memset(ppu.cgram,  0, 512);
+  memset(ppu.oam,    0, 544);
+  ppu.ppu_cycles               = 0;
+  ppu.ppu_prev_cycles          = 0;
+  ppu.display_disable          = true;
+  ppu.display_brightness       = 15;
+  ppu.visible_scanlines        = 224;
+  ppu.toggle_visible_scanlines = 224;
+
+  ppu.interlace        = false;
+  ppu.interlace_frame  = 0;
+  ppu.hline_pos        = 0;
+  ppu.vline_pos        = 261;
+  ppu.irq_triggered    = false;
+  ppu.virq_triggered   = false;
+  ppu.hirq_triggered   = false;
+  ppu.vram_write_pos   = 0;
+  ppu.cgram_write_pos  = 0;
+  ppu.wram_write_pos   = 0;
+  ppu.vram_inc_size    = 2;
+  ppu.vram_inc_reg     = 0;
+  ppu.oam_write_pos    = 0;
+  ppu.oam_tiledata_loc = 0;
+
+  ppu.bg_enabled[OAM]              = false;
+  ppu.ss_bg_enabled[OAM]           = false;
+  ppu.mosaic_size                  = 0;
+  ppu.mosaic_enabled[BG4]          = false;
+  ppu.mosaic_enabled[BG3]          = false;
+  ppu.mosaic_enabled[BG2]          = false;
+  ppu.mosaic_enabled[BG1]          = false;
+  ppu.bg_windowing_enabled[OAM]    = false;
+  ppu.ss_bg_windowing_enabled[OAM] = false;
+  ppu.bg_window1_enabled[OAM]      = false;
+  ppu.bg_window2_enabled[OAM]      = false;
+  ppu.bg_window1_clipmode[OAM]     = false;
+  ppu.bg_window2_clipmode[OAM]     = false;
+  ppu.bg_window_mask[OAM]          = false;
+
+  for(i=0;i<4;i++) {
+    ppu.bg_enabled[i]              = false;
+    ppu.ss_bg_enabled[i]           = false;
+    ppu.bg_window1_enabled[i]      = false;
+    ppu.bg_window2_enabled[i]      = false;
+    ppu.bg_windowing_enabled[i]    = false;
+    ppu.ss_bg_windowing_enabled[i] = false;
+    ppu.bg_window1_clipmode[i]     = 0;
+    ppu.bg_window2_clipmode[i]     = 0;
+    ppu.bg_window_mask[i]          = 0;
+    ppu.bg_tilemap_loc[i]          = 0;
+    ppu.bg_tiledata_loc[i]         = 0;
+    ppu.bg_hscroll_pos[i]          = 0;
+    ppu.bg_vscroll_pos[i]          = 0;
+  }
+  ppu.bg_priority_mode    = 0;
+  ppu.oam_base_size       = 0;
+  ppu.oam_name_sel        = 0;
+  ppu.bg_mode             = 0;
+
+  ppu.mul_a               = 0;
+  ppu.mul_b               = 0;
+  ppu.div_a               = 0;
+  ppu.div_b               = 0;
+  ppu.r_4214              = 0;
+  ppu.r_4216              = 0;
+
+  ppu.smul_a              = 0;
+  ppu.smul_b              = 0;
+  ppu.smul_r              = 0;
+
+  ppu.window1_left        = 0;
+  ppu.window1_right       = 0;
+  ppu.window2_left        = 0;
+  ppu.window2_right       = 0;
+
+  ppu.color_window1_enabled  = 0;
+  ppu.color_window2_enabled  = 0;
+  ppu.color_window1_clipmode = 0;
+  ppu.color_window2_clipmode = 0;
+  ppu.color_window_mask      = 0;
+  ppu.color_mask             = 0;
+  ppu.ss_color_mask          = 0;
+  ppu.addsub_mode            = 0;
+  ppu.color_mode             = 0;
+  ppu.color_halve            = 0;
+  for(i=0;i<6;i++) {
+    ppu.bg_color_enabled[i]  = false;
+  }
+  ppu.color_r = 0;
+  ppu.color_g = 0;
+  ppu.color_b = 0;
+
+  ppu.toggle_active_hdma_channels = 0;
+  ppu.active_hdma_channels        = 0;
+  for(i=0;i<8;i++) {
+    memset(&dma_channel[i], 0, sizeof(dmachannel));
+    ppu.hdma_completed[i]           = false;
+    ppu.hdma_scanlines_remaining[i] = 0;
+    ppu.hdma_index_pointer[i]       = 0;
+  }
+
+  ppu.vcounter_enabled = false;
+  ppu.hcounter_enabled = false;
+  ppu.hirq_pos         = 0;
+  ppu.virq_pos         = 0;
+
+  ppu.auto_joypad_read    = false;
+  ppu.joypad_strobe_value = 0;
+
+  ppu.latch_toggle        = 0;
+  ppu.latch_vpos          = 0;
+  ppu.latch_hpos          = 0;
+
+  ppu.m7a = ppu.m7b =
+  ppu.m7c = ppu.m7d =
+  ppu.m7x = ppu.m7y = 0;
+
+  ppu.m7hofs = ppu.m7vofs = 0x0000;
+
+  ppu.mode7_hflip = false;
+  ppu.mode7_vflip = false;
+}
diff --git a/bsnes/ppu/ppu_addsub.cpp b/bsnes/ppu/ppu_addsub.cpp
new file mode 100644
index 00000000..bd711235
--- /dev/null
+++ b/bsnes/ppu/ppu_addsub.cpp
@@ -0,0 +1,60 @@
+/*
+  $2130 : fixed color / screen add sub
+  abcd--ef
+
+  ab: main
+  cd: subscreen
+    00: all the time
+    01: inside window only
+    10: outside window only
+    11: all the time
+  e: 0 = enable addsub for fixed color
+     1 = enable addsub for sub screen
+  f: color / chardata = direct color
+     (mode3, 4, 7 only)
+*/
+void mmio_w2130(byte value) {
+  ppu.color_mask    = (value >> 6) & 3;
+  ppu.ss_color_mask = (value >> 4) & 3;
+  ppu.addsub_mode   = (value & 0x02)?1:0;
+}
+
+/*
+  $2131 : addsub designation
+  mrgsdcba
+
+  m: 0 = enable add color data mode
+     1 = enable sub color data mode
+  r: 1/2 color mode
+  g: Backarea enable
+  s: OAM enable
+  d: BG4 enable
+  c: BG3 enable
+  b: BG2 enable
+  a: BG1 enable
+*/
+void mmio_w2131(byte value) {
+  ppu.color_mode             = (value & 0x80)?COLORMODE_SUB:COLORMODE_ADD;
+  ppu.color_halve            = (value & 0x40)?1:0;
+  ppu.bg_color_enabled[BACK] = (value & 0x20)?true:false;
+  ppu.bg_color_enabled[OAM]  = (value & 0x10)?true:false;
+  ppu.bg_color_enabled[BG4]  = (value & 0x08)?true:false;
+  ppu.bg_color_enabled[BG3]  = (value & 0x04)?true:false;
+  ppu.bg_color_enabled[BG2]  = (value & 0x02)?true:false;
+  ppu.bg_color_enabled[BG1]  = (value & 0x01)?true:false;
+}
+
+/*
+  $2132 : addsub settings
+  bgrddddd
+
+  b: affect blue
+  g: affect green
+  r: affect red
+  d: color constant
+*/
+void mmio_w2132(byte value) {
+  if(value & 0x80)ppu.color_b = (value & 0x1f);
+  if(value & 0x40)ppu.color_g = (value & 0x1f);
+  if(value & 0x20)ppu.color_r = (value & 0x1f);
+}
diff --git a/bsnes/ppu/ppu_cache.cpp b/bsnes/ppu/ppu_cache.cpp
new file mode 100644
index 00000000..591db059
--- /dev/null
+++ b/bsnes/ppu/ppu_cache.cpp
@@ -0,0 +1,49 @@
+#define BLENDTYPE_BACK    0
+#define BLENDTYPE_MAIN    1
+#define BLENDTYPE_SUB     2
+#define BLENDTYPE_COMBINE 3
+
+#define COLORDEPTH_4   0
+#define COLORDEPTH_16  1
+#define COLORDEPTH_256 2
+
+struct {
+  byte color_main, color_sub;
+  byte src_main,   src_sub;
+  byte blend_type;
+}ppu_pixel_cache[512];
+
+#define TILE_2BIT 0
+#define TILE_4BIT 1
+#define TILE_8BIT 2
+
+byte *ppu_bg_tiledata[3];
+byte *ppu_bg_tiledata_state[3];
+
+//this should be reset once every scanline
+void ppu_clear_pixel_cache(void) {
+int i;
+  for(i=0;i<512;i++) {
+    ppu_pixel_cache[i].color_main =
+    ppu_pixel_cache[i].color_sub  = 0;
+    ppu_pixel_cache[i].src_main   =
+    ppu_pixel_cache[i].src_sub    = BACK;
+    ppu_pixel_cache[i].blend_type = BLENDTYPE_BACK;
+  }
+}
+
+void ppu_init_tiledata_cache(void) {
+int i;
+  ppu_bg_tiledata[TILE_2BIT]       = (byte*)malloc(262144);
+  ppu_bg_tiledata[TILE_4BIT]       = (byte*)malloc(131072);
+  ppu_bg_tiledata[TILE_8BIT]       = (byte*)malloc( 65536);
+  ppu_bg_tiledata_state[TILE_2BIT] = (byte*)malloc(  4096);
+  ppu_bg_tiledata_state[TILE_4BIT] = (byte*)malloc(  2048);
+  ppu_bg_tiledata_state[TILE_8BIT] = (byte*)malloc(  1024);
+  memset(ppu_bg_tiledata[TILE_2BIT],       0, 262144);
+  memset(ppu_bg_tiledata[TILE_4BIT],       0, 131072);
+  memset(ppu_bg_tiledata[TILE_4BIT],       0,  65536);
+  memset(ppu_bg_tiledata_state[TILE_2BIT], 0,   4096);
+  memset(ppu_bg_tiledata_state[TILE_4BIT], 0,   2048);
+  memset(ppu_bg_tiledata_state[TILE_8BIT], 0,   1024);
+}
diff --git a/bsnes/ppu/ppu_dma.cpp b/bsnes/ppu/ppu_dma.cpp
new file mode 100644
index 00000000..66f2812f
--- /dev/null
+++ b/bsnes/ppu/ppu_dma.cpp
@@ -0,0 +1,485 @@
+#define DMATRANSFER_CPUTOMMIO 0
+#define DMATRANSFER_MMIOTOCPU 1
+
+#define DMAINDEX_ABSOLUTE 0
+#define DMAINDEX_INDIRECT 1
+
+#define DMAWRITE_INC 0
+#define DMAWRITE_DEC 1
+
+#define HDMAMODE_NORMAL     0
+#define HDMAMODE_CONTINUOUS 1
+
+typedef struct {
+  byte  transfer_mode;
+  byte  index_mode;
+  bool  fixed_address;
+  byte  write_dir;
+  byte  transfer_type;
+  word  dest_addr;
+  ulong src_addr;
+  word  transfer_size;
+  byte  indirect_bank_address;
+  byte  hdma_mode;
+  word  hdma_indirect_pointer;
+}dmachannel;
+
+dmachannel dma_channel[8];
+
+/*
+  $43x0 : DMA control
+  da-ifttt
+
+  d: (dma only)
+     0=read from cpu mem, write to $21??
+     1=read from $21??, write to cpu mem
+  a: (hdma only)
+     0=absolute addressing
+     1=indirect addressing
+  f: 1=fixed address, 0=inc/dec address
+  i: 0=increment address, 1=decrement address
+  t: transfer type
+     000: 1 reg  1 write  (01->2118 23->2118 45->2118 67->2118 89->2118)
+     001: 2 regs 1 write  (01->2118 23->2119 45->2118 67->2119 89->2118)
+     010: 1 reg  2 writes (01->2118 23->2118 45->2118 67->2118 89->2118)
+     011: 2 regs 2 writes (01->2118 23->2118 45->2119 67->2119 89->2118)
+     100: 4 regs 1 write  (01->2118 23->2119 45->211a 67->211b 89->2118)
+     101-111: unknown
+*/
+void mmio_w43x0(byte c, byte value) {
+  dma_channel[c].transfer_mode = (value & 0x80)?DMATRANSFER_MMIOTOCPU:DMATRANSFER_CPUTOMMIO;
+  dma_channel[c].index_mode    = (value & 0x40)?DMAINDEX_INDIRECT:DMAINDEX_ABSOLUTE;
+  dma_channel[c].write_dir     = (value & 0x10)?DMAWRITE_DEC:DMAWRITE_INC;
+  dma_channel[c].fixed_address = (value & 0x08)?true:false;
+  dma_channel[c].transfer_type = (value & 0x07);
+}
+
+/*
+  $43x1 : DMA destination address
+  bbbbbbbb
+
+  b: $2100 | b = destination register - limited to $21xx regs only
+*/
+void mmio_w43x1(byte c, byte value) {
+  dma_channel[c].dest_addr = 0x2100 | value;
+}
+
+/*
+  $43x2-$43x4 : 24-bit DMA source address
+
+  after a dma transfer, this address must be incremented
+*/
+void mmio_w43x2(byte c, byte value) {
+  dma_channel[c].src_addr = (dma_channel[c].src_addr & 0xffff00) | value;
+}
+
+void mmio_w43x3(byte c, byte value) {
+  dma_channel[c].src_addr = (dma_channel[c].src_addr & 0xff00ff) | (value << 8);
+}
+
+void mmio_w43x4(byte c, byte value) {
+  dma_channel[c].src_addr = (dma_channel[c].src_addr & 0x00ffff) | (value << 16);
+}
+
+/*
+  $43x5/$43x6 : DMA transfer size
+*/
+void mmio_w43x5(byte c, byte value) {
+  dma_channel[c].transfer_size = (dma_channel[c].transfer_size & 0xff00) | value;
+}
+
+void mmio_w43x6(byte c, byte value) {
+  dma_channel[c].transfer_size = (dma_channel[c].transfer_size & 0x00ff) | (value << 8);
+}
+
+/*
+  $43x7 : HDMA indirect bank address
+*/
+void mmio_w43x7(byte c, byte value) {
+  dma_channel[c].indirect_bank_address = value;
+}
+
+void dma_cputommio(byte c, byte a) {
+byte x;
+  x = gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, dma_channel[c].src_addr);
+  mmio_write(dma_channel[c].dest_addr + a, x);
+  if(dma_channel[c].fixed_address == false) {
+    if(dma_channel[c].write_dir == DMAWRITE_INC)dma_channel[c].src_addr++;
+    if(dma_channel[c].write_dir == DMAWRITE_DEC)dma_channel[c].src_addr--;
+  }
+  dma_channel[c].transfer_size--;
+}
+
+void dma_mmiotocpu(byte c, byte a) {
+byte x;
+  x = mmio_read(dma_channel[c].dest_addr + a);
+  gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, dma_channel[c].src_addr, x);
+  if(dma_channel[c].fixed_address == false) {
+    if(dma_channel[c].write_dir == DMAWRITE_INC)dma_channel[c].src_addr++;
+    if(dma_channel[c].write_dir == DMAWRITE_DEC)dma_channel[c].src_addr--;
+  }
+  dma_channel[c].transfer_size--;
+}
+
+void dma_transfer_type0(byte c) {
+  if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
+    while(1) {
+      dma_cputommio(c, 0); if(dma_channel[c].transfer_size == 0)break;
+    }
+  } else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
+    while(1) {
+      dma_mmiotocpu(c, 0); if(dma_channel[c].transfer_size == 0)break;
+    }
+  }
+}
+
+void dma_transfer_type1(byte c) {
+  if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
+    while(1) {
+      dma_cputommio(c, 0); if(dma_channel[c].transfer_size == 0)break;
+      dma_cputommio(c, 1); if(dma_channel[c].transfer_size == 0)break;
+    }
+  } else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
+    while(1) {
+      dma_mmiotocpu(c, 0); if(dma_channel[c].transfer_size == 0)break;
+      dma_mmiotocpu(c, 1); if(dma_channel[c].transfer_size == 0)break;
+    }
+  }
+}
+
+void dma_transfer_type2(byte c) {
+  if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
+    while(1) {
+      dma_cputommio(c, 0); if(dma_channel[c].transfer_size == 0)break;
+    }
+  } else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
+    while(1) {
+      dma_mmiotocpu(c, 0); if(dma_channel[c].transfer_size == 0)break;
+    }
+  }
+}
+
+void dma_transfer_type3(byte c) {
+  if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
+    while(1) {
+      dma_cputommio(c, 0); if(dma_channel[c].transfer_size == 0)break;
+      dma_cputommio(c, 0); if(dma_channel[c].transfer_size == 0)break;
+      dma_cputommio(c, 1); if(dma_channel[c].transfer_size == 0)break;
+      dma_cputommio(c, 1); if(dma_channel[c].transfer_size == 0)break;
+    }
+  } else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
+    while(1) {
+      dma_mmiotocpu(c, 0); if(dma_channel[c].transfer_size == 0)break;
+      dma_mmiotocpu(c, 0); if(dma_channel[c].transfer_size == 0)break;
+      dma_mmiotocpu(c, 1); if(dma_channel[c].transfer_size == 0)break;
+      dma_mmiotocpu(c, 1); if(dma_channel[c].transfer_size == 0)break;
+    }
+  }
+}
+
+void dma_transfer_type4(byte c) {
+  if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
+    while(1) {
+      dma_cputommio(c, 0); if(dma_channel[c].transfer_size == 0)break;
+      dma_cputommio(c, 1); if(dma_channel[c].transfer_size == 0)break;
+      dma_cputommio(c, 2); if(dma_channel[c].transfer_size == 0)break;
+      dma_cputommio(c, 3); if(dma_channel[c].transfer_size == 0)break;
+    }
+  } else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
+    while(1) {
+      dma_mmiotocpu(c, 0); if(dma_channel[c].transfer_size == 0)break;
+      dma_mmiotocpu(c, 1); if(dma_channel[c].transfer_size == 0)break;
+      dma_mmiotocpu(c, 2); if(dma_channel[c].transfer_size == 0)break;
+      dma_mmiotocpu(c, 3); if(dma_channel[c].transfer_size == 0)break;
+    }
+  }
+}
+
+/*
+  $420b : DMA  enable
+  $420c : HDMA enable
+
+  each bit corresponds to the respecting DMA channel (7,6,5,4,3,2,1,0)
+  setting a bit in this register will perform the DMA transfer. multiple
+  transfers can be done at once. requires one cycle per byte transferred
+  hdma bits are sticky (they are not cleared automatically after write)
+*/
+void mmio_w420b(byte value) {
+int i;
+  for(i=0;i<8;i++) {
+    if(value & (1 << i)) {
+      snes_time->add_cpu_cycles(dma_channel[i].transfer_size * 6);
+      if     (dma_channel[i].transfer_type == 0)dma_transfer_type0(i);
+      else if(dma_channel[i].transfer_type == 1)dma_transfer_type1(i);
+      else if(dma_channel[i].transfer_type == 2)dma_transfer_type2(i);
+      else if(dma_channel[i].transfer_type == 3)dma_transfer_type3(i);
+      else if(dma_channel[i].transfer_type == 4)dma_transfer_type4(i);
+      else dprintf("* mmio_w420b(): Unknown DMA transfer type: %d", dma_channel[i].transfer_type);
+    }
+  }
+}
+
+void mmio_w420c(byte value) {
+//don't actually enable hdma channels until the start of the next frame
+  ppu.toggle_active_hdma_channels = value;
+}
+
+byte hdma_read_absolute(byte c) {
+ulong x;
+  x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[c].src_addr + ppu.hdma_index_pointer[c]);
+  ppu.hdma_index_pointer[c]++;
+  return x;
+}
+
+byte hdma_read_indirect(byte c) {
+ulong x;
+  x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dma_channel[c].src_addr + ppu.hdma_index_pointer[c]);
+  x += dma_channel[c].hdma_indirect_pointer;
+  x = (dma_channel[c].indirect_bank_address << 16) | (x & 0xffff);
+  x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, x);
+  dma_channel[c].hdma_indirect_pointer++;
+  return x;
+}
+
+void hdma_transfer_type0_absolute(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_absolute(c));
+}
+
+void hdma_transfer_type0_indirect(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_indirect(c));
+  if(dma_channel[c].hdma_mode == HDMAMODE_NORMAL)dma_channel[c].hdma_indirect_pointer -= 1;
+}
+
+void hdma_transfer_type1_absolute(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_absolute(c));
+  mmio_write(dma_channel[c].dest_addr + 1, hdma_read_absolute(c));
+}
+
+void hdma_transfer_type1_indirect(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_indirect(c));
+  mmio_write(dma_channel[c].dest_addr + 1, hdma_read_indirect(c));
+  if(dma_channel[c].hdma_mode == HDMAMODE_NORMAL)dma_channel[c].hdma_indirect_pointer -= 2;
+}
+
+void hdma_transfer_type2_absolute(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_absolute(c));
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_absolute(c));
+}
+
+void hdma_transfer_type2_indirect(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_indirect(c));
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_indirect(c));
+  if(dma_channel[c].hdma_mode == HDMAMODE_NORMAL)dma_channel[c].hdma_indirect_pointer -= 2;
+}
+
+void hdma_transfer_type3_absolute(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_absolute(c));
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_absolute(c));
+  mmio_write(dma_channel[c].dest_addr + 1, hdma_read_absolute(c));
+  mmio_write(dma_channel[c].dest_addr + 1, hdma_read_absolute(c));
+}
+
+void hdma_transfer_type3_indirect(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_indirect(c));
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_indirect(c));
+  mmio_write(dma_channel[c].dest_addr + 1, hdma_read_indirect(c));
+  mmio_write(dma_channel[c].dest_addr + 1, hdma_read_indirect(c));
+  if(dma_channel[c].hdma_mode == HDMAMODE_NORMAL)dma_channel[c].hdma_indirect_pointer -= 4;
+}
+
+void hdma_transfer_type4_absolute(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_absolute(c));
+  mmio_write(dma_channel[c].dest_addr + 1, hdma_read_absolute(c));
+  mmio_write(dma_channel[c].dest_addr + 2, hdma_read_absolute(c));
+  mmio_write(dma_channel[c].dest_addr + 3, hdma_read_absolute(c));
+}
+
+void hdma_transfer_type4_indirect(byte c) {
+  mmio_write(dma_channel[c].dest_addr,     hdma_read_indirect(c));
+  mmio_write(dma_channel[c].dest_addr + 1, hdma_read_indirect(c));
+  mmio_write(dma_channel[c].dest_addr + 2, hdma_read_indirect(c));
+  mmio_write(dma_channel[c].dest_addr + 3, hdma_read_indirect(c));
+  if(dma_channel[c].hdma_mode == HDMAMODE_NORMAL)dma_channel[c].hdma_indirect_pointer -= 4;
+}
+
+byte hdma_transfer_type_size_table[8] = { 1, 2, 2, 4, 4, 0, 0, 0 };
+
+void HDMAFirstWrite(byte c) {
+  if(dma_channel[c].hdma_mode == HDMAMODE_NORMAL     && ppu.hdma_scanlines_remaining[c] == 0x00) {
+    return;
+  }
+  if(dma_channel[c].hdma_mode == HDMAMODE_CONTINUOUS && ppu.hdma_scanlines_remaining[c] == 0x80) {
+    return;
+  }
+
+  if(dma_channel[c].index_mode == DMAINDEX_ABSOLUTE) {
+    if     (dma_channel[c].transfer_type == 0)hdma_transfer_type0_absolute(c);
+    else if(dma_channel[c].transfer_type == 1)hdma_transfer_type1_absolute(c);
+    else if(dma_channel[c].transfer_type == 2)hdma_transfer_type2_absolute(c);
+    else if(dma_channel[c].transfer_type == 3)hdma_transfer_type3_absolute(c);
+    else if(dma_channel[c].transfer_type == 4)hdma_transfer_type4_absolute(c);
+    else dprintf("* mmio_w420c(): Unknown HDMA transfer type: %d", dma_channel[c].transfer_type);
+  } else { //indirect
+    if     (dma_channel[c].transfer_type == 0)hdma_transfer_type0_indirect(c);
+    else if(dma_channel[c].transfer_type == 1)hdma_transfer_type1_indirect(c);
+    else if(dma_channel[c].transfer_type == 2)hdma_transfer_type2_indirect(c);
+    else if(dma_channel[c].transfer_type == 3)hdma_transfer_type3_indirect(c);
+    else if(dma_channel[c].transfer_type == 4)hdma_transfer_type4_indirect(c);
+    else dprintf("* mmio_w420c(): Unknown HDMA transfer type: %d", dma_channel[c].transfer_type);
+  }
+}
+
+void UpdateHDMAAbsoluteNormal(byte c) {
+  if(ppu.hdma_scanlines_remaining[c] == 0x00) {
+    ppu.hdma_scanlines_remaining[c] = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[c].src_addr + ppu.hdma_index_pointer[c]);
+
+    if(ppu.hdma_scanlines_remaining[c] == 0) {
+      ppu.hdma_completed[c] = true;
+      return;
+    }
+
+    dma_channel[c].hdma_indirect_pointer = 0;
+    if(ppu.hdma_scanlines_remaining[c] > 0x80) {
+      dma_channel[c].hdma_mode = HDMAMODE_CONTINUOUS;
+    } else {
+      dma_channel[c].hdma_mode = HDMAMODE_NORMAL;
+    }
+
+    ppu.hdma_index_pointer[c]++;
+    HDMAFirstWrite(c);
+  }
+
+  ppu.hdma_scanlines_remaining[c]--;
+}
+
+void UpdateHDMAAbsoluteContinuous(byte c) {
+  if(ppu.hdma_scanlines_remaining[c] == 0x80) {
+    ppu.hdma_scanlines_remaining[c] = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[c].src_addr + ppu.hdma_index_pointer[c]);
+
+    if(ppu.hdma_scanlines_remaining[c] == 0) {
+      ppu.hdma_completed[c] = true;
+      return;
+    }
+
+    dma_channel[c].hdma_indirect_pointer = 0;
+    if(ppu.hdma_scanlines_remaining[c] > 0x80) {
+      dma_channel[c].hdma_mode = HDMAMODE_CONTINUOUS;
+    } else {
+      dma_channel[c].hdma_mode = HDMAMODE_NORMAL;
+    }
+
+    ppu.hdma_index_pointer[c]++;
+    HDMAFirstWrite(c);
+    ppu.hdma_scanlines_remaining[c]--;
+  } else {
+    if     (dma_channel[c].transfer_type == 0)hdma_transfer_type0_absolute(c);
+    else if(dma_channel[c].transfer_type == 1)hdma_transfer_type1_absolute(c);
+    else if(dma_channel[c].transfer_type == 2)hdma_transfer_type2_absolute(c);
+    else if(dma_channel[c].transfer_type == 3)hdma_transfer_type3_absolute(c);
+    else if(dma_channel[c].transfer_type == 4)hdma_transfer_type4_absolute(c);
+    else dprintf("* mmio_w420c(): Unknown HDMA transfer type: %d", dma_channel[c].transfer_type);
+
+    ppu.hdma_scanlines_remaining[c]--;
+  }
+}
+
+void UpdateHDMAIndirectNormal(byte c) {
+  if(ppu.hdma_scanlines_remaining[c] == 0x00) {
+    ppu.hdma_index_pointer[c] += 2;
+    ppu.hdma_scanlines_remaining[c] = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[c].src_addr + ppu.hdma_index_pointer[c]);
+
+    if(ppu.hdma_scanlines_remaining[c] == 0) {
+      ppu.hdma_completed[c] = true;
+      return;
+    }
+
+    dma_channel[c].hdma_indirect_pointer = 0;
+    if(ppu.hdma_scanlines_remaining[c] > 0x80) {
+      dma_channel[c].hdma_mode = HDMAMODE_CONTINUOUS;
+    } else {
+      dma_channel[c].hdma_mode = HDMAMODE_NORMAL;
+    }
+
+    ppu.hdma_index_pointer[c]++;
+    HDMAFirstWrite(c);
+  }
+
+  ppu.hdma_scanlines_remaining[c]--;
+}
+
+void UpdateHDMAIndirectContinuous(byte c) {
+  if(ppu.hdma_scanlines_remaining[c] == 0x80) {
+    ppu.hdma_index_pointer[c] += 2;
+    ppu.hdma_scanlines_remaining[c] = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[c].src_addr + ppu.hdma_index_pointer[c]);
+
+    if(ppu.hdma_scanlines_remaining[c] == 0) {
+      ppu.hdma_completed[c] = true;
+      return;
+    }
+
+    dma_channel[c].hdma_indirect_pointer = 0;
+    if(ppu.hdma_scanlines_remaining[c] > 0x80) {
+      dma_channel[c].hdma_mode = HDMAMODE_CONTINUOUS;
+    } else {
+      dma_channel[c].hdma_mode = HDMAMODE_NORMAL;
+    }
+    ppu.hdma_index_pointer[c]++;
+    HDMAFirstWrite(c);
+    ppu.hdma_scanlines_remaining[c]--;
+  } else {
+    if     (dma_channel[c].transfer_type == 0)hdma_transfer_type0_indirect(c);
+    else if(dma_channel[c].transfer_type == 1)hdma_transfer_type1_indirect(c);
+    else if(dma_channel[c].transfer_type == 2)hdma_transfer_type2_indirect(c);
+    else if(dma_channel[c].transfer_type == 3)hdma_transfer_type3_indirect(c);
+    else if(dma_channel[c].transfer_type == 4)hdma_transfer_type4_indirect(c);
+    else dprintf("* mmio_w420c(): Unknown HDMA transfer type: %d", dma_channel[c].transfer_type);
+
+    ppu.hdma_scanlines_remaining[c]--;
+  }
+}
+
+void UpdateHDMA(void) {
+int c;
+  for(c=0;c<8;c++) {
+    if(ppu.active_hdma_channels & (1 << c)) {
+      if(ppu.vline_pos == 0)continue;
+      if(ppu.vline_pos == 1) {
+        ppu.hdma_completed[c]     = false;
+        ppu.hdma_index_pointer[c] = 0;
+        ppu.hdma_scanlines_remaining[c] = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[c].src_addr);
+        ppu.hdma_index_pointer[c]++;
+
+        if(ppu.hdma_scanlines_remaining[c] == 0) {
+          ppu.hdma_completed[c] = true;
+          continue;
+        }
+
+        dma_channel[c].hdma_indirect_pointer = 0;
+        if(ppu.hdma_scanlines_remaining[c] > 0x80) {
+          dma_channel[c].hdma_mode = HDMAMODE_CONTINUOUS;
+        } else {
+          dma_channel[c].hdma_mode = HDMAMODE_NORMAL;
+        }
+
+        HDMAFirstWrite(c);
+        ppu.hdma_scanlines_remaining[c]--;
+      } else {
+        if(ppu.hdma_completed[c] == true)continue;
+
+        if(dma_channel[c].index_mode == DMAINDEX_ABSOLUTE) {
+          if(dma_channel[c].hdma_mode == HDMAMODE_NORMAL) {
+            UpdateHDMAAbsoluteNormal(c);
+          } else {
+            UpdateHDMAAbsoluteContinuous(c);
+          }
+        } else { //indirect
+          if(dma_channel[c].hdma_mode == HDMAMODE_NORMAL) {
+            UpdateHDMAIndirectNormal(c);
+          } else {
+            UpdateHDMAIndirectContinuous(c);
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/bsnes/ppu/ppu_joypad.cpp b/bsnes/ppu/ppu_joypad.cpp
new file mode 100644
index 00000000..082325d0
--- /dev/null
+++ b/bsnes/ppu/ppu_joypad.cpp
@@ -0,0 +1,67 @@
+joypad_state joypad1;
+
+/*
+  *1 - The joypad contains a small bit shifter that has 16 bits.
+    Reading from 4016 reads one bit from this buffer, then moves
+    the buffer left one, and adds a '1' to the rightmost bit.
+    Writing a one to $4016 will fill the buffer with the current
+    joypad button states, and lock the bit shifter at position
+    zero. All reads will be the first buffer state, or 'B'.
+    A zero must be written back to $4016 to unlock the buffer,
+    so that reads will increment the bit shifting position.
+*/
+byte mmio_r4016(void) {
+byte r = 0;
+  if(ppu.joypad_strobe_value == 1) { //*1
+    r |= joypad1.b;
+  } else {
+    if     (joypad1.read_pos ==  0)r |= joypad1.b;
+    else if(joypad1.read_pos ==  1)r |= joypad1.y;
+    else if(joypad1.read_pos ==  2)r |= joypad1.select;
+    else if(joypad1.read_pos ==  3)r |= joypad1.start;
+    else if(joypad1.read_pos ==  4)r |= joypad1.up;
+    else if(joypad1.read_pos ==  5)r |= joypad1.down;
+    else if(joypad1.read_pos ==  6)r |= joypad1.left;
+    else if(joypad1.read_pos ==  7)r |= joypad1.right;
+    else if(joypad1.read_pos ==  8)r |= joypad1.a;
+    else if(joypad1.read_pos ==  9)r |= joypad1.x;
+    else if(joypad1.read_pos == 10)r |= joypad1.l;
+    else if(joypad1.read_pos == 11)r |= joypad1.r;
+    else if(joypad1.read_pos == 16)r |= 1; //joypad connected bit (1=yes, 0=no)
+    else                           r |= 1; //after 16th read, all subsequent reads return 1
+    if(++joypad1.read_pos > 17)joypad1.read_pos = 17;
+  }
+  return r;
+}
+
+byte mmio_r4218(void) {
+byte r;
+  if(ppu.auto_joypad_read == false)               return 0x00; //cannot read joypad if auto joypad read not enabled
+  if(ppu.vline_pos >= 225 && ppu.vline_pos <= 227)return 0x00; //cannot read joypad while SNES is polling the joypad data
+  r = joypad1.a << 7 |
+      joypad1.x << 6 |
+      joypad1.l << 5 |
+      joypad1.r << 4;
+  return r;
+}
+
+byte mmio_r4219(void) {
+byte r;
+  if(ppu.auto_joypad_read == false)               return 0x00; //cannot read joypad if auto joypad read not enabled
+  if(ppu.vline_pos >= 225 && ppu.vline_pos <= 227)return 0x00; //cannot read joypad while SNES is polling the joypad data
+  r = joypad1.b      << 7 |
+      joypad1.y      << 6 |
+      joypad1.select << 5 |
+      joypad1.start  << 4 |
+      joypad1.up     << 3 |
+      joypad1.down   << 2 |
+      joypad1.left   << 1 |
+      joypad1.right;
+  return r;
+}
+
+void mmio_w4016(byte value) {
+  ppu.joypad_strobe_value = value;
+  if(value == 1)UpdateJoypad();
+  if(value == 0)joypad1.read_pos = 0;
+}
diff --git a/bsnes/ppu/ppu_misc.cpp b/bsnes/ppu/ppu_misc.cpp
new file mode 100644
index 00000000..80d1cf91
--- /dev/null
+++ b/bsnes/ppu/ppu_misc.cpp
@@ -0,0 +1,15 @@
+/*
+  $21c2/$21c3
+
+  These seem to be version information registers... I don't know
+  what their purpose is, but I do know that the SNES demo rom
+  expects these values to be returned in order to proceed through
+  the character test.
+*/
+byte mmio_r21c2(void) {
+  return 0x20;
+}
+
+byte mmio_r21c3(void) {
+  return 0x00;
+}
diff --git a/bsnes/ppu/ppu_mode7.cpp b/bsnes/ppu/ppu_mode7.cpp
new file mode 100644
index 00000000..302eed08
--- /dev/null
+++ b/bsnes/ppu/ppu_mode7.cpp
@@ -0,0 +1,74 @@
+/*
+  $211a : mode7 settings register
+  ab0000yx
+
+  ab:
+   00 = use screen repetition if outside screen area
+   01 = ???
+   10 = use character 0x00 repetition if outside screen area
+   11 = use back color if outside screen area
+  y: vertical screen flip
+  x: horizontal screen flip
+*/
+void mmio_w211a(byte value) {
+  ppu.mode7_vflip = (value & 0x02)?true:false;
+  ppu.mode7_hflip = (value & 0x01)?true:false;
+}
+
+byte m7_latch = 0x00;
+
+/*
+  $211b : m7a / 16-bit source operand for signed multiplication
+*/
+void mmio_w211b(byte value) {
+static byte latch = 0;
+  ppu.m7a  = (value << 8) | m7_latch;
+  m7_latch = value;
+
+  if(!latch) { ppu.smul_a = (ppu.smul_a & 0xff00) | value;        }
+  else       { ppu.smul_a = (ppu.smul_a & 0x00ff) | (value << 8); }
+
+  latch ^= 1;
+}
+
+/*
+  $211c : m7b / 8-bit source operand for signed multiplication
+*/
+void mmio_w211c(byte value) {
+  ppu.m7b  = (value << 8) | m7_latch;
+  m7_latch = value;
+
+  ppu.smul_b = value;
+}
+
+/*
+  $211d : m7c
+*/
+void mmio_w211d(byte value) {
+  ppu.m7c  = (value << 8) | m7_latch;
+  m7_latch = value;
+}
+
+/*
+  $211e : m7d
+*/
+void mmio_w211e(byte value) {
+  ppu.m7d  = (value << 8) | m7_latch;
+  m7_latch = value;
+}
+
+/*
+  $211f : m7x
+*/
+void mmio_w211f(byte value) {
+  ppu.m7x  = (value << 8) | m7_latch;
+  m7_latch = value;
+}
+
+/*
+  $2120 : m7y
+*/
+void mmio_w2120(byte value) {
+  ppu.m7y  = (value << 8) | m7_latch;
+  m7_latch = value;
+}
diff --git a/bsnes/ppu/ppu_muldiv.cpp b/bsnes/ppu/ppu_muldiv.cpp
new file mode 100644
index 00000000..731be27b
--- /dev/null
+++ b/bsnes/ppu/ppu_muldiv.cpp
@@ -0,0 +1,57 @@
+byte mmio_r2134(void) {
+ulong r;
+  r = (signed short)ppu.smul_a * (signed char)ppu.smul_b;
+  return r & 0xff;
+}
+
+byte mmio_r2135(void) {
+ulong r;
+  r = (signed short)ppu.smul_a * (signed char)ppu.smul_b;
+  return (r >> 8) & 0xff;
+}
+
+byte mmio_r2136(void) {
+ulong r;
+  r = (signed short)ppu.smul_a * (signed char)ppu.smul_b;
+  return (r >> 16) & 0xff;
+}
+
+void mmio_w4202(byte value) {
+  ppu.mul_a = value;
+}
+
+void mmio_w4203(byte value) {
+  ppu.mul_b = value;
+  ppu.r_4216 = ppu.mul_a * ppu.mul_b;
+}
+
+void mmio_w4204(byte value) {
+  ppu.div_a = (ppu.div_a & 0xff00) | value;
+}
+
+void mmio_w4205(byte value) {
+  ppu.div_a = (ppu.div_a & 0x00ff) | (value << 8);
+}
+
+void mmio_w4206(byte value) {
+  ppu.div_b = value;
+
+  ppu.r_4214 = (ppu.div_b)?ppu.div_a / ppu.div_b : 0;
+  ppu.r_4216 = (ppu.div_b)?ppu.div_a % ppu.div_b : 0;
+}
+
+byte mmio_r4214(void) {
+  return ppu.r_4214;
+}
+
+byte mmio_r4215(void) {
+  return ppu.r_4214 >> 8;
+}
+
+byte mmio_r4216(void) {
+  return ppu.r_4216;
+}
+
+byte mmio_r4217(void) {
+  return ppu.r_4216 >> 8;
+}
diff --git a/bsnes/ppu/ppu_oam.cpp b/bsnes/ppu/ppu_oam.cpp
new file mode 100644
index 00000000..162c6d83
--- /dev/null
+++ b/bsnes/ppu/ppu_oam.cpp
@@ -0,0 +1,86 @@
+/*
+  $2101 : OAM settings
+  sssnnbbb
+
+  s: base sprite size
+          small : large
+     000:   8x8 : 16x16
+     001:   8x8 : 32x32
+     010:   8x8 : 64x64
+     011: 16x16 : 32x32
+     100: 16x16 : 64x64
+     101: 32x32 : 64x64
+     110: 16x32 : 32x64
+     111: 16x32 : 32x32
+     small/large is determined by oam size bit
+  n: name selection (0-3)
+  b: oam tiledata location (>>14) -- highest bit ignored
+*/
+void mmio_w2101(byte value) {
+  ppu.oam_base_size    = (value >> 5);
+  ppu.oam_name_sel     = (value >> 3) & 3;
+  ppu.oam_tiledata_loc = (value & 3) << 14;
+}
+
+/*
+  $2102/$2103 : OAM access address
+  $2102: llllllll
+  $2103: ???????h
+
+  9-bit address, h = bit 8, l = bits 7-0
+*/
+byte ppu_oam_write_posl = 0x00, ppu_oam_write_posh = 0x00;
+
+void mmio_w2102(byte value) {
+  ppu_oam_write_posl = value;
+  ppu.oam_write_pos = ((ppu_oam_write_posh << 8) | (ppu_oam_write_posl)) * 2;
+}
+
+void mmio_w2103(byte value) {
+  ppu_oam_write_posh = value & 0x01;
+  ppu.oam_write_pos = ((ppu_oam_write_posh << 8) | (ppu_oam_write_posl)) * 2;
+}
+
+byte ppu_oam_latch_data = 0;
+
+/*
+  $2104 : OAM write
+
+  write one byte to OAM data. even writes (bit 0 = 0) are cached
+  to the OAM latch, and no data is transferred to OAM ram. odd writes
+  (bit 0 = 1) write the latch value, and then the requested value (2 bytes)
+  to oam data. writes to OAM address 0x0200 and above (priority / x bit 8 table)
+  always write, but even writes still update the latch data.
+*/
+void mmio_w2104(byte value) {
+  if(ppu.oam_write_pos >= 0x0200) {
+    if((ppu.oam_write_pos & 1) == 0) {
+      ppu_oam_latch_data = value;
+    }
+    oam_write(ppu.oam_write_pos, value);
+  } else if((ppu.oam_write_pos & 1) == 0) {
+    ppu_oam_latch_data = value;
+  } else {
+    oam_write((ppu.oam_write_pos & 0x03fe),     ppu_oam_latch_data);
+    oam_write((ppu.oam_write_pos & 0x03fe) + 1, value);
+  }
+  ppu.oam_write_pos++;
+  ppu.oam_write_pos &= 0x03ff;
+}
+
+/*
+  $2138 : OAM read
+
+  read one byte from OAM data. if address is even (bit 0 = 0),
+  latch data is updated.
+*/
+byte mmio_r2138(void) {
+byte r;
+  r = oam_read(ppu.oam_write_pos);
+  if((ppu.oam_write_pos & 1) == 0) {
+    ppu_oam_latch_data = r;
+  }
+  ppu.oam_write_pos++;
+  ppu.oam_write_pos &= 0x03ff;
+  return r;
+}
diff --git a/bsnes/ppu/ppu_palette.cpp b/bsnes/ppu/ppu_palette.cpp
new file mode 100644
index 00000000..f8f3b142
--- /dev/null
+++ b/bsnes/ppu/ppu_palette.cpp
@@ -0,0 +1,36 @@
+/*
+  $2121 : cgram write position
+
+  takes an 8-bit value that indexes into color palette cgram data.
+  multiply value by 2 to get actual offset into ppu.cgram
+*/
+void mmio_w2121(byte value) {
+//if(ppu.vline_pos < 224 && ppu.display_disable == false)return;
+  ppu.cgram_write_pos = value << 1;
+}
+
+/*
+  $2122 : cgram write
+
+  writes to cgram using cgram_write_pos * 2 as an index
+*/
+void mmio_w2122(byte val) {
+//if(ppu.vline_pos < 224 && ppu.display_disable == false)return;
+  ppu.cgram[ppu.cgram_write_pos] = val;
+  ppu.cgram_write_pos++;
+  ppu.cgram_write_pos &= 0x01ff;
+}
+
+/*
+  $213b : cgram read
+
+  read from cgram using cgram_write_pos * 2 as an index
+*/
+byte mmio_r213b(void) {
+byte r;
+//if(ppu.vline_pos < 224 && ppu.display_disable == false)return;
+  r = ppu.cgram[ppu.cgram_write_pos];
+  ppu.cgram_write_pos++;
+  ppu.cgram_write_pos &= 0x01ff;
+  return r;
+}
diff --git a/bsnes/ppu/ppu_render.cpp b/bsnes/ppu/ppu_render.cpp
new file mode 100644
index 00000000..648760ee
--- /dev/null
+++ b/bsnes/ppu/ppu_render.cpp
@@ -0,0 +1,753 @@
+byte ppu_addsub_adjust_buffer[96] = {
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+  31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31
+};
+
+#define ppu_pal_pixel(__i) \
+  (*((word*)ppu.cgram + __i))
+
+word ppu_addsub_pixels(byte x, byte cdest_index, byte cdest_bg, byte csrc_index, byte csrc_bg) {
+int r, g, b;
+byte hd = 0, hs = 0;
+word cdest = ppu_pal_pixel(cdest_index);
+word csrc  = ppu_pal_pixel(csrc_index);
+//oam palettes 0-3 are not affected by color add/sub
+  if(cdest_bg == OAM) {
+    if(cdest_index < 192) {
+      return cdest;
+    }
+  }
+  if(ppu.bg_color_enabled[cdest_bg] == true) {
+    hd = hs = ppu.color_halve;
+  }
+  switch(ppu.color_mode) {
+  case COLORMODE_ADD:
+    r = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest      ) & 31) >> hd) + ( ((csrc      ) & 31) >> hs) ));
+    g = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest >>  5) & 31) >> hd) + ( ((csrc >>  5) & 31) >> hs) ));
+    b = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest >> 10) & 31) >> hd) + ( ((csrc >> 10) & 31) >> hs) ));
+    break;
+  case COLORMODE_SUB:
+    r = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest      ) & 31) >> hd) - ( ((csrc      ) & 31) >> hs) ));
+    g = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest >>  5) & 31) >> hd) - ( ((csrc >>  5) & 31) >> hs) ));
+    b = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest >> 10) & 31) >> hd) - ( ((csrc >> 10) & 31) >> hs) ));
+    break;
+  }
+  return ((r) | (g << 5) | (b << 10));
+}
+
+word ppu_addsub_pixel(byte x, byte cdest_index, byte cdest_bg) {
+int r, g, b;
+byte hd = 0;
+word cdest = ppu_pal_pixel(cdest_index);
+//only oam palettes 4-7 are affected by color add/sub
+  if(cdest_bg == OAM) {
+    if(cdest_index < 192) {
+      return cdest;
+    }
+  }
+  if(ppu.bg_color_enabled[cdest_bg] == true) {
+    hd = ppu.color_halve;
+  }
+  switch(ppu.color_mode) {
+  case COLORMODE_ADD:
+    r = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest      ) & 31) >> hd) + (ppu.color_r >> hd) ));
+    g = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest >>  5) & 31) >> hd) + (ppu.color_g >> hd) ));
+    b = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest >> 10) & 31) >> hd) + (ppu.color_b >> hd) ));
+    break;
+  case COLORMODE_SUB:
+    r = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest      ) & 31) >> hd) - (ppu.color_r >> hd) ));
+    g = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest >>  5) & 31) >> hd) - (ppu.color_g >> hd) ));
+    b = *(ppu_addsub_adjust_buffer + 32 + (( ((cdest >> 10) & 31) >> hd) - (ppu.color_b >> hd) ));
+    break;
+  }
+  return ((r) | (g << 5) | (b << 10));
+}
+
+#define ppu_render_bg_tile_line_4(__m) \
+  col = 0;              \
+  if(d0 & __m)col += 1; \
+  if(d1 & __m)col += 2; \
+  *dest++ = col
+#define ppu_render_bg_tile_line_16(__m) \
+  col = 0;              \
+  if(d0 & __m)col += 1; \
+  if(d1 & __m)col += 2; \
+  if(d2 & __m)col += 4; \
+  if(d3 & __m)col += 8; \
+  *dest++ = col
+#define ppu_render_bg_tile_line_256(__m) \
+  col = 0;                \
+  if(d0 & __m)col +=   1; \
+  if(d1 & __m)col +=   2; \
+  if(d2 & __m)col +=   4; \
+  if(d3 & __m)col +=   8; \
+  if(d4 & __m)col +=  16; \
+  if(d5 & __m)col +=  32; \
+  if(d6 & __m)col +=  64; \
+  if(d7 & __m)col += 128; \
+  *dest++ = col
+
+void ppu_render_bg_tile(byte color_depth, byte bg, word tile_num) {
+byte  mask, d0, d1, d2, d3, d4, d5, d6, d7, col;
+int   x, y;
+ulong pos;
+byte *dest;
+  switch(color_depth) {
+  case COLORDEPTH_4:
+    dest = (byte*)ppu_bg_tiledata[TILE_2BIT] + tile_num * 64;
+    pos  = tile_num * 16;
+    y    = 8;
+    while(y--) {
+      d0 = ppu.vram[pos    ];
+      d1 = ppu.vram[pos + 1];
+      ppu_render_bg_tile_line_4(0x80);
+      ppu_render_bg_tile_line_4(0x40);
+      ppu_render_bg_tile_line_4(0x20);
+      ppu_render_bg_tile_line_4(0x10);
+      ppu_render_bg_tile_line_4(0x08);
+      ppu_render_bg_tile_line_4(0x04);
+      ppu_render_bg_tile_line_4(0x02);
+      ppu_render_bg_tile_line_4(0x01);
+      pos += 2;
+    }
+    ppu_bg_tiledata_state[TILE_2BIT][tile_num] = 0;
+    break;
+  case COLORDEPTH_16:
+    dest = (byte*)ppu_bg_tiledata[TILE_4BIT] + tile_num * 64;
+    pos  = tile_num * 32;
+    y    = 8;
+    while(y--) {
+      d0 = ppu.vram[pos     ];
+      d1 = ppu.vram[pos +  1];
+      d2 = ppu.vram[pos + 16];
+      d3 = ppu.vram[pos + 17];
+      ppu_render_bg_tile_line_16(0x80);
+      ppu_render_bg_tile_line_16(0x40);
+      ppu_render_bg_tile_line_16(0x20);
+      ppu_render_bg_tile_line_16(0x10);
+      ppu_render_bg_tile_line_16(0x08);
+      ppu_render_bg_tile_line_16(0x04);
+      ppu_render_bg_tile_line_16(0x02);
+      ppu_render_bg_tile_line_16(0x01);
+      pos += 2;
+    }
+    ppu_bg_tiledata_state[TILE_4BIT][tile_num] = 0;
+    break;
+  case COLORDEPTH_256:
+    dest = (byte*)ppu_bg_tiledata[TILE_8BIT] + tile_num * 64;
+    pos  = tile_num * 64;
+    y    = 8;
+    while(y--) {
+      d0 = ppu.vram[pos     ];
+      d1 = ppu.vram[pos +  1];
+      d2 = ppu.vram[pos + 16];
+      d3 = ppu.vram[pos + 17];
+      d4 = ppu.vram[pos + 32];
+      d5 = ppu.vram[pos + 33];
+      d6 = ppu.vram[pos + 48];
+      d7 = ppu.vram[pos + 49];
+      ppu_render_bg_tile_line_256(0x80);
+      ppu_render_bg_tile_line_256(0x40);
+      ppu_render_bg_tile_line_256(0x20);
+      ppu_render_bg_tile_line_256(0x10);
+      ppu_render_bg_tile_line_256(0x08);
+      ppu_render_bg_tile_line_256(0x04);
+      ppu_render_bg_tile_line_256(0x02);
+      ppu_render_bg_tile_line_256(0x01);
+      pos += 2;
+    }
+    ppu_bg_tiledata_state[TILE_8BIT][tile_num] = 0;
+    break;
+  }
+}
+
+#define PPU_MAIN 0
+#define PPU_SUB  1
+
+bool windows_not_obstructing(byte layer, byte bg, byte x);
+bool color_windows_not_obstructing(byte x, byte color_mask_type);
+
+//light table is mirrored twice so that the high bit (bit 15) in the color
+//is ignored, and does not cause color to reach into next light table.
+#define ppu_write_pixel() \
+  *(ptr + x) = *(light_table + cx)
+
+void ppu_render_line_to_screen(void) {
+int x;
+word *ptr, *light_table;
+word c, cx, cy;
+word screen_width = render.snes_width;
+  ptr         = (word*)ppu.screen;
+  light_table = (word*)ppu.light_table + (ppu.display_brightness * 65536);
+  if(ppu.interlace == true) {
+    ptr += ((ppu.vline_pos * 2) + ppu.interlace_frame) * 512;
+  } else {
+    ptr += ppu.vline_pos * 512;
+  }
+  for(x=0;x<screen_width;x++) {
+    switch(ppu_pixel_cache[x].blend_type) {
+    case BLENDTYPE_BACK:
+      if(ppu.bg_color_enabled[BACK] == true && color_windows_not_obstructing(x, PPU_SUB) == false) {
+        cx = ppu_addsub_pixel(x, 0, BACK);
+      } else {
+        cx = ppu_pal_pixel(0);
+      }
+      ppu_write_pixel();
+      break;
+    case BLENDTYPE_MAIN:
+      if(ppu.bg_color_enabled[ppu_pixel_cache[x].src_main] == true && color_windows_not_obstructing(x, PPU_SUB) == false) {
+        cx = ppu_addsub_pixel(x, ppu_pixel_cache[x].color_main, ppu_pixel_cache[x].src_main);
+      } else {
+        cx = ppu_pal_pixel(ppu_pixel_cache[x].color_main);
+      }
+      ppu_write_pixel();
+      break;
+    case BLENDTYPE_SUB:
+      if(ppu.bg_color_enabled[BACK] && color_windows_not_obstructing(x, PPU_SUB) == false) {
+        cx = ppu_addsub_pixels(x, 0, BACK, ppu_pixel_cache[x].color_sub, ppu_pixel_cache[x].src_sub);
+      } else {
+        cx = ppu_pal_pixel(ppu_pixel_cache[x].color_sub);
+      }
+      ppu_write_pixel();
+      break;
+    case BLENDTYPE_COMBINE:
+      if(color_windows_not_obstructing(x, PPU_SUB) == false) {
+        if(ppu_pixel_cache[x].src_sub == BACK) {
+          cx = ppu_addsub_pixels(x, ppu_pixel_cache[x].color_main, ppu_pixel_cache[x].src_main, 0, BACK);
+        } else {
+          cx = ppu_addsub_pixels(x, ppu_pixel_cache[x].color_main, ppu_pixel_cache[x].src_main,
+                                    ppu_pixel_cache[x].color_sub,  ppu_pixel_cache[x].src_sub);
+        }
+      } else {
+        cx = ppu_pal_pixel(ppu_pixel_cache[x].color_main);
+      }
+      ppu_write_pixel();
+      break;
+    }
+  }
+}
+
+void ppu_set_pixel(byte bg, word x, byte pal_index) {
+  if(ppu.bg_enabled[bg] == true && ppu.ss_bg_enabled[bg] == true) {
+    if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
+    ppu_pixel_cache[x].blend_type = BLENDTYPE_MAIN;
+    ppu_pixel_cache[x].src_main   = bg;
+    ppu_pixel_cache[x].color_main = pal_index;
+    if(color_windows_not_obstructing(x, PPU_SUB) == false) {
+      ppu_pixel_cache[x].src_sub    = bg;
+      ppu_pixel_cache[x].color_sub  = pal_index;
+    }
+  } else if(ppu.bg_enabled[bg] == true && bg == OAM && pal_index < 192) {
+    if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
+    ppu_pixel_cache[x].blend_type = BLENDTYPE_MAIN;
+    ppu_pixel_cache[x].src_main   = bg;
+    ppu_pixel_cache[x].color_main = pal_index;
+  } else if(ppu.bg_enabled[bg] == true) {
+    if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
+    if(ppu.bg_color_enabled[bg] == true && ppu_pixel_cache[x].src_sub != BACK) {
+      ppu_pixel_cache[x].blend_type = BLENDTYPE_COMBINE;
+    } else {
+      ppu_pixel_cache[x].blend_type = BLENDTYPE_MAIN;
+    }
+    ppu_pixel_cache[x].src_main   = bg;
+    ppu_pixel_cache[x].color_main = pal_index;
+  } else if(ppu.ss_bg_enabled[bg] == true) {
+    if(windows_not_obstructing(PPU_SUB, bg, x) == false)return;
+    ppu_pixel_cache[x].src_sub    = bg;
+    ppu_pixel_cache[x].color_sub  = pal_index;
+    if(ppu_pixel_cache[x].blend_type == BLENDTYPE_BACK) {
+      ppu_pixel_cache[x].blend_type = BLENDTYPE_SUB;
+    } else if(ppu_pixel_cache[x].blend_type == BLENDTYPE_MAIN) {
+      if(ppu_pixel_cache[x].src_main != OAM || (ppu_pixel_cache[x].src_main == OAM && ppu_pixel_cache[x].color_main >= 192)) {
+        if(ppu.bg_color_enabled[ppu_pixel_cache[x].src_main] == true) {
+          ppu_pixel_cache[x].blend_type = BLENDTYPE_COMBINE;
+        }
+      }
+    }
+  }
+}
+
+struct {
+  byte num;
+  byte width, height;
+  word x, y;
+  word character;
+  byte v_flip, h_flip;
+  byte palette;
+  byte priority;
+}current_sprite;
+
+void ppu_set_sprite_attributes(byte sprite_num) {
+ulong t;
+byte size, b;
+word x;
+  t = ppu.oam[(sprite_num << 2)    ]       |
+      ppu.oam[(sprite_num << 2) + 1] <<  8 |
+      ppu.oam[(sprite_num << 2) + 2] << 16 |
+      ppu.oam[(sprite_num << 2) + 3] << 24;
+  b = ppu.oam[512 + (sprite_num >> 2)];
+
+  if     ((sprite_num & 3) == 0) { size = (b & 0x02)?1:0; x = (b & 0x01)?0x100:0; }
+  else if((sprite_num & 3) == 1) { size = (b & 0x08)?1:0; x = (b & 0x04)?0x100:0; }
+  else if((sprite_num & 3) == 2) { size = (b & 0x20)?1:0; x = (b & 0x10)?0x100:0; }
+  else if((sprite_num & 3) == 3) { size = (b & 0x80)?1:0; x = (b & 0x40)?0x100:0; }
+
+  current_sprite.num       = sprite_num;
+  current_sprite.priority  = (t >> 28) & 3;
+  current_sprite.x         = x | (t & 0xff);
+  current_sprite.y         = (t >> 8) & 0xff;
+  current_sprite.v_flip    = (t & 0x80000000)?1:0;
+  current_sprite.h_flip    = (t & 0x40000000)?1:0;
+  current_sprite.palette   = (t >> 25) & 7;
+  current_sprite.character = (t >> 16) & 0x01ff;
+
+//size: 0 = small, 1 = large
+  switch(ppu.oam_base_size) {
+  case 0:
+    if(!size) { current_sprite.width =  8; current_sprite.height =  8; }
+    else      { current_sprite.width = 16; current_sprite.height = 16; }
+    break;
+  case 1:
+    if(!size) { current_sprite.width =  8; current_sprite.height =  8; }
+    else      { current_sprite.width = 32; current_sprite.height = 32; }
+    break;
+  case 2:
+    if(!size) { current_sprite.width =  8; current_sprite.height =  8; }
+    else      { current_sprite.width = 64; current_sprite.height = 64; }
+    break;
+  case 3:
+    if(!size) { current_sprite.width = 16; current_sprite.height = 16; }
+    else      { current_sprite.width = 32; current_sprite.height = 32; }
+    break;
+  case 4:
+    if(!size) { current_sprite.width = 16; current_sprite.height = 16; }
+    else      { current_sprite.width = 64; current_sprite.height = 64; }
+    break;
+  case 5:
+    if(!size) { current_sprite.width = 32; current_sprite.height = 32; }
+    else      { current_sprite.width = 64; current_sprite.height = 64; }
+    break;
+  case 6:
+    if(!size) { current_sprite.width = 16; current_sprite.height = 32; }
+    else      { current_sprite.width = 32; current_sprite.height = 64; }
+    break;
+  case 7:
+    if(!size) { current_sprite.width = 16; current_sprite.height = 32; }
+    else      { current_sprite.width = 32; current_sprite.height = 32; }
+    break;
+  }
+}
+
+bool windows_not_obstructing(byte layer, byte bg, byte x) {
+byte w1_mask, w2_mask; //1 = masked, 0 = not masked
+  if(layer == PPU_MAIN) {
+    if(ppu.bg_windowing_enabled[bg] == false)return true;
+  } else if(layer == PPU_SUB) {
+    if(ppu.ss_bg_windowing_enabled[bg] == false)return true;
+  }
+
+  if(ppu.bg_window1_enabled[bg] == true && ppu.bg_window2_enabled[bg] == false) {
+    if(ppu.bg_window1_clipmode[bg] == CLIPMODE_IN) {
+      if(x >= ppu.window1_left && x <= ppu.window1_right)return false;
+      return true;
+    } else {
+      if(x <= ppu.window1_left || x >= ppu.window1_right)return false;
+      return true;
+    }
+  } else if(ppu.bg_window2_enabled[bg] == true && ppu.bg_window1_enabled[bg] == false) {
+    if(ppu.bg_window2_clipmode[bg] == CLIPMODE_IN) {
+      if(x >= ppu.window2_left && x <= ppu.window2_right)return false;
+      return true;
+    } else {
+      if(x <= ppu.window2_left || x >= ppu.window2_right)return false;
+      return true;
+    }
+  } else if(ppu.bg_window1_enabled[bg] == true && ppu.bg_window2_enabled[bg] == true) {
+    if(ppu.bg_window1_clipmode[bg] == CLIPMODE_IN) {
+      if(x >= ppu.window1_left && x <= ppu.window1_right)w1_mask = 1;
+      else w1_mask = 0;
+    } else {
+      if(x <= ppu.window1_left || x >= ppu.window1_right)w1_mask = 1;
+      else w1_mask = 0;
+    }
+
+    if(ppu.bg_window2_clipmode[bg] == CLIPMODE_IN) {
+      if(x >= ppu.window2_left && x <= ppu.window2_right)w2_mask = 1;
+      else w2_mask = 0;
+    } else {
+      if(x <= ppu.window2_left || x >= ppu.window2_right)w2_mask = 1;
+      else w2_mask = 0;
+    }
+
+    switch(ppu.bg_window_mask[bg]) {
+    case WINDOWMASK_OR:
+      if((w1_mask | w2_mask) == 1)return false;
+      return true;
+    case WINDOWMASK_AND:
+      if((w1_mask & w2_mask) == 1)return false;
+      return true;
+    case WINDOWMASK_XOR:
+      if((w1_mask ^ w2_mask) == 1)return false;
+      return true;
+    case WINDOWMASK_XNOR:
+      if((w1_mask ^ w2_mask) == 0)return false;
+      return true;
+    }
+  }
+  return true;
+}
+
+bool color_windows_not_obstructing(byte x, byte color_mask_type) {
+byte w1_mask, w2_mask; //1 = masked, 0 = not masked
+byte color_mask;
+bool r;
+  if(color_mask_type == PPU_MAIN)color_mask = ppu.color_mask;
+  else                           color_mask = ppu.ss_color_mask;
+
+  if(color_mask == 0)return false;
+  if(color_mask == 3)return true;
+
+  if(ppu.color_window1_enabled == false && ppu.color_window2_enabled == false) {
+    r = true;
+  } else if(ppu.color_window1_enabled == true && ppu.color_window2_enabled == false) {
+    if(ppu.color_window1_clipmode == CLIPMODE_IN) {
+      if(x >= ppu.window1_left && x <= ppu.window1_right)r = false;
+      else                                               r = true;
+    } else {
+      if(x <= ppu.window1_left || x >= ppu.window1_right)r = false;
+      else                                               r = true;
+    }
+  } else if(ppu.color_window1_enabled == false && ppu.color_window2_enabled == true) {
+    if(ppu.color_window2_clipmode == CLIPMODE_IN) {
+      if(x >= ppu.window2_left && x <= ppu.window2_right)r = false;
+      else                                               r = true;
+    } else {
+      if(x <= ppu.window2_left || x >= ppu.window2_right)r = false;
+      else                                               r = true;
+    }
+  } else if(ppu.color_window1_enabled == true && ppu.color_window2_enabled == true) {
+    if(ppu.color_window1_clipmode == CLIPMODE_IN) {
+      if(x >= ppu.window1_left && x <= ppu.window1_right)w1_mask = 1;
+      else w1_mask = 0;
+    } else {
+      if(x <= ppu.window1_left || x >= ppu.window1_right)w1_mask = 1;
+      else w1_mask = 0;
+    }
+
+    if(ppu.color_window2_clipmode == CLIPMODE_IN) {
+      if(x >= ppu.window2_left && x <= ppu.window2_right)w2_mask = 1;
+      else w2_mask = 0;
+    } else {
+      if(x <= ppu.window2_left || x >= ppu.window2_right)w2_mask = 1;
+      else w2_mask = 0;
+    }
+
+    switch(ppu.color_window_mask) {
+    case WINDOWMASK_OR:
+      if((w1_mask | w2_mask) == 1)r = false;
+      else                        r = true;
+      break;
+    case WINDOWMASK_AND:
+      if((w1_mask & w2_mask) == 1)r = false;
+      else                        r = true;
+      break;
+    case WINDOWMASK_XOR:
+      if((w1_mask ^ w2_mask) == 1)r = false;
+      else                        r = true;
+      break;
+    case WINDOWMASK_XNOR:
+      if((w1_mask ^ w2_mask) == 0)r = false;
+      else                        r = true;
+      break;
+    }
+  }
+
+  if(color_mask == 2) {
+    r = (r == true)?false:true;
+  }
+
+  return r;
+}
+
+/*
+  *1 - When bit 8 of a sprite's character number is set, such that character data
+       is read from the upper half (upper 8k) of sprite vram, bits 4-3 of $2101
+       are added to bits 14-13 of the tiledata location. The address wraps around
+       the 64k bank. Why this happens, or what it's for, I have no idea.
+  *2 - The sprite tiledata is stored with 16 tiles making up the first row, followed
+       by 16 tiles making up the second row, and so on. Therefore, to get the
+       correct y tile, y / 8 * 1 row (16 tiles) must be used.
+*/
+
+#define ppu_render_oam_tile_line(__m) \
+  x &= 511;               \
+  if(x < 256) {           \
+    col = 0;              \
+    if(d0 & __m)col += 1; \
+    if(d1 & __m)col += 2; \
+    if(d2 & __m)col += 4; \
+    if(d3 & __m)col += 8; \
+    if(col) {                             \
+      col += pal_index;                   \
+      col += 128;                         \
+      ppu_set_pixel(OAM, x, col);         \
+    }                                     \
+  }                                       \
+  x++
+
+void ppu_render_oam_sprite(void) {
+word pos, col, chr, tiledata_inc;
+byte d0, d1, d2, d3, pal_index;
+int x, y, z, x1, mx, mask, p;
+int tile_width;
+  if(ppu.bg_enabled[OAM] == false && ppu.ss_bg_enabled[OAM] == false)return;
+
+  tile_width = current_sprite.width >> SH_8; //e.x. 16x16 sprite = 2x2 tiles
+
+  y = ppu.vline_pos;
+  x = current_sprite.x;
+  if(current_sprite.v_flip) {
+    y = (current_sprite.height - 1) - (ppu.vline_pos - current_sprite.y);
+  } else {
+    y = ppu.vline_pos - current_sprite.y;
+  }
+  y &= 255;
+
+  chr = current_sprite.character;
+  tiledata_inc = (chr & 0x100)?(ppu.oam_name_sel << 13):0; //*1
+  chr += (y >> SH_8) << SH_16; //*2
+  pal_index = (current_sprite.palette << SH_16);
+  for(x1=0;x1<tile_width;x1++) {
+    if(current_sprite.h_flip)mx = (tile_width - 1) - x1;
+    else                     mx = x1;
+    pos = ppu.oam_tiledata_loc + ((chr + mx) << SH_32) + ((y & 7) << SH_2) + tiledata_inc;
+    d0 = ppu.vram[pos     ];
+    d1 = ppu.vram[pos +  1];
+    d2 = ppu.vram[pos + 16];
+    d3 = ppu.vram[pos + 17];
+    if(current_sprite.h_flip) {
+      ppu_render_oam_tile_line(0x01);
+      ppu_render_oam_tile_line(0x02);
+      ppu_render_oam_tile_line(0x04);
+      ppu_render_oam_tile_line(0x08);
+      ppu_render_oam_tile_line(0x10);
+      ppu_render_oam_tile_line(0x20);
+      ppu_render_oam_tile_line(0x40);
+      ppu_render_oam_tile_line(0x80);
+    } else {
+      ppu_render_oam_tile_line(0x80);
+      ppu_render_oam_tile_line(0x40);
+      ppu_render_oam_tile_line(0x20);
+      ppu_render_oam_tile_line(0x10);
+      ppu_render_oam_tile_line(0x08);
+      ppu_render_oam_tile_line(0x04);
+      ppu_render_oam_tile_line(0x02);
+      ppu_render_oam_tile_line(0x01);
+    }
+  }
+}
+
+void ppu_render_line_oam(byte priority) {
+int s;
+  if(ppu.bg_enabled[OAM] != true && ppu.ss_bg_enabled[OAM] != true)return;
+
+  s = 128;
+  while(s--) {
+    ppu_set_sprite_attributes(s);
+    if(current_sprite.priority == priority) {
+//if the sprite is within screen boundaries... render the current line from the sprite
+      if(ppu.vline_pos >= current_sprite.y && ppu.vline_pos < (current_sprite.y + current_sprite.height)) {
+        ppu_render_oam_sprite();
+//or if the sprite is so close to the bottom of the screen that the bottom of it actually wraps back around to the top...
+      } else if((current_sprite.y + current_sprite.height) >= 256 && ppu.vline_pos < ((current_sprite.y + current_sprite.height) & 255)) {
+        ppu_render_oam_sprite();
+      }
+    }
+  }
+}
+
+/*
+  *1 - map_index
+    The tilemap can be 32x32, 64x32, 32x64, or 64x64. Rather than expanding the width
+    and height of the tilemap, the game instead stores duplicate tilemaps immediately
+    following the previous ones. For example, if you were in 64x64 mode, there would
+    be four tilemaps. Each tilemap would be 2048 bytes in size
+    (32 tiles * 32 tiles * 2 bytes/tile), the first tilemap would make the top left
+    corner, the second the top right, the third the bottom left, and the fourth, the
+    bottom right. Because x / y are divided by the tile size, the tile size setting
+    (8x8 or 16x16) does not affect the result.
+  *2 - pos = ppu.bg_tilemap_loc[bg] + map_index + ((y1 / tile_size) & 31) * 64 + ( ((x / tile_size) & 31) * 2);
+    Format: tilemap start location +
+              map index (either map 0 or map 1; see *1) +
+              ((y tile #) mapped to tilemap boundary) * # of bytes per tilemap line +
+              (((x tile #) mapped to tilemap boundary) * 2 (# of bytes per tilemap entry));
+*/
+
+void ppu_render_line_bg(byte color_depth, byte bg, byte priority) {
+int x, y, z, x1, y1;
+int mirror_x, mirror_y, p;
+int screen_x, screen_y;
+int bg_x, bg_y;
+int xpos, ypos, mosaic_x, mosaic_y;
+word t, base_xpos, base_pos, pos, ppos = 0;
+word col;
+byte *src, *bg_tiledata, *bg_tiledata_state;
+byte tiledata_size;
+byte tile_size, tile_width, tile_height;
+byte mask, pal_index, pal_size;
+word tile_num, screen_width, screen_height, screen_width_mask, screen_height_mask, map_index;
+word *mosaic_table;
+  if(ppu.bg_enabled[bg] == false && ppu.ss_bg_enabled[bg] == false)return;
+
+  switch(color_depth) {
+  case COLORDEPTH_4:
+    pal_size      =     4;
+    tiledata_size = SH_16;
+    break;
+  case COLORDEPTH_16:
+    pal_size      =    16;
+    tiledata_size = SH_32;
+    break;
+  case COLORDEPTH_256:
+    pal_size      =   256;
+    tiledata_size = SH_64;
+    break;
+  }
+  bg_tiledata       = (byte*)ppu_bg_tiledata[color_depth];
+  bg_tiledata_state = (byte*)ppu_bg_tiledata_state[color_depth];
+
+  screen_width  = render.snes_width;
+  screen_height = render.snes_width; //this is correct -- ppu tilemap is based around 256x256, etc.
+  tile_size     = (ppu.bg_tile_size[bg])?SH_16:SH_8;
+  tile_width    = tile_size;
+  tile_height   = tile_size;
+
+  if(ppu.interlace == true && (ppu.bg_mode == 5 || ppu.bg_mode == 6)) {
+    screen_y = (ppu.vline_pos << SH_2) + ppu.interlace_frame;
+  } else {
+    screen_y = ppu.vline_pos;
+  }
+
+//Not sure why, but modes 5 and 6 seem to force 16-width tiles.
+//The tile size attribute in $2105 has no effect on tile width.
+  if(ppu.bg_mode == 5 || ppu.bg_mode == 6) {
+    tile_width = SH_16;
+  }
+
+  if(tile_size == SH_16) {
+    screen_width  <<= SH_2;
+    screen_height <<= SH_2;
+  }
+
+  if(ppu.bg_tilemap_size[bg] & 0x01)screen_width  <<= SH_2;
+  if(ppu.bg_tilemap_size[bg] & 0x02)screen_height <<= SH_2;
+
+  screen_width_mask  = screen_width  - 1;
+  screen_height_mask = screen_height - 1;
+
+  if(render.snes_width == 512) {
+    bg_x = (ppu.bg_hscroll_pos[bg] << SH_2) & screen_width_mask;
+  } else {
+    bg_x = ppu.bg_hscroll_pos[bg] & screen_width_mask;
+  }
+  if(render.snes_height == 448) {
+    bg_y = (screen_y + ((ppu.bg_vscroll_pos[bg] << SH_2) & screen_height_mask)) & screen_height_mask;
+  } else {
+    bg_y = (screen_y + (ppu.bg_vscroll_pos[bg] & screen_height_mask)) & screen_height_mask;
+  }
+
+  mosaic_table = (word*)ppu.mosaic_table[ppu.mosaic_size];
+  mosaic_y     = mosaic_table[bg_y];
+
+  for(screen_x=0;screen_x<render.snes_width;screen_x++) {
+    switch(ppu.bg_tilemap_size[bg]) {
+    case 0:
+      map_index  = 0;
+      break;
+    case 1:
+      map_index  = ((bg_x >> tile_size) > 31)?32*32*2:0;
+      break;
+    case 2:
+      map_index  = ((bg_y >> tile_size) > 31)?32*32*2:0;
+      break;
+    case 3:
+      map_index  = ((bg_x >> tile_size) > 31)?32*32*2:0;
+      map_index += ((bg_y >> tile_size) > 31)?32*32*2*2:0;
+      break;
+    }
+
+    mosaic_x = mosaic_table[bg_x];
+
+    base_xpos = ((mosaic_x >> SH_8) & 31);
+    base_pos  = (((mosaic_y >> tile_height) & 31) << SH_32) + ((mosaic_x >> tile_width) & 31);
+    pos       = ppu.bg_tilemap_loc[bg] + map_index + (base_pos << SH_2);
+    t         = *((word*)ppu.vram + (pos >> SH_2));
+    mirror_y  = (t & 0x8000)?1:0;
+    mirror_x  = (t & 0x4000)?1:0;
+    if(((t >> 13) & 1) == priority) {
+      tile_num = t & 0x03ff;
+      if(tile_width == SH_16) {
+        if((mosaic_x & 15) >= 8)tile_num++;
+        if(mirror_x) {
+          if((mosaic_x & 15) >= 8)tile_num--;
+          else                    tile_num++;
+        }
+        tile_num &= 0x03ff;
+      }
+      if(tile_height == SH_16) {
+        if((mosaic_y & 15) >= 8)tile_num += 16;
+        if(mirror_y) {
+          if((mosaic_y & 15) >= 8)tile_num -= 16;
+          else                    tile_num += 16;
+        }
+        tile_num &= 0x03ff;
+      }
+      tile_num += (ppu.bg_tiledata_loc[bg] >> tiledata_size);
+
+      if(bg_tiledata_state[tile_num] == 1) {
+        ppu_render_bg_tile(color_depth, bg, tile_num);
+      }
+
+      pal_index = ((t >> 10) & 7) * pal_size;
+
+      if(mirror_y) { ypos = (7 - (mosaic_y & 7)); }
+      else         { ypos = (    (mosaic_y & 7)); }
+
+//loop while we are rendering from the same tile, as there's no need to do all of the above work
+//unless we have rendered all of the visible tile, taking mosaic into account.
+      while(1) {
+        if(mirror_x) { xpos = (7 - (mosaic_x & 7)); }
+        else         { xpos = (    (mosaic_x & 7)); }
+        col  = *(bg_tiledata + (tile_num << SH_64) + (ypos << SH_8) + (xpos));
+        if(col) {
+          ppu_set_pixel(bg, screen_x, col + pal_index);
+        }
+
+        bg_x++;
+        bg_x &= screen_width_mask;
+        mosaic_x = mosaic_table[bg_x];
+
+        if(base_xpos != ((mosaic_x >> SH_8) & 31))break;
+        screen_x++;
+        if(screen_x >= render.snes_width)break;
+      }
+    } else {
+      while(1) {
+        bg_x++;
+        bg_x &= screen_width_mask;
+        mosaic_x = mosaic_table[bg_x];
+
+        if(base_xpos != ((mosaic_x >> SH_8) & 31))break;
+        screen_x++;
+        if(screen_x >= render.snes_width)break;
+      }
+    }
+  }
+}
+
+#ifdef PUBLIC_DOMAIN
+  #include "ppu_render_mode7f.cpp"
+#else
+  #include "ppu_render_mode7i.cpp"
+#endif
diff --git a/bsnes/ppu/ppu_render_mode7f.cpp b/bsnes/ppu/ppu_render_mode7f.cpp
new file mode 100644
index 00000000..3fd66357
--- /dev/null
+++ b/bsnes/ppu/ppu_render_mode7f.cpp
@@ -0,0 +1,74 @@
+/*
+  This mode7 code was derived from my own research, assisted by
+  information in the public domain. It is therefore redistributed
+  to the public domain. This code is infinitesimally less accurate
+  than ppu_render_mode7i.cpp, but nearly twice as slow.
+  However, this file contains no licensing restrictions.
+  Please define the precompiler variable PUBLIC_DOMAIN to use this
+  code instead of mode7i.
+*/
+
+/*
+  *1 - converts 16-bit word value to float within the range -128/127. decimal
+       has range of 256 with steps of 0.00390625
+  *2 - (int)float will turn anything from -0.999 to 0.999 to 0. this code will
+       check to see if the number is negative, and if the decimal place (.xxx)
+       is zero or not. If value is positive or the decimal place ends on .000,
+       the number is converted directly to an int. otherwise, one is subtracted
+       to make up for the rounding error of 1 mentioned above.
+       result is masked by 1023 (width / height of map is 1024) to prevent
+       negative values from causing an error with the division in the tile
+       calculation below.
+  *3 - mode7 vram consists of 32k of data. there are two 16k regions interleaved
+       in bytes. the low byte is the tile number, and the high byte is tile data.
+       the tile data directly indexes into the palette. the map is 128*128, and
+       there are 256 possible characters. each character is 64 bytes in length.
+*/
+void ppu_render_line_m7(void) {
+int   x, y, sx, sy;
+byte  tile, palette;
+float x_stepx, x_stepy, y_stepx, y_stepy;
+float centerx, centery, scrollx, scrolly, startx, starty;
+  y               = (ppu.mode7_vflip == true)?223 - ppu.vline_pos:ppu.vline_pos;
+
+//*1
+  x_stepx = (float)((signed short)ppu.m7a) / 256.0;
+  x_stepy = (float)((signed short)ppu.m7b) / 256.0;
+  y_stepx = (float)((signed short)ppu.m7c) / 256.0;
+  y_stepy = (float)((signed short)ppu.m7d) / 256.0;
+
+  centerx = (float)(1.0 - x_stepx) * (signed short)ppu.m7x - x_stepy * (signed short)ppu.m7y;
+  centery = (float)(1.0 - y_stepy) * (signed short)ppu.m7y - y_stepx * (signed short)ppu.m7x;
+
+  scrollx = (float)((signed short)ppu.m7hofs);
+  scrolly = (float)((signed short)ppu.m7vofs);
+
+  startx  = centerx + ((scrollx) * x_stepx) + ((scrolly + y) * x_stepy);
+  starty  = centery + ((scrollx) * y_stepx) + ((scrolly + y) * y_stepy);
+
+  for(x=0;x<256;x++) {
+//*2
+    if(startx < 0.0 && (int)(startx * 32768) & 32767) {
+      sx = (int)(startx - 1) & 1023;
+    } else {
+      sx = (int)startx & 1023;
+    }
+    if(starty < 0.0 && (int)(starty * 32768) & 32767) {
+      sy = (int)(starty - 1) & 1023;
+    } else {
+      sy = (int)starty & 1023;
+    }
+//*3
+    tile    = ppu.vram[(((sy / 8) & 127) * 128 + ((sx / 8) & 127)) << 1];
+    palette = ppu.vram[((tile * 64 + (sy & 7) * 8 + (sx & 7)) << 1) + 1];
+    if(palette) {
+      if(ppu.mode7_hflip == true) {
+        ppu_set_pixel(BG1, 255 - x, palette);
+      } else {
+        ppu_set_pixel(BG1, x, palette);
+      }
+    }
+    startx += x_stepx;
+    starty += y_stepx;
+  }
+}
diff --git a/bsnes/ppu/ppu_render_mode7i.cpp b/bsnes/ppu/ppu_render_mode7i.cpp
new file mode 100644
index 00000000..6fc9dffe
--- /dev/null
+++ b/bsnes/ppu/ppu_render_mode7i.cpp
@@ -0,0 +1,66 @@
+/*
+  The algorithm in this file was derived from the snes9x source code.
+  The snes9x source code is not public domain. If you wish to use this
+  code, you must abide by the terms of the snes9x license. If you do not
+  wish to abide by the snes9x licensing terms, please define the precompiler
+  variable PUBLIC_DOMAIN so that ppu_render_mode7f.cpp is used instead of
+  this file. You must also remove this file from any work that you release
+  that does not follow the snes9x license.
+  See license.txt for more info on the license of this software and snes9x.
+*/
+
+#define CLIP_10BIT_SIGNED(x) \
+  ((x) & ((1 << 10) - 1)) + (((((x) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3)
+
+#define CAST_WORDTOINT(x) \
+  (int)(((x & 0x8000)?(x | 0xffff0000):(x & 0x00007fff)))
+
+void ppu_render_line_m7(void) {
+int x;
+int step_m7a, step_m7c, m7a, m7b, m7c, m7d;
+int hoffset, voffset;
+int centerx, centery;
+int xx, yy;
+int px, py;
+int tile, palette;
+  hoffset = (CAST_WORDTOINT(ppu.m7hofs) << 7) >> 7;
+  voffset = (CAST_WORDTOINT(ppu.m7vofs) << 7) >> 7;
+
+  centerx = (CAST_WORDTOINT(ppu.m7x) << 7) >> 7;
+  centery = (CAST_WORDTOINT(ppu.m7y) << 7) >> 7;
+
+  if(ppu.mode7_vflip == true) {
+    yy = 223 - ppu.vline_pos;
+  } else {
+    yy = ppu.vline_pos;
+  }
+  yy += CLIP_10BIT_SIGNED(voffset - centery);
+
+  m7b = CAST_WORDTOINT(ppu.m7b) * yy + (centerx << 8);
+  m7d = CAST_WORDTOINT(ppu.m7d) * yy + (centery << 8);
+
+  step_m7a = CAST_WORDTOINT(ppu.m7a);
+  step_m7c = CAST_WORDTOINT(ppu.m7c);
+
+  xx = CLIP_10BIT_SIGNED(hoffset - centerx);
+
+  m7a = CAST_WORDTOINT(ppu.m7a) * xx;
+  m7c = CAST_WORDTOINT(ppu.m7c) * xx;
+
+  for(x=0;x<256;x++) {
+    px = ((m7a + m7b) >> 8) & 1023;
+    py = ((m7c + m7d) >> 8) & 1023;
+
+    tile    = ppu.vram[(((py / 8) & 127) * 128 + ((px / 8) & 127)) << 1];
+    palette = ppu.vram[((tile * 64 + (py & 7) * 8 + (px & 7)) << 1) + 1];
+
+    if(ppu.mode7_hflip == true) {
+      ppu_set_pixel(BG1, 255 - x, palette);
+    } else {
+      ppu_set_pixel(BG1, x, palette);
+    }
+
+    m7a += step_m7a;
+    m7c += step_m7c;
+  }
+}
diff --git a/bsnes/ppu/ppu_screen.cpp b/bsnes/ppu/ppu_screen.cpp
new file mode 100644
index 00000000..9b6c7990
--- /dev/null
+++ b/bsnes/ppu/ppu_screen.cpp
@@ -0,0 +1,92 @@
+/*
+  $2100 : screen brightness / enable
+  d---bbbb
+
+  d: display (0=on, 1=off)
+  b: brightness (0-15)
+*/
+extern emustate emu_state;
+
+void mmio_w2100(byte value) {
+  ppu.display_disable    = (value & 0x80)?true:false;
+  ppu.display_brightness = (value & 0x0f);
+}
+
+/*
+  $2105 : screen mode register
+  dcbapmmm
+
+  d: bg4 tile size (0=8x8, 1=16x16)
+  c: bg3 tile size (0=8x8, 1=16x16)
+  b: bg2 tile size (0=8x8, 1=16x16)
+  a: bg1 tile size (0=8x8, 1=16x16)
+  p: bg priority mode
+  m: screen mode
+*/
+void mmio_w2105(byte value) {
+  ppu.bg_tile_size[BG4] = (value & 0x80)?1:0;
+  ppu.bg_tile_size[BG3] = (value & 0x40)?1:0;
+  ppu.bg_tile_size[BG2] = (value & 0x20)?1:0;
+  ppu.bg_tile_size[BG1] = (value & 0x10)?1:0;
+  ppu.bg_priority_mode  = (value & 0x08)?1:0;
+  ppu.bg_mode           = (value & 0x07);
+  video_setsnesmode();
+}
+
+/*
+  $2106 : mosaic
+  ssssdcba
+
+  s: size (0=smallest, 15=largest)
+  d: affect bg4
+  c: affect bg3
+  b: affect bg2
+  a: affect bg1
+*/
+void mmio_w2106(byte value) {
+  ppu.mosaic_size         = (value >> 4) & 15;
+  ppu.mosaic_enabled[BG4] = (value & 0x08)?true:false;
+  ppu.mosaic_enabled[BG3] = (value & 0x04)?true:false;
+  ppu.mosaic_enabled[BG2] = (value & 0x02)?true:false;
+  ppu.mosaic_enabled[BG1] = (value & 0x01)?true:false;
+}
+
+/*
+  $212c : main screen desgination
+  $212d : sub screen designation
+  ---sdcba
+
+  s: oam enable
+  d: bg4 enable
+  c: bg3 enable
+  b: bg2 enable
+  a: bg1 enable
+*/
+void mmio_w212c(byte value) {
+  ppu.bg_enabled[OAM] = (value & 0x10)?true:false;
+  ppu.bg_enabled[BG4] = (value & 0x08)?true:false;
+  ppu.bg_enabled[BG3] = (value & 0x04)?true:false;
+  ppu.bg_enabled[BG2] = (value & 0x02)?true:false;
+  ppu.bg_enabled[BG1] = (value & 0x01)?true:false;
+}
+
+void mmio_w212d(byte value) {
+  ppu.ss_bg_enabled[OAM] = (value & 0x10)?true:false;
+  ppu.ss_bg_enabled[BG4] = (value & 0x08)?true:false;
+  ppu.ss_bg_enabled[BG3] = (value & 0x04)?true:false;
+  ppu.ss_bg_enabled[BG2] = (value & 0x02)?true:false;
+  ppu.ss_bg_enabled[BG1] = (value & 0x01)?true:false;
+}
+
+/*
+  $2133 : screen mode settings
+  ?????h?i
+
+  h: snes height (0 = 224, 1 = 240)
+  i: interlace   (0 = off, 1 = on)
+*/
+void mmio_w2133(byte value) {
+  ppu.toggle_visible_scanlines = (value & 0x04)?240:224;
+  ppu.interlace                = (value & 0x01)?true:false;
+  video_setsnesmode();
+}
diff --git a/bsnes/ppu/ppu_scroll.cpp b/bsnes/ppu/ppu_scroll.cpp
new file mode 100644
index 00000000..c5345950
--- /dev/null
+++ b/bsnes/ppu/ppu_scroll.cpp
@@ -0,0 +1,46 @@
+/*
+  $210d-$2114 : Scroll registers
+
+  210d/210e: bg1 hscroll/bg1 vscroll
+  210f/2110: bg2 hscroll/bg2 vscroll
+  2111/2112: bg3 hscroll/bg3 vscroll
+  2113/2114: bg4 hscroll/bg4 vscroll
+
+  you must write to this register twice to write the full address.
+  starting positions are 0, 0. only 11 bits of the address are used.
+*/
+void mmio_w210d(byte value) {
+  ppu.bg_hscroll_pos[BG1] = (value << 8) | (ppu.bg_hscroll_pos[BG1] >> 8);
+  ppu.m7hofs = (value << 8) | m7_latch;
+  m7_latch   = value;
+}
+
+void mmio_w210e(byte value) {
+  ppu.bg_vscroll_pos[BG1] = (value << 8) | (ppu.bg_vscroll_pos[BG1] >> 8);
+  ppu.m7vofs = (value << 8) | m7_latch;
+  m7_latch   = value;
+}
+
+void mmio_w210f(byte value) {
+  ppu.bg_hscroll_pos[BG2] = (value << 8) | (ppu.bg_hscroll_pos[BG2] >> 8);
+}
+
+void mmio_w2110(byte value) {
+  ppu.bg_vscroll_pos[BG2] = (value << 8) | (ppu.bg_vscroll_pos[BG2] >> 8);
+}
+
+void mmio_w2111(byte value) {
+  ppu.bg_hscroll_pos[BG3] = (value << 8) | (ppu.bg_hscroll_pos[BG3] >> 8);
+}
+
+void mmio_w2112(byte value) {
+  ppu.bg_vscroll_pos[BG3] = (value << 8) | (ppu.bg_vscroll_pos[BG3] >> 8);
+}
+
+void mmio_w2113(byte value) {
+  ppu.bg_hscroll_pos[BG4] = (value << 8) | (ppu.bg_hscroll_pos[BG4] >> 8);
+}
+
+void mmio_w2114(byte value) {
+  ppu.bg_vscroll_pos[BG4] = (value << 8) | (ppu.bg_vscroll_pos[BG4] >> 8);
+}
diff --git a/bsnes/ppu/ppu_timing.cpp b/bsnes/ppu/ppu_timing.cpp
new file mode 100644
index 00000000..31169975
--- /dev/null
+++ b/bsnes/ppu/ppu_timing.cpp
@@ -0,0 +1,160 @@
+/*
+  $213d : vertical latch position
+
+  returns the current scanline. must read from
+  $2137 before reading from this register.
+*/
+byte mmio_r2137(void) {
+  ppu.latch_toggle = 0;
+  ppu.latch_vpos = snes_time->vscan_pos;
+  ppu.latch_hpos = snes_time->hscan_pos;
+  return 0x00;
+}
+
+byte mmio_r213c(void) {
+word r;
+  r = ppu.latch_hpos;
+  if(ppu.latch_toggle)r >>= 8;
+  ppu.latch_toggle ^= 1;
+  return r;
+}
+
+byte mmio_r213d(void) {
+word r;
+  r = ppu.latch_vpos;
+  if(ppu.latch_toggle)r >>= 8;
+  ppu.latch_toggle ^= 1;
+  return r;
+}
+
+/*
+  $213e : ppu1 status register
+
+  trm0vvvv
+  t: time over (?)
+  r: range over (?)
+  m: master/slave mode select (?)
+  v: version # (returns 1)
+*/
+byte mmio_r213e(void) {
+  return 0x01;
+}
+
+/*
+  $213f : ppu2 status register
+  fl0mvvvv
+  f: field # (?)
+  l: external signal applied (should be 0)
+  m: ntsc/pal mode (0=ntsc, 1=pal)
+  v: version # (returns 0)
+*/
+byte mmio_r213f(void) {
+  return 0x00;
+}
+
+/*
+  $4200 : counter enable
+  n-vh---j
+
+  n: nmi enable
+  v: vertical counter enable
+  h: horizontal counter enable
+  j: automatic joypad enable
+
+  the v/h counters must be enabled to invoke IRQs. the vertical
+  counter will override the horizontal counter. in other words,
+  if both v+h are set, only vertical IRQs will be performed.
+*/
+void mmio_w4200(byte value) {
+  gx816->nmi_enabled   = (value & 0x80)?true:false;
+  ppu.vcounter_enabled = (value & 0x20)?true:false;
+  ppu.hcounter_enabled = (value & 0x10)?true:false;
+  ppu.auto_joypad_read = (value & 0x01)?true:false;
+}
+
+/*
+  $4207/$4208 : horizontal counter position
+
+  9-bit value, used to invoke horizontal IRQs
+  horizontal range: 0-339
+*/
+void mmio_w4207(byte value) {
+  ppu.hirq_pos = (ppu.hirq_pos & 0x0100) | value;
+}
+void mmio_w4208(byte value) {
+  ppu.hirq_pos = (ppu.hirq_pos & 0x00ff) | (value & 1) << 8;
+}
+
+/*
+  $4209/$420a : vertical counter position
+
+  9-bit value, used to invoke vertical IRQs
+  vertical range: 0-261
+*/
+void mmio_w4209(byte value) {
+  ppu.virq_pos = (ppu.virq_pos & 0x0100) | value;
+}
+void mmio_w420a(byte value) {
+  ppu.virq_pos = (ppu.virq_pos & 0x00ff) | (value & 1) << 8;
+}
+
+/*
+  $420d : memory speed
+  0000000x
+
+  x: 0 = SlowROM
+     1 = FastROM
+*/
+void mmio_w420d(byte value) {
+  gx816->toggle_memory_speed = (value) & 0x01;
+}
+
+/*
+  $4210 : nmi status
+  n-------
+
+  n: outside nmi (0=no, 1=yes)
+*/
+byte mmio_r4210(void) {
+byte r;
+  r = (gx816->nmi_pin ^ 1)?0x80:0x00;
+  gx816->nmi_pin = 1;
+  return r;
+}
+
+/*
+  $4211 : irq toggle
+  i?------
+
+  i: irq state (1=in irq, 0=not in irq)?
+  ?: unknown, always return 1?
+*/
+byte mmio_r4211(void) {
+byte r;
+  r = 0x40;
+  if(ppu.irq_triggered == true)r |= 0x80;
+  ppu.irq_triggered = false;
+  return r;
+}
+
+/*
+  $4212 : video status
+  vh-----j
+
+  v: vblank (0=no, 1=yes)
+  h: hblank (0=no, 1=yes)
+  j: joypad ready (for auto joypad mode)
+*/
+byte mmio_r4212(void) {
+byte r;
+  r = 0x00;
+
+//set when the SNES is updating the joypad data automatically
+  if(snes_time->vscan_pos >= (ppu.visible_scanlines + 1) && snes_time->vscan_pos <= (ppu.visible_scanlines + 3))r |= 0x01;
+
+//set when the SNES is in hblank/vblank
+  if(snes_time->hscan_pos >= 256)r |= 0x40;
+  if(snes_time->vscan_pos >= ppu.visible_scanlines)r |= 0x80;
+
+  return r;
+}
diff --git a/bsnes/ppu/ppu_vram.cpp b/bsnes/ppu/ppu_vram.cpp
new file mode 100644
index 00000000..5ce65a35
--- /dev/null
+++ b/bsnes/ppu/ppu_vram.cpp
@@ -0,0 +1,131 @@
+/*
+  $2107-$210a : bg1-4 tilemap location
+  bbbbbbss
+
+  b: location of bg tilemap - highest bit is ignored
+  s: tilemap size (00 = 32x32, 01 = 64x32, 10 = 32x64, 11 = 64x64)
+*/
+void mmio_w2107(byte value) {
+  ppu.bg_tilemap_loc[BG1]  = (value & 0x7c) << 9;
+  ppu.bg_tilemap_size[BG1] = value & 3;
+}
+void mmio_w2108(byte value) {
+  ppu.bg_tilemap_loc[BG2]  = (value & 0x7c) << 9;
+  ppu.bg_tilemap_size[BG2] = value & 3;
+}
+void mmio_w2109(byte value) {
+  ppu.bg_tilemap_loc[BG3]  = (value & 0x7c) << 9;
+  ppu.bg_tilemap_size[BG3] = value & 3;
+}
+void mmio_w210a(byte value) {
+  ppu.bg_tilemap_loc[BG4]  = (value & 0x7c) << 9;
+  ppu.bg_tilemap_size[BG4] = value & 3;
+}
+
+/*
+  $210b/$210c: bg1-4 tiledata location
+  bbbbaaaa
+
+  a: bg1/3 tiledata location (210b/210c)
+  b: bg2/4 tiledata location (210b/210c)
+*/
+void mmio_w210b(byte value) {
+  ppu.bg_tiledata_loc[BG1] = (value & 0x07) << 13;
+  ppu.bg_tiledata_loc[BG2] = (value & 0x70) <<  9;
+}
+void mmio_w210c(byte value) {
+  ppu.bg_tiledata_loc[BG3] = (value & 0x07) << 13;
+  ppu.bg_tiledata_loc[BG4] = (value & 0x70) <<  9;
+}
+
+/*
+  $2115 : vram write counter
+  i---ggrr
+
+  i: 0 = increment on $2118/$2139
+     1 = increment on $2119/$213a
+  g: graphic increment
+  r: increment rate
+     00 = increment by 2
+     01 = increment by 64
+     10 = increment by 128
+     11 = increment by 256
+*/
+void mmio_w2115(byte value) {
+if(value & 0x0c)dprintf("$2115 = %0.2x", value);
+  ppu.vram_inc_reg  = (value & 0x80)?1:0;
+  switch(value & 3) {
+  case 0x00:ppu.vram_inc_size =   1;break;
+  case 0x01:ppu.vram_inc_size =  32;break;
+  case 0x02:ppu.vram_inc_size =  64;break;
+  case 0x03:ppu.vram_inc_size = 128;break;
+  }
+}
+
+/*
+  $2116/$2117 : vram write position
+
+  15-bit value ($2116/$2117) determining position in vram to write to using $2118
+  this value is doubled to get true write position (0000-ffff)
+*/
+void mmio_w2116(byte value) {
+  ppu.vram_write_pos = ((ppu.vram_write_pos & 0xff00) | value) & 0x7fff;
+}
+void mmio_w2117(byte value) {
+  ppu.vram_write_pos = ((value << 8) | (ppu.vram_write_pos & 0xff)) & 0x7fff;
+}
+
+/*
+  $2118/$2119 : vram write
+
+  $2118/$2119 write to vram using vram_write_pos, this is then incremented based on
+  the settings of $2115 (vram_inc_size / vram_inc_reg)
+*/
+void mmio_w2118(byte value) {
+word w = ppu.vram_write_pos * 2;
+  ppu.vram[w] = value;
+  if(ppu.vram_inc_reg == 0) {
+    ppu.vram_write_pos += ppu.vram_inc_size;
+    ppu.vram_write_pos &= 0x7fff;
+  }
+  ppu_bg_tiledata_state[TILE_2BIT][(w >> 4)] = 1;
+  ppu_bg_tiledata_state[TILE_4BIT][(w >> 5)] = 1;
+  ppu_bg_tiledata_state[TILE_8BIT][(w >> 6)] = 1;
+}
+
+void mmio_w2119(byte value) {
+word w = ppu.vram_write_pos * 2 + 1;
+  ppu.vram[w] = value;
+  if(ppu.vram_inc_reg == 1) {
+    ppu.vram_write_pos += ppu.vram_inc_size;
+    ppu.vram_write_pos &= 0x7fff;
+  }
+  ppu_bg_tiledata_state[TILE_2BIT][(w >> 4)] = 1;
+  ppu_bg_tiledata_state[TILE_4BIT][(w >> 5)] = 1;
+  ppu_bg_tiledata_state[TILE_8BIT][(w >> 6)] = 1;
+}
+
+/*
+  $2139/$213a : vram read
+*/
+byte mmio_r2139(void) {
+word w = ppu.vram_write_pos * 2;
+byte r;
+  r = ppu.vram[w];
+  if(ppu.vram_inc_reg == 0) {
+    ppu.vram_write_pos += ppu.vram_inc_size;
+    ppu.vram_write_pos &= 0x7fff;
+  }
+  return r;
+}
+
+byte mmio_r213a(void) {
+word w = ppu.vram_write_pos * 2 + 1;
+byte r;
+  r = ppu.vram[w];
+  if(ppu.vram_inc_reg == 1) {
+    ppu.vram_write_pos += ppu.vram_inc_size;
+    ppu.vram_write_pos &= 0x7fff;
+  }
+  return r;
+}
diff --git a/bsnes/ppu/ppu_window.cpp b/bsnes/ppu/ppu_window.cpp
new file mode 100644
index 00000000..a7a012cf
--- /dev/null
+++ b/bsnes/ppu/ppu_window.cpp
@@ -0,0 +1,121 @@
+/*
+  $2123/$2124/$2125 : window mask settings
+
+  $2123:
+    hgfedcba
+    (bg2)
+    h: enable window 2
+    g: clip window 2 (0=in, 1=out)
+    f: enable window 1
+    e: clip window 1 (0=in, 1=out)
+    (bg1)
+    h: enable window 2
+    g: clip window 2 (0=in, 1=out)
+    f: enable window 1
+    e: clip window 1 (0=in, 1=out)
+  $2124: same as $2123, but with bg4/3
+  $2125:
+    hgfedcba
+    h: enable color window 2
+    g: clip window 2 (0=in, 1=out)
+    f: enable color window 1
+    e: clip window 1 (0=in, 1=out)
+    d: enable OAM window 2
+    c: clip window 2 (0=in, 1=out)
+    b: enable OAM window 1
+    a: clip window 1 (0=in, 1=out)
+*/
+void mmio_w2123(byte value) {
+  ppu.bg_window2_enabled [BG2] = (value & 0x80)?true:false;
+  ppu.bg_window2_clipmode[BG2] = (value & 0x40)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.bg_window1_enabled [BG2] = (value & 0x20)?true:false;
+  ppu.bg_window1_clipmode[BG2] = (value & 0x10)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.bg_window2_enabled [BG1] = (value & 0x08)?true:false;
+  ppu.bg_window2_clipmode[BG1] = (value & 0x04)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.bg_window1_enabled [BG1] = (value & 0x02)?true:false;
+  ppu.bg_window1_clipmode[BG1] = (value & 0x01)?CLIPMODE_OUT:CLIPMODE_IN;
+}
+
+void mmio_w2124(byte value) {
+  ppu.bg_window2_enabled [BG4] = (value & 0x80)?true:false;
+  ppu.bg_window2_clipmode[BG4] = (value & 0x40)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.bg_window1_enabled [BG4] = (value & 0x20)?true:false;
+  ppu.bg_window1_clipmode[BG4] = (value & 0x10)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.bg_window2_enabled [BG3] = (value & 0x08)?true:false;
+  ppu.bg_window2_clipmode[BG3] = (value & 0x04)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.bg_window1_enabled [BG3] = (value & 0x02)?true:false;
+  ppu.bg_window1_clipmode[BG3] = (value & 0x01)?CLIPMODE_OUT:CLIPMODE_IN;
+}
+
+void mmio_w2125(byte value) {
+  ppu.color_window2_enabled  = (value & 0x80)?true:false;
+  ppu.color_window2_clipmode = (value & 0x40)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.color_window1_enabled  = (value & 0x20)?true:false;
+  ppu.color_window1_clipmode = (value & 0x10)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.bg_window2_enabled [OAM] = (value & 0x08)?true:false;
+  ppu.bg_window2_clipmode[OAM] = (value & 0x04)?CLIPMODE_OUT:CLIPMODE_IN;
+  ppu.bg_window1_enabled [OAM] = (value & 0x02)?true:false;
+  ppu.bg_window1_clipmode[OAM] = (value & 0x01)?CLIPMODE_OUT:CLIPMODE_IN;
+}
+
+/*
+ $2126-$2129 : window position settings
+
+  $2126: window 1 left
+  $2127: window 1 right
+  $2128: window 2 left
+  $2129: window 2 right
+*/
+void mmio_w2126(byte value) { ppu.window1_left  = value; }
+void mmio_w2127(byte value) { ppu.window1_right = value; }
+void mmio_w2128(byte value) { ppu.window2_left  = value; }
+void mmio_w2129(byte value) { ppu.window2_right = value; }
+
+/*
+  $212a/$212b : window mask settings
+  $212a: ddccbbaa (d=bg4, c=bg3, b=bg2, a=bg1)
+  $212b: ----ccss (c=color add/sub, s=oam)
+
+  00=or
+  01=and
+  10=xor
+  11=xnor
+*/
+void mmio_w212a(byte value) {
+  ppu.bg_window_mask[BG4] = (value >> 6) & 3;
+  ppu.bg_window_mask[BG3] = (value >> 4) & 3;
+  ppu.bg_window_mask[BG2] = (value >> 2) & 3;
+  ppu.bg_window_mask[BG1] = (value     ) & 3;
+}
+
+void mmio_w212b(byte value) {
+  ppu.color_window_mask   = (value >> 2) & 3;
+  ppu.bg_window_mask[OAM] = (value     ) & 3;
+}
+
+/*
+  $212e/$212f : main window designation
+
+  ---odcba
+
+  o: OAM enable
+  d: BG4 enable
+  c: BG3 enable
+  b: BG2 enable
+  a: BG1 enable
+*/
+void mmio_w212e(byte value) {
+  ppu.bg_windowing_enabled[OAM] = (value & 0x10)?true:false;
+  ppu.bg_windowing_enabled[BG4] = (value & 0x08)?true:false;
+  ppu.bg_windowing_enabled[BG3] = (value & 0x04)?true:false;
+  ppu.bg_windowing_enabled[BG2] = (value & 0x02)?true:false;
+  ppu.bg_windowing_enabled[BG1] = (value & 0x01)?true:false;
+}
+
+void mmio_w212f(byte value) {
+  ppu.ss_bg_windowing_enabled[OAM] = (value & 0x10)?true:false;
+  ppu.ss_bg_windowing_enabled[BG4] = (value & 0x08)?true:false;
+  ppu.ss_bg_windowing_enabled[BG3] = (value & 0x04)?true:false;
+  ppu.ss_bg_windowing_enabled[BG2] = (value & 0x02)?true:false;
+  ppu.ss_bg_windowing_enabled[BG1] = (value & 0x01)?true:false;
+}
diff --git a/bsnes/ppu/ppu_wram.cpp b/bsnes/ppu/ppu_wram.cpp
new file mode 100644
index 00000000..87f59f23
--- /dev/null
+++ b/bsnes/ppu/ppu_wram.cpp
@@ -0,0 +1,24 @@
+/*
+  $2180 : wram write
+
+  write byte to wram write pointer ($2181-$2183), then increment pointer.
+  always stays within 7e0000-7fffff, high 7 bits of 24-bit offset ignored.
+*/
+void mmio_w2180(byte value) {
+  gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, 0x7e0000 | ppu.wram_write_pos, value);
+  ppu.wram_write_pos++;
+  ppu.wram_write_pos &= 0x01ffff;
+}
+
+/*
+  $2181-$2183: wram write pointer set
+*/
+void mmio_w2181(byte value) {
+  ppu.wram_write_pos = ((ppu.wram_write_pos & 0xffff00) | value) & 0x01ffff;
+}
+void mmio_w2182(byte value) {
+  ppu.wram_write_pos = ((ppu.wram_write_pos & 0xff00ff) | (value << 8)) & 0x01ffff;
+}
+void mmio_w2183(byte value) {
+  ppu.wram_write_pos = ((ppu.wram_write_pos & 0x00ffff) | (value << 16)) & 0x01ffff;
+}
diff --git a/bsnes/qc.bat b/bsnes/qc.bat
new file mode 100644
index 00000000..76e3786d
--- /dev/null
+++ b/bsnes/qc.bat
@@ -0,0 +1,3 @@
+del c:\root\bsnes_testrom\bsnes.exe
+copy bsnes.exe c:\root\bsnes_testrom\bsnes.exe
+@pause
\ No newline at end of file
diff --git a/bsnes/timing.obj b/bsnes/timing.obj
new file mode 100644
index 0000000000000000000000000000000000000000..450d6b3d0804783094608f43206c4e62ad2cfdd1
GIT binary patch
literal 3162
zcma)-?`vCC7{|{|(j@(rAGQ;z%A$sfFO1#dY86Iq>L#13+ES=<jwWq>lt_Ps<fff{
zW6;vkU6kNIpu)htQU@Cp1(&ocmBDbu7m6?xLAQ!8^hHWU7r)QB_x9eK+jM>4p8K40
zzUT8i=iGD79TK|P^^;el-7d!ZnPQ=2E|rkxQ)-p<!g<=R)zo*JkA)`ld1I@?SW*2V
z>nn$()H%t}=YxNyffw)%$3w}~WML}!f+i*18_+GPS^@PFKHp#?FMy6EXfCP=*r031
zTZLvr)ivYwVf-dEwiY<By?FOS)2r(C;`Koj-v>{EX6YWh0CIW{nokV6rt^hn!=T%B
z{lME)HE_8#<NXbt&8cXb%{Pwj4rrzgx@Nq2XqFAS-SVS-P*OEY<mTV^L+C!c2Tug#
z^L_IEfvyc_gG`(6lgU(iqA)E@XC|K;Iyv}!z}WE0(6N`JFC8BZ$d&N7EAI5l2?rkM
zdWi^LDh$>J-^Ju(L5I9ix#KI=A`9c`qxFLe?o~Is)*LK-lm&8aXp4B4@1O~FG3P-&
z3Qfn3W{_)Q-sP_qP2BtT7u>7Yz2`5((|E<2nCmRo-qIr!YsFl?Si80`yGvvzMV`+$
zjY|Eo`BC)8c~%B4+KRbn(O+K(e}oL!1@VFE4-b}uci$<yF|%T=oa-sp>I(<tPTn0g
zb+6I~f~-_3{R)rvfRowq2^5b;JWL-1roQ;<x)_f&CjTY7N8}r~so(qQv7lS_*f&-@
z;|dYb9i!0-(?eQ3-FO&#gqNJo0~|oz#R$yP4VTk$)F<B<-a7;xD}~+#Pp9`b(0e!?
zJHd?zyD;6f5T#ZV;~|xS`-x|GP-8e`|GN(H=Fj%;R{WL;)1dp*k$f2ZARg>Pnj#y$
za5mV1BrXd}KS~_~FZL8%NUKBq!$Gg=x=nHw7d=c8#Ok_(3nXWCu*+8vMA@T+rG<Wd
zO-XrYol7OUNA<5aLcw5Yr4IH49`!8v^~9-%uQ%RWwjr(@lMk&{%H{H_+rP<c;mykJ
zwrfr(wzuVPz8uD~$I>e!j_~Gob-c1=gO4L<G9n+QLNT607`}^z(wXU$+I+Xp*pwh;
zW-_x=PbsfZBAaDmVs0iI$|RkSwX-@jc4qu*Ql@r6`^N6W-}6nvOn*!YXcyF9ks3{V
zX|1HOG2{P^euZ{{R*|gp_ZUKH>+-15h+G0R%J4TOo-&HGbC=FW?TmJ&kxX^F5P*Q9
z{&b~(Nhc4Wg{*~>$xBk9nmHDoTRj#@S}d{XLbVHhC@I$C?3ryn)*@QST$WkTm1rir
zEMz(%I{BBY6IXQd2ZV*STF7({o5`&fay!=qP-2PLmh1h0b@EqeA#1mg>54X!+bv|;
z-&lE+WS81k|I^7^N+Zrd<2R+-%1rLGkm<g$3vrZ`^YxD}-qOilYJzz!WZGS3ve!cP
z?`Vi|{??zePClZN{T4FaJ7%)qLZ*AtE{G_}sy8b*iYk!3raD~~GTqr`au+8rVnifA
zo65&<cvGSn9*&OfRCA&jWsyjqv0)^7Ts(b-MW#|xY-S=arE;;vn~CXEEHPJ@mBa?=
zsZ%0p&kY>vSJ+eiN4O8}L^2smWDBt@AD?d=dYTW_MEU)QW}1mis7x~zrK-hiDl(z=
SA{Da92`R;wHD{R{R`7qD{x!+~

literal 0
HcmV?d00001

diff --git a/bsnes/timing/timing.cpp b/bsnes/timing/timing.cpp
new file mode 100644
index 00000000..60449829
--- /dev/null
+++ b/bsnes/timing/timing.cpp
@@ -0,0 +1,103 @@
+#include "../base.h"
+#include "../cpu/g65816.h"
+extern g65816 *gx816;
+#include "timing.h"
+
+snes_timer::snes_timer() {
+  master_cycles = 0;
+  vscan_pos     = 0;
+  hscan_pos     = 0;
+}
+
+#define MEMSPEED_FAST   6
+#define MEMSPEED_SLOW   8
+#define MEMSPEED_XSLOW 12
+ulong snes_timer::get_master_cycle_count(ulong offset) {
+byte db;
+word addr;
+  db   = (offset >> 16) & 0xff;
+  addr = (offset) & 0xffff;
+  if(db >= 0x00 && db <= 0x3f) {
+    if     (addr >= 0x0000 && addr <= 0x1fff)return MEMSPEED_SLOW;
+    else if(addr >= 0x2000 && addr <= 0x3fff)return MEMSPEED_FAST;
+    else if(addr >= 0x4000 && addr <= 0x41ff)return MEMSPEED_XSLOW;
+    else if(addr >= 0x4200 && addr <= 0x5fff)return MEMSPEED_FAST;
+    else if(addr >= 0x6000 && addr <= 0xffff)return MEMSPEED_SLOW;
+  } else if(db >= 0x40 && db <= 0x7f) {
+    return MEMSPEED_SLOW;
+  } else if(db >= 0x80 && db <= 0xbf) {
+    if     (addr >= 0x0000 && addr <= 0x1fff)return MEMSPEED_SLOW;
+    else if(addr >= 0x2000 && addr <= 0x3fff)return MEMSPEED_FAST;
+    else if(addr >= 0x4000 && addr <= 0x41ff)return MEMSPEED_XSLOW;
+    else if(addr >= 0x4200 && addr <= 0x5fff)return MEMSPEED_FAST;
+    else if(addr >= 0x6000 && addr <= 0x7fff)return MEMSPEED_SLOW;
+    else if(addr >= 0x8000 && addr <= 0xffff) {
+      if(gx816->memory_speed == MEMSPEED_SLOWROM) {
+        return MEMSPEED_SLOW;
+      } else { //gx816->memory_speed == MEMSPEED_FASTROM
+        return MEMSPEED_FAST;
+      }
+    }
+  } else if(db >= 0xc0 && db <= 0xff) {
+    if(gx816->memory_speed == MEMSPEED_SLOWROM) {
+      return MEMSPEED_SLOW;
+    } else { //gx816->memory_speed == MEMSPEED_FASTROM
+      return MEMSPEED_FAST;
+    }
+  }
+  return MEMSPEED_FAST; //this should never be hit
+}
+
+/*
+  vpa = 1, vda = 1 -> add_cpu_pcycles (opcode fetch)
+  vpa = 1, vda = 0 -> add_cpu_pcycles (operand fetch)
+  vpa = 0, vda = 1 -> add_cpu_dcycles (memory fetch)
+  vpa = 0, vda = 0 -> add_cpu_icycles (internal operation)
+*/
+void snes_timer::add_cpu_pcycles(ulong n) {
+ulong speed;
+  speed = get_master_cycle_count(gx816->regs.pc);
+  master_cycles += n * speed;
+}
+
+void snes_timer::add_cpu_scycles(ulong n) {
+ulong speed;
+  speed = get_master_cycle_count(gx816->regs.s);
+  master_cycles += n * speed;
+}
+
+void snes_timer::add_cpu_mcycles(ulong n, ulong addr) {
+ulong speed;
+  speed = get_master_cycle_count(addr);
+  master_cycles += n * speed;
+}
+
+void snes_timer::add_cpu_icycles(ulong n) {
+  master_cycles += n * MEMSPEED_FAST;
+}
+
+void snes_timer::add_cpu_icycles(ulong n, ulong flags) {
+  if(flags & TIMING_BANKCROSS) {
+    if(gx816->index_bank_crossed == true)n++;
+  }
+//regs.dl != 0x00
+  if(flags & TIMING_CONDITION2) {
+    if((gx816->regs.d & 0xff) != 0x00)n++;
+  }
+//add 1 cycle for indexing across page boundaries, or write, or x=0
+  if(flags & TIMING_CONDITION4) {
+    if(gx816->index_bank_crossed == true || !(gx816->regs.p & PF_X))n++;
+  }
+  master_cycles += n * MEMSPEED_FAST;
+}
+
+void snes_timer::add_cpu_cycles(ulong n) {
+  master_cycles += n;
+}
+
+void snes_timer::update_timer(void) {
+  vscan_pos = (master_cycles / CYCLES_PER_SCANLINE) % 262;
+  hscan_pos = (master_cycles % CYCLES_PER_SCANLINE) / 4;
+}
+
+snes_timer *snes_time;
diff --git a/bsnes/timing/timing.h b/bsnes/timing/timing.h
new file mode 100644
index 00000000..b3dfb6d7
--- /dev/null
+++ b/bsnes/timing/timing.h
@@ -0,0 +1,23 @@
+#define CYCLES_PER_SCANLINE  1360
+#define WRAM_REFRESH_DOT_POS  132
+
+#define TIMING_NONE       0x00
+#define TIMING_BANKCROSS  0x01
+#define TIMING_REGD       0x02
+#define TIMING_CONDITION2 0x02
+#define TIMING_CONDITION4 0x04
+
+class snes_timer {
+public:
+ulong master_cycles;
+word vscan_pos, hscan_pos;
+  ulong get_master_cycle_count(ulong offset);
+  void  add_cpu_pcycles(ulong n);
+  void  add_cpu_scycles(ulong n);
+  void  add_cpu_mcycles(ulong n, ulong addr);
+  void  add_cpu_icycles(ulong n);
+  void  add_cpu_icycles(ulong n, ulong flags);
+  void  add_cpu_cycles(ulong n);
+  void  update_timer(void);
+  snes_timer();
+};
diff --git a/bsnes/win/gui.cpp b/bsnes/win/gui.cpp
new file mode 100644
index 00000000..7d0f8f7e
--- /dev/null
+++ b/bsnes/win/gui.cpp
@@ -0,0 +1,434 @@
+#include "../base.h"
+#include "../timing/timing.h"
+extern snes_timer *snes_time;
+#include "../cpu/g65816.h"
+extern g65816 *gx816;
+extern emustate emu_state;
+extern debugstate debugger;
+extern videostate render;
+extern ppustate ppu;
+#include <windows.h>
+
+#define BSNES_TITLE "bsnes v0.0.002 ir9"
+
+enum {
+  MENU_FILE_LOAD = 100,
+  MENU_FILE_RESET,
+  MENU_FILE_EXIT,
+  MENU_SETTINGS_VIDEOMODE_512x448w,
+  MENU_SETTINGS_VIDEOMODE_640x480f,
+  MENU_SETTINGS_FRAMESKIP_OFF,
+  MENU_SETTINGS_FRAMESKIP_1,
+  MENU_SETTINGS_FRAMESKIP_2,
+  MENU_SETTINGS_FRAMESKIP_3,
+  MENU_SETTINGS_FRAMESKIP_4,
+  MENU_SETTINGS_FRAMESKIP_5,
+  MENU_SETTINGS_FRAMESKIP_6,
+  MENU_SETTINGS_FRAMESKIP_7,
+  MENU_SETTINGS_FRAMESKIP_8,
+  MENU_SETTINGS_FRAMESKIP_9,
+  MENU_SETTINGS_DEBUGGER,
+  MENU_HELP_ABOUT
+};
+
+HWND  hwndMain = 0;
+HMENU hmenuMain;
+HFONT hFontFixed, hFont;
+
+extern joypad_state joypad1;
+
+#define KEY_UP    VK_UP
+#define KEY_DOWN  VK_DOWN
+#define KEY_LEFT  VK_LEFT
+#define KEY_RIGHT VK_RIGHT
+#define KEY_SHIFT VK_RSHIFT
+#define KEY_ENTER VK_RETURN
+#define KEY_A     'A'
+#define KEY_S     'S'
+#define KEY_D     'D'
+#define KEY_Z     'Z'
+#define KEY_X     'X'
+#define KEY_C     'C'
+
+#define KeyState(key) ((GetAsyncKeyState(key) & 0x8000)?1:0)
+
+void UpdateJoypad(void) {
+  joypad1.up     = KeyState(KEY_UP   );
+  joypad1.down   = KeyState(KEY_DOWN );
+  joypad1.left   = KeyState(KEY_LEFT );
+  joypad1.right  = KeyState(KEY_RIGHT);
+  joypad1.select = KeyState(KEY_SHIFT);
+  joypad1.start  = KeyState(KEY_ENTER);
+  joypad1.y      = KeyState(KEY_A    );
+  joypad1.b      = KeyState(KEY_Z    );
+  joypad1.x      = KeyState(KEY_S    );
+  joypad1.a      = KeyState(KEY_X    );
+  joypad1.l      = KeyState(KEY_D    );
+  joypad1.r      = KeyState(KEY_C    );
+}
+
+void alert(char *s, ...) {
+char str[4096];
+va_list args;
+  va_start(args, s);
+  vsprintf(str, s, args);
+  va_end(args);
+  MessageBox(0, str, "bsnes", MB_OK);
+}
+
+void FixWindowSize(HWND hwnd, ulong width, ulong height, ulong px = null, ulong py = null) {
+RECT rc;
+ulong x, y, wx, wy;
+  ShowWindow(hwnd, SW_HIDE);
+  SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOZORDER);
+  GetClientRect(hwnd, &rc);
+  x = width + width - (rc.right - rc.left);
+  y = height + height - (rc.bottom - rc.top);
+  wx = (GetSystemMetrics(SM_CXSCREEN) - x) / 2;
+  wy = (GetSystemMetrics(SM_CYSCREEN) - y) / 2;
+  if(px == null || py == null) {
+    SetWindowPos(hwnd, 0, wx, wy, x, y, SWP_NOZORDER);
+  } else {
+    SetWindowPos(hwnd, 0, px, py, x, y, SWP_NOZORDER);
+  }
+}
+
+HBRUSH black_brush;
+
+long __stdcall wndprocMain(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
+
+void RegisterMainWindow() {
+WNDCLASS wc;
+  wc.cbClsExtra = 0;
+  wc.cbWndExtra = 0;
+  wc.hbrBackground = black_brush;
+  wc.hCursor       = LoadCursor(0, IDC_ARROW);
+  wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
+  wc.hInstance     = GetModuleHandle(0);
+  wc.lpfnWndProc   = wndprocMain;
+  wc.lpszClassName = "bsnes";
+  wc.lpszMenuName  = 0;
+  wc.style         = CS_HREDRAW | CS_VREDRAW;
+  RegisterClass(&wc);
+}
+
+void CreateMainMenu(void) {
+HMENU hsubmenu, hbranchmenu;
+  hmenuMain = CreateMenu();
+
+  hsubmenu = CreatePopupMenu();
+  AppendMenu(hsubmenu, MF_STRING, MENU_FILE_LOAD,  "&Load ROM");
+  AppendMenu(hsubmenu, MF_STRING, MENU_FILE_RESET, "&Reset");
+  AppendMenu(hsubmenu, MF_SEPARATOR, 0, "");
+  AppendMenu(hsubmenu, MF_STRING, MENU_FILE_EXIT, "E&xit");
+  AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&File");
+
+  hsubmenu = CreatePopupMenu();
+
+  hbranchmenu = CreatePopupMenu();
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_512x448w, "512x448 Windowed");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_640x480f, "640x480 Fullscreen");
+  AppendMenu(hsubmenu, MF_STRING | MF_POPUP, (unsigned int)hbranchmenu, "&Video Mode");
+
+  hbranchmenu = CreatePopupMenu();
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_OFF, "Off");
+  AppendMenu(hbranchmenu, MF_SEPARATOR, 0, "");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_1,     "1");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_2,     "2");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_3,     "3");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_4,     "4");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_5,     "5");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_6,     "6");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_7,     "7");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_8,     "8");
+  AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_9,     "9");
+  AppendMenu(hsubmenu, MF_STRING | MF_POPUP, (unsigned int)hbranchmenu, "&Frameskip");
+
+  AppendMenu(hsubmenu, MF_SEPARATOR, 0, "");
+  AppendMenu(hsubmenu, MF_STRING | (debug_get_state() == DEBUGMODE_WAIT)?MF_CHECKED:MF_UNCHECKED, MENU_SETTINGS_DEBUGGER, "&Debug Mode");
+  AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Settings");
+
+  hsubmenu = CreatePopupMenu();
+  AppendMenu(hsubmenu, MF_STRING, MENU_HELP_ABOUT, "&About");
+  AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Help");
+
+  CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_512x448w, MF_CHECKED);
+  CheckMenuItem(hmenuMain, MENU_SETTINGS_FRAMESKIP_OFF + render.frame_skip, MF_CHECKED);
+}
+
+void CreateMainWindow(void) {
+  hwndMain = CreateWindow("bsnes", BSNES_TITLE, WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
+    0, 0, 640, 480, 0, 0, GetModuleHandle(0), 0);
+  CreateMainMenu();
+}
+
+void SetMainWindowPos(bool update_style) {
+  if(render.fullscreen == true) {
+    if(update_style == true) {
+      SetWindowLong(hwndMain, GWL_STYLE,   WS_POPUP);
+      SetWindowLong(hwndMain, GWL_EXSTYLE, WS_EX_TOPMOST);
+      SetWindowPos(hwndMain, HWND_TOPMOST, 0, 0, 640, 480, 0);
+    }
+    if(render.show_menu == true) {
+      ShowCursor(TRUE);
+    } else {
+      ShowCursor(FALSE);
+    }
+  } else {
+    if(update_style == true) {
+      SetWindowLong(hwndMain, GWL_STYLE,   WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
+      SetWindowLong(hwndMain, GWL_EXSTYLE, 0);
+    }
+    FixWindowSize(hwndMain, render.width, render.height);
+  }
+}
+
+void UpdateMainWindowStyle(bool update_style) {
+  if(render.fullscreen == false) {
+    ShowWindow(hwndMain, SW_HIDE);
+  }
+
+  if(render.show_menu == true) {
+    SetMenu(hwndMain, hmenuMain);
+    SetMainWindowPos(update_style);
+  } else {
+    SetMenu(hwndMain, 0);
+    SetMainWindowPos(update_style);
+  }
+
+  if(render.fullscreen == false) {
+    ShowWindow(hwndMain, SW_NORMAL);
+  }
+}
+
+HWND NewWindow(WNDPROC wndproc, char *classname, char *title, ulong color, ulong width, ulong height) {
+WNDCLASS wc;
+HWND hwnd;
+  wc.cbClsExtra = 0;
+  wc.cbWndExtra = 0;
+  wc.hbrBackground = (color == null)?(HBRUSH)(COLOR_WINDOW):black_brush;
+  wc.hCursor       = LoadCursor(0, IDC_ARROW);
+  wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
+  wc.hInstance     = GetModuleHandle(0);
+  wc.lpfnWndProc   = wndproc;
+  wc.lpszClassName = classname;
+  wc.lpszMenuName  = 0;
+  wc.style         = CS_HREDRAW | CS_VREDRAW;
+  RegisterClass(&wc);
+
+  hwnd = CreateWindow(classname, title, WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
+    0, 0, width, height, 0, 0, wc.hInstance, 0);
+  return hwnd;
+}
+
+#include "render.cpp"
+
+bool GUIOpenFile(char *fn) {
+OPENFILENAME ofn;
+  memset(&ofn, 0, sizeof(ofn));
+
+  ofn.lStructSize = sizeof(ofn);
+  ofn.hwndOwner = hwndMain;
+  ofn.lpstrFilter = "SNES ROM Images (*.smc;*.swc;*.fig;*.ufo;*.gd3;*.078)\0*.smc;*.swc;*.fig;*.ufo;*.gd3;*.078\0All Files (*.*)\0*.*\0";
+  ofn.lpstrFile = fn;
+  ofn.nMaxFile = MAX_PATH;
+  ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
+  ofn.lpstrDefExt = "smc";
+
+  if(GetOpenFileName(&ofn)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+void EnableDebugger(byte first_time);
+void DisableDebugger(void);
+
+long __stdcall wndprocMain(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
+char fn[MAX_PATH];
+bool result;
+  switch(msg) {
+  case WM_DESTROY:
+    PostQuitMessage(0);
+    break;
+  case WM_PAINT:
+    UpdateDisplay_NoRender();
+    break;
+  case WM_KEYDOWN:
+    switch(wparam) {
+    case VK_ESCAPE:
+      if(render.show_menu == true) {
+        render.show_menu = false;
+      } else {
+        render.show_menu = true;
+      }
+      UpdateMainWindowStyle(false);
+      break;
+    }
+    break;
+  case WM_COMMAND:
+    switch(LOWORD(wparam)) {
+    case MENU_FILE_LOAD:
+      strcpy(fn, "");
+      result = GUIOpenFile(fn);
+      if(result == true) {
+        strcpy(emu_state.rom_name, fn);
+        fn[strlen(fn) - 4] = 0;
+        strcat(fn, ".srm");
+        strcpy(emu_state.sram_name, fn);
+        gx816->PowerOn(0);
+        gx816->LoadROM();
+        if(debug_get_state() == DEBUGMODE_NOROM) {
+          debug_set_state(DEBUGMODE_DISABLED);
+        }
+      }
+      break;
+    case MENU_FILE_RESET:
+      gx816->Reset();
+      break;
+    case MENU_FILE_EXIT:
+      PostQuitMessage(0);
+      break;
+    case MENU_SETTINGS_VIDEOMODE_512x448w:
+      video_setmode(false, 512, 448);
+      CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_512x448w, MF_CHECKED);
+      CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_640x480f, MF_UNCHECKED);
+      break;
+    case MENU_SETTINGS_VIDEOMODE_640x480f:
+      video_setmode(true, 512, 448);
+      CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_512x448w, MF_UNCHECKED);
+      CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_640x480f, MF_CHECKED);
+      break;
+    case MENU_SETTINGS_FRAMESKIP_OFF:
+    case MENU_SETTINGS_FRAMESKIP_1:
+    case MENU_SETTINGS_FRAMESKIP_2:
+    case MENU_SETTINGS_FRAMESKIP_3:
+    case MENU_SETTINGS_FRAMESKIP_4:
+    case MENU_SETTINGS_FRAMESKIP_5:
+    case MENU_SETTINGS_FRAMESKIP_6:
+    case MENU_SETTINGS_FRAMESKIP_7:
+    case MENU_SETTINGS_FRAMESKIP_8:
+    case MENU_SETTINGS_FRAMESKIP_9:
+      CheckMenuItem(hmenuMain, MENU_SETTINGS_FRAMESKIP_OFF + render.frame_skip, MF_UNCHECKED);
+      render.frame_skip  = LOWORD(wparam) - MENU_SETTINGS_FRAMESKIP_OFF;
+      render.frame_count = 0;
+      CheckMenuItem(hmenuMain, MENU_SETTINGS_FRAMESKIP_OFF + render.frame_skip, MF_CHECKED);
+      break;
+    case MENU_SETTINGS_DEBUGGER:
+      if(debug_get_state() == DEBUGMODE_NOROM)break;
+
+      if(debug_get_state() == DEBUGMODE_DISABLED) {
+        CheckMenuItem(hmenuMain, MENU_SETTINGS_DEBUGGER, MF_CHECKED);
+        EnableDebugger(0);
+      } else {
+        CheckMenuItem(hmenuMain, MENU_SETTINGS_DEBUGGER, MF_UNCHECKED);
+        DisableDebugger();
+      }
+      break;
+    case MENU_HELP_ABOUT:
+      MessageBox(hwndMain, "bsnes -- written by byuu", "About", MB_OK);
+      break;
+    }
+    break;
+  }
+
+  return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+void CreateFonts(void) {
+HDC hdc;
+long height;
+  hdc = GetDC(0);
+  height = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+  ReleaseDC(0, hdc);
+  hFontFixed = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New");
+
+  hdc = GetDC(0);
+  height = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+  ReleaseDC(0, hdc);
+  hFont      = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Tahoma");
+}
+
+#include "gui_cpu.cpp"
+#include "gui_mem.cpp"
+#include "gui_bp.cpp"
+#include "gui_bgtoggle.cpp"
+
+void EnableDebugger(byte first_time) {
+  debug_set_state(DEBUGMODE_WAIT);
+
+  hwndDCPU = NewWindow(wndprocDCPU, "bsnes_cpu", "g65816 cpu debugger", null, DCPU_WIDTH, DCPU_HEIGHT);
+  CreateDCPU();
+  FixWindowSize(hwndDCPU, DCPU_WIDTH, DCPU_HEIGHT, 0, 1024 - 320);
+
+  hwndDMEM = NewWindow(wndprocDMEM, "bsnes_mem", "g65816 memory editor -- snes memory mode", null, 495, 238);
+  CreateDMEM();
+  FixWindowSize(hwndDMEM, 495, 238, 316, 441);
+
+  hwndDBP = NewWindow(wndprocDBP, "bsnes_bp", "g65816 breakpoint editor", null, 310, 238);
+  CreateDBP();
+  FixWindowSize(hwndDBP, 310, 238, 0, 441);
+
+  hwndDBGToggle = NewWindow(wndprocDBGToggle, "bsnes_bgtoggle", "ppu bg toggle", null, 275, 90);
+  CreateDBGToggle();
+  FixWindowSize(hwndDBGToggle, 275, 90, 0, 326);
+
+  FixWindowSize(hwndMain, 256, 224, 681, 1024 - 320);
+
+  ShowWindow(hwndDCPU,      SW_NORMAL);
+  ShowWindow(hwndDMEM,      SW_NORMAL);
+  ShowWindow(hwndDBP,       SW_NORMAL);
+  ShowWindow(hwndDBGToggle, SW_NORMAL);
+  ShowWindow(hwndMain,      SW_NORMAL);
+
+  if(first_time == 0) {
+    debug_refresh_mem();
+    debug_refresh_bp();
+    debug_update_cycles();
+    dprintf("* Debugger Enabled");
+    UpdateDisplay();
+  }
+}
+
+void DisableDebugger(void) {
+  debug_set_state(DEBUGMODE_DISABLED);
+
+  DestroyWindow(hwndDCPU);
+  DestroyWindow(hwndDBP);
+  DestroyWindow(hwndDMEM);
+  DestroyWindow(hwndDBGToggle);
+}
+
+void __winmain(void) {
+MSG msg;
+  CreateFonts();
+  black_brush = CreateSolidBrush(RGB(0, 0, 0));
+  RegisterMainWindow();
+  CreateMainWindow();
+  UpdateMainWindowStyle(false);
+
+  if(debug_get_state() == DEBUGMODE_WAIT) {
+    EnableDebugger(1);
+  }
+  video_setmode(render.fullscreen, render.width, render.height);
+
+  InitDisplay();
+  CreateColorTable();
+  SelectRenderer();
+
+  InitSNES();
+
+  UpdateDisplay();
+  UpdateDisplay();
+
+  while(1) {
+    if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
+      if(msg.message == WM_QUIT)break;
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+    } else {
+      RunSNES();
+    }
+  }
+}
diff --git a/bsnes/win/gui_bgtoggle.cpp b/bsnes/win/gui_bgtoggle.cpp
new file mode 100644
index 00000000..40a05344
--- /dev/null
+++ b/bsnes/win/gui_bgtoggle.cpp
@@ -0,0 +1,149 @@
+#define DBGTOGGLE_BG1ENABLE  100
+#define DBGTOGGLE_BG1ENABLE0 101
+#define DBGTOGGLE_BG1ENABLE1 102
+#define DBGTOGGLE_BG2ENABLE  103
+#define DBGTOGGLE_BG2ENABLE0 104
+#define DBGTOGGLE_BG2ENABLE1 105
+#define DBGTOGGLE_BG3ENABLE  106
+#define DBGTOGGLE_BG3ENABLE0 107
+#define DBGTOGGLE_BG3ENABLE1 108
+#define DBGTOGGLE_BG4ENABLE  109
+#define DBGTOGGLE_BG4ENABLE0 110
+#define DBGTOGGLE_BG4ENABLE1 111
+#define DBGTOGGLE_OAMENABLE  112
+#define DBGTOGGLE_OAMENABLE0 113
+#define DBGTOGGLE_OAMENABLE1 114
+#define DBGTOGGLE_OAMENABLE2 115
+#define DBGTOGGLE_OAMENABLE3 116
+
+#define BGTOGGLE_CLICK(src, val)                                       \
+  case src:                                                            \
+    state = SendDlgItemMessage(hwndDBGToggle, src, BM_GETCHECK, 0, 0); \
+    if(state == 0) {                                                   \
+      val = true;                                                      \
+      SendDlgItemMessage(hwndDBGToggle, src, BM_SETCHECK, 1, 0);       \
+    } else {                                                           \
+      val = false;                                                     \
+      SendDlgItemMessage(hwndDBGToggle, src, BM_SETCHECK, 0, 0);       \
+    }                                                                  \
+    break
+
+HWND hwndDBGToggle;
+
+long __stdcall wndprocDBGToggle(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
+int state;
+  if(msg == WM_DESTROY || msg == WM_CLOSE)return 0;
+  if(msg == WM_COMMAND) {
+    if(HIWORD(wparam) == BN_CLICKED) {
+      switch(LOWORD(wparam)) {
+        BGTOGGLE_CLICK(DBGTOGGLE_BG1ENABLE,  render.bg1_enabled[DEBUG_BGENABLED_ALL ]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG1ENABLE0, render.bg1_enabled[DEBUG_BGENABLED_PRI0]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG1ENABLE1, render.bg1_enabled[DEBUG_BGENABLED_PRI1]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG2ENABLE,  render.bg2_enabled[DEBUG_BGENABLED_ALL ]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG2ENABLE0, render.bg2_enabled[DEBUG_BGENABLED_PRI0]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG2ENABLE1, render.bg2_enabled[DEBUG_BGENABLED_PRI1]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG3ENABLE,  render.bg3_enabled[DEBUG_BGENABLED_ALL ]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG3ENABLE0, render.bg3_enabled[DEBUG_BGENABLED_PRI0]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG3ENABLE1, render.bg3_enabled[DEBUG_BGENABLED_PRI1]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG4ENABLE,  render.bg4_enabled[DEBUG_BGENABLED_ALL ]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG4ENABLE0, render.bg4_enabled[DEBUG_BGENABLED_PRI0]);
+        BGTOGGLE_CLICK(DBGTOGGLE_BG4ENABLE1, render.bg4_enabled[DEBUG_BGENABLED_PRI1]);
+        BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE,  render.oam_enabled[DEBUG_BGENABLED_ALL ]);
+        BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE0, render.oam_enabled[DEBUG_BGENABLED_PRI0]);
+        BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE1, render.oam_enabled[DEBUG_BGENABLED_PRI1]);
+        BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE2, render.oam_enabled[DEBUG_BGENABLED_PRI2]);
+        BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE3, render.oam_enabled[DEBUG_BGENABLED_PRI3]);
+      }
+    }
+  }
+  return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+void CreateDBGToggle(void) {
+int x, y, wl, wr, h;
+  x  =  5;
+  y  =  5;
+  wl = 90;
+  wr = 45;
+  h  = 16;
+  CreateWindow("BUTTON", "Enable BG1", WS_CHILD|WS_VISIBLE|BS_CHECKBOX,  x, y, wl, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG1ENABLE,  GetModuleHandle(0), 0);
+  x += wl;
+  CreateWindow("BUTTON", "Pri 0",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG1ENABLE0, GetModuleHandle(0), 0);
+  x += wr;
+  CreateWindow("BUTTON", "Pri 1",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG1ENABLE1, GetModuleHandle(0), 0);
+
+  x  = 5;
+  y += h;
+  CreateWindow("BUTTON", "Enable BG2", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG2ENABLE,  GetModuleHandle(0), 0);
+  x += wl;
+  CreateWindow("BUTTON", "Pri 0",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG2ENABLE0, GetModuleHandle(0), 0);
+  x += wr;
+  CreateWindow("BUTTON", "Pri 1",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG2ENABLE1, GetModuleHandle(0), 0);
+
+  x  = 5;
+  y += h;
+  CreateWindow("BUTTON", "Enable BG3", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG3ENABLE,  GetModuleHandle(0), 0);
+  x += wl;
+  CreateWindow("BUTTON", "Pri 0",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG3ENABLE0, GetModuleHandle(0), 0);
+  x += wr;
+  CreateWindow("BUTTON", "Pri 1",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG3ENABLE1, GetModuleHandle(0), 0);
+
+  x  = 5;
+  y += h;
+  CreateWindow("BUTTON", "Enable BG4", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG4ENABLE,  GetModuleHandle(0), 0);
+  x += wl;
+  CreateWindow("BUTTON", "Pri 0",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG4ENABLE0, GetModuleHandle(0), 0);
+  x += wr;
+  CreateWindow("BUTTON", "Pri 1",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_BG4ENABLE1, GetModuleHandle(0), 0);
+
+  x  = 5;
+  y += h;
+  CreateWindow("BUTTON", "Enable OAM", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE,  GetModuleHandle(0), 0);
+  x += wl;
+  CreateWindow("BUTTON", "Pri 0",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE0, GetModuleHandle(0), 0);
+  x += wr;
+  CreateWindow("BUTTON", "Pri 1",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE1, GetModuleHandle(0), 0);
+  x += wr;
+  CreateWindow("BUTTON", "Pri 2",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE2, GetModuleHandle(0), 0);
+  x += wr;
+  CreateWindow("BUTTON", "Pri 3",      WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
+    hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE3, GetModuleHandle(0), 0);
+
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG1ENABLE,  WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG1ENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG1ENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG2ENABLE,  WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG2ENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG2ENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG3ENABLE,  WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG3ENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG3ENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG4ENABLE,  WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG4ENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG4ENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE,  WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE2, WM_SETFONT, (WPARAM)hFont, TRUE);
+  SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE3, WM_SETFONT, (WPARAM)hFont, TRUE);
+
+  for(int i=DBGTOGGLE_BG1ENABLE;i<=DBGTOGGLE_OAMENABLE3;i++) {
+    SendDlgItemMessage(hwndDBGToggle, i, BM_SETCHECK, 1, 0);
+  }
+}
diff --git a/bsnes/win/gui_bp.cpp b/bsnes/win/gui_bp.cpp
new file mode 100644
index 00000000..d488ea9c
--- /dev/null
+++ b/bsnes/win/gui_bp.cpp
@@ -0,0 +1,131 @@
+#define DBP_LIST         100
+#define DBP_ADDBP        101
+#define DBP_REMBP        102
+#define DBP_CLRBP        103
+#define DBP_STATIC1      104
+#define DBP_BPNUM        105
+#define DBP_BPOFFSET     106
+#define DBP_BPR          107
+#define DBP_BPW          108
+#define DBP_BPX          109
+#define DBP_BPV          110
+#define DBP_BPVAL        111
+
+HWND hwndDBP;
+
+void debug_refresh_bp(void) {
+char str[64*16], t[64];
+  if(debug_get_state() == DEBUGMODE_DISABLED)return;
+
+  strcpy(str, "");
+  for(int i=0;i<16;i++) {
+    sprintf(t, "%0.2d: ", i);
+    strcat(str, t);
+    if(gx816->bp_list[i].flags == BP_OFF) {
+      strcat(str, "------ ---- -- (Disabled)");
+    } else {
+      sprintf(t, "%0.6x %c%c%c%c ", gx816->bp_list[i].offset,
+        (gx816->bp_list[i].flags & BP_READ )?'R':'r',
+        (gx816->bp_list[i].flags & BP_WRITE)?'W':'w',
+        (gx816->bp_list[i].flags & BP_EXEC )?'X':'x',
+        (gx816->bp_list[i].flags & BP_VAL  )?'V':'v');
+      strcat(str, t);
+      if(gx816->bp_list[i].flags & BP_VAL) {
+        sprintf(t, "%0.2x ", gx816->bp_list[i].value);
+        strcat(str, t);
+      } else strcat(str, "-- ");
+      sprintf(t, "%10d", gx816->bp_list[i].hit_count);
+      strcat(str, t);
+    }
+    if(i != 15)strcat(str, "\n");
+  }
+
+  SetDlgItemText(hwndDBP, DBP_LIST, str);
+}
+
+long __stdcall wndprocDBP(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
+char str[256];
+ulong num, offset, val, flags;
+int i;
+  if(msg == WM_DESTROY || msg == WM_CLOSE)return 0; //don't allow debugger to be closed (yet)
+
+  if(msg == WM_COMMAND) {
+    switch(LOWORD(wparam)) {
+    case DBP_ADDBP:
+      GetDlgItemText(hwndDBP, DBP_BPNUM, str, 255);
+      num = strdec(str);
+      GetDlgItemText(hwndDBP, DBP_BPOFFSET, str, 255);
+      offset = strhex(str) & 0xffffff;
+      GetDlgItemText(hwndDBP, DBP_BPVAL, str, 255);
+      val = strhex(str);
+
+      flags = 0;
+      if(SendMessage(GetDlgItem(hwndDBP, DBP_BPR), BM_GETCHECK, 0, 0))flags |= BP_READ;
+      if(SendMessage(GetDlgItem(hwndDBP, DBP_BPW), BM_GETCHECK, 0, 0))flags |= BP_WRITE;
+      if(SendMessage(GetDlgItem(hwndDBP, DBP_BPX), BM_GETCHECK, 0, 0))flags |= BP_EXEC;
+      if(SendMessage(GetDlgItem(hwndDBP, DBP_BPV), BM_GETCHECK, 0, 0))flags |= BP_VAL;
+
+      if(num > 15)dprintf("Invalid breakpoint #: %d -- 0-15 valid", num);
+      else {
+        gx816->bp_list[num].offset = offset;
+        gx816->bp_list[num].flags  = flags;
+        if(gx816->bp_list[num].flags & BP_VAL)gx816->bp_list[num].value = val;
+        else                                  gx816->bp_list[num].value = 0;
+        gx816->bp_list[num].hit_count = 0;
+      }
+      debugger.refresh_bp = true;
+      break;
+    case DBP_REMBP:
+      GetDlgItemText(hwndDBP, DBP_BPNUM, str, 255);
+      num = strdec(str);
+      if(num > 15)dprintf("Invalid breakpoint #: %d -- 0-15 valid", num);
+      else {
+        gx816->bp_list[num].offset    = 0;
+        gx816->bp_list[num].flags     = BP_OFF;
+        gx816->bp_list[num].value     = 0;
+        gx816->bp_list[num].hit_count = 0;
+      }
+      debugger.refresh_bp = true;
+      break;
+    case DBP_CLRBP:
+      for(i=0;i<16;i++) {
+        gx816->bp_list[i].offset    = 0;
+        gx816->bp_list[i].flags     = BP_OFF;
+        gx816->bp_list[i].value     = 0;
+        gx816->bp_list[i].hit_count = 0;
+      }
+      debugger.refresh_bp = true;
+      break;
+    }
+  }
+
+  return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+void CreateDBP(void) {
+  CreateWindowEx(WS_EX_STATICEDGE, "STATIC", "", WS_CHILD|WS_VISIBLE, 5, 5, 205, 228, hwndDBP, (HMENU)DBP_LIST, GetModuleHandle(0), 0);
+  CreateWindow("STATIC", "BP #:  Offset:", WS_CHILD|WS_VISIBLE, 215, 5, 90, 15, hwndDBP, (HMENU)DBP_STATIC1, GetModuleHandle(0), 0);
+  CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "00", WS_CHILD|WS_VISIBLE,     215, 20, 30, 23, hwndDBP, (HMENU)DBP_BPNUM, GetModuleHandle(0), 0);
+  CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "000000", WS_CHILD|WS_VISIBLE, 245, 20, 60, 23, hwndDBP, (HMENU)DBP_BPOFFSET, GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "R", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,    215,  44,  30, 18, hwndDBP, (HMENU)DBP_BPR,   GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "W", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,    245,  44,  30, 18, hwndDBP, (HMENU)DBP_BPW,   GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "X", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,    275,  44,  30, 18, hwndDBP, (HMENU)DBP_BPX,   GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "V", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,    215,  65,  30, 18, hwndDBP, (HMENU)DBP_BPV,   GetModuleHandle(0), 0);
+  CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "00", WS_CHILD|WS_VISIBLE, 245,  62,  60, 23, hwndDBP, (HMENU)DBP_BPVAL, GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Set BP",        WS_CHILD|WS_VISIBLE,        215,  88,  90, 20, hwndDBP, (HMENU)DBP_ADDBP, GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Clear BP",      WS_CHILD|WS_VISIBLE,        215, 108,  90, 20, hwndDBP, (HMENU)DBP_REMBP, GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Clear All BPs", WS_CHILD|WS_VISIBLE,        215, 128,  90, 20, hwndDBP, (HMENU)DBP_CLRBP, GetModuleHandle(0), 0);
+
+  SendDlgItemMessage(hwndDBP, DBP_LIST,     WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_STATIC1,  WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_BPNUM,    WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_BPOFFSET, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_BPR,      WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_BPW,      WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_BPX,      WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_BPV,      WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_BPVAL,    WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_ADDBP,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_REMBP,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDBP, DBP_CLRBP,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+}
diff --git a/bsnes/win/gui_cpu.cpp b/bsnes/win/gui_cpu.cpp
new file mode 100644
index 00000000..d1d30917
--- /dev/null
+++ b/bsnes/win/gui_cpu.cpp
@@ -0,0 +1,208 @@
+#define DCPU_WIDTH  675
+#define DCPU_HEIGHT 295
+
+#define DCPU_DISAS       100
+#define DCPU_RUN         101
+#define DCPU_STEP        102
+#define DCPU_PROCEED     103
+#define DCPU_INFO        104
+#define DCPU_TRACE       105
+#define DCPU_CYCLES      106
+
+HWND hwndDCPU;
+
+char dcpu_disas_mem[20][256];
+
+void dprintf(char *s, ...) {
+char str[256*20];
+va_list args;
+int i;
+  if(debug_get_state() == DEBUGMODE_DISABLED)return;
+
+  va_start(args, s);
+  vsprintf(str, s, args);
+  va_end(args);
+
+  if(debugger.trace_enabled == true) {
+    fprintf(debugger.trace_fp, "%s\r\n", str);
+  }
+
+//if(debug_get_state() != DEBUGMODE_RUN) {
+    for(i=0;i<19;i++)strcpy(dcpu_disas_mem[i], dcpu_disas_mem[i+1]);
+    strcpy(dcpu_disas_mem[19], str);
+
+    strcpy(str, "");
+    for(i=0;i<20;i++) {
+      strcat(str, dcpu_disas_mem[i]);
+      if(i != 20)strcat(str, "\n");
+    }
+
+    SetDlgItemText(hwndDCPU, DCPU_DISAS, str);
+//}
+}
+
+void debug_update_cycles(void) {
+char str[256];
+  if(debug_get_state() == DEBUGMODE_DISABLED ||
+     debug_get_state() == DEBUGMODE_RUN)return;
+
+  sprintf(str, "Scanline: %d\nCC: %d", ppu.vline_pos, snes_time->master_cycles);
+  SetDlgItemText(hwndDCPU, DCPU_CYCLES, str);
+}
+
+void debug_set_state(byte state) {
+  debugger.mode = state;
+  if(hwndDCPU && state != DEBUGMODE_DISABLED) {
+    if(state == DEBUGMODE_WAIT || state == DEBUGMODE_STEP) {
+      SetDlgItemText(hwndDCPU, DCPU_RUN, "Run");
+    } else {
+      SetDlgItemText(hwndDCPU, DCPU_RUN, "Stop");
+    }
+  }
+
+  if(state == DEBUGMODE_DISABLED) {
+    RunSNES = RunSNES_NoDebug;
+  } else {
+    RunSNES = RunSNES_Debug;
+  }
+}
+
+long __stdcall wndprocDCPU(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
+FILE *fp;
+  if(msg == WM_DESTROY || msg == WM_CLOSE)return 0; //don't allow debugger to be closed (yet)
+
+  if(msg == WM_COMMAND) {
+    switch(LOWORD(wparam)) {
+    case DCPU_RUN:
+      if(debug_get_state() != DEBUGMODE_RUN) {
+        debug_set_state(DEBUGMODE_RUN);
+        SetDlgItemText(hwndDCPU, DCPU_RUN, "Stop");
+      } else {
+        debug_set_state(DEBUGMODE_WAIT);
+        disas_g65816_op();
+        SetDlgItemText(hwndDCPU, DCPU_RUN, "Run");
+      }
+      break;
+    case DCPU_STEP:
+      if(debug_get_state() == DEBUGMODE_WAIT) {
+        debug_set_state(DEBUGMODE_STEP);
+      }
+      break;
+    case DCPU_PROCEED:
+      fp = fopen("data.bin", "wb");
+      fwrite(ppu.vram, 0x10000, 1, fp);
+      fwrite(gx816->wram, 0x20000, 1, fp);
+      fwrite(ppu.cgram, 512, 1, fp);
+      fwrite(ppu.oam, 544, 1, fp);
+      fclose(fp);
+      break;
+    case DCPU_INFO:
+      fp = fopen("data.txt", "w");
+      fprintf(fp,
+              "Memory speed: %s\n"
+              "Mode: %d\n"
+              "BGs On: %d%d%d%d%d\n"
+              "Sub BGs On: %d%d%d%d%d\n"
+              "Tilemap Loc: %0.4x,%0.4x,%0.4x,%0.4x\n"
+              "Tiledata Loc: %0.4x,%0.4x,%0.4x,%0.4x,%0.4x\n"
+              "Tilemap Size: %d,%d,%d,%d\n"
+              "Tile Size: %d,%d,%d,%d\n"
+              "BG Priority Mode: %d\n"
+              "OAM Base Size: %d\nOAM Name Sel: %d\nBG Enabled: %d\nBG Brightness: %d\n"
+              "Window 1 Left: %d\nWindow 1 Right: %d\nWindow 2 Left: %d\nWindow 2 Right: %d\n"
+              "Window 1 Enabled: %d%d%d%d%d\nWindow 2 Enabled: %d%d%d%d%d\n"
+              "Window 1 Clipmode: %s,%s,%s,%s,%s\nWindow 2 Clipmode: %s,%s,%s,%s,%s\n"
+              "BG Windowing Enabled: %d%d%d%d%d\nSub BG Windowing Enabled: %d%d%d%d%d\n"
+              "BG Window Mask: %d,%d,%d,%d,%d\n"
+              "Color Windows Enabled: %d%d\nColor Window Clipmodes: %d,%d\n"
+              "Color Window Mask: %d\nColor Mask: %d\nSub Color Mask: %d\nAddsub Mode: %d\nColor Mode: %d\nColor Halve: %d\n"
+              "BG Color Enabled: %d%d%d%d%d%d\n"
+              "RGB Color Settings: %d,%d,%d\nVIRQ Counter Enabled: %s\nHIRQ Counter Enabled: %s\n"
+              "VIRQ Pos: %d\nHIRQ Pos: %d\n"
+              "Mode 7 Screen Flip: x: %s, y: %s\n"
+              "m7a: %0.4x (%f) m7b: %0.4x (%f) m7c: %0.4x (%f) m7d: %0.4x (%f)\n"
+              "m7x: %0.4x m7y: %0.4x\n",
+        (gx816->memory_speed == 1)?"FastROM":"SlowROM", ppu.bg_mode,
+        (ppu.bg_enabled[0] == true)?1:0, (ppu.bg_enabled[1] == true)?1:0,
+        (ppu.bg_enabled[2] == true)?1:0, (ppu.bg_enabled[3] == true)?1:0, (ppu.bg_enabled[4] == true)?1:0,
+        (ppu.ss_bg_enabled[0] == true)?1:0, (ppu.ss_bg_enabled[1] == true)?1:0,
+        (ppu.ss_bg_enabled[2] == true)?1:0, (ppu.ss_bg_enabled[3] == true)?1:0, (ppu.ss_bg_enabled[4] == true)?1:0,
+        ppu.bg_tilemap_loc[0], ppu.bg_tilemap_loc[1], ppu.bg_tilemap_loc[2], ppu.bg_tilemap_loc[3],
+        ppu.bg_tiledata_loc[0], ppu.bg_tiledata_loc[1], ppu.bg_tiledata_loc[2], ppu.bg_tiledata_loc[3], ppu.oam_tiledata_loc,
+        ppu.bg_tilemap_size[0], ppu.bg_tilemap_size[1], ppu.bg_tilemap_size[2], ppu.bg_tilemap_size[3],
+        ppu.bg_tile_size[0], ppu.bg_tile_size[1], ppu.bg_tile_size[2], ppu.bg_tile_size[3], ppu.bg_priority_mode,
+        ppu.oam_base_size, ppu.oam_name_sel, (ppu.display_disable == true)?0:1, ppu.display_brightness,
+        ppu.window1_left, ppu.window1_right, ppu.window2_left, ppu.window2_right,
+        (ppu.bg_window1_enabled[BG1] == true)?1:0, (ppu.bg_window1_enabled[BG2] == true)?1:0,
+        (ppu.bg_window1_enabled[BG3] == true)?1:0, (ppu.bg_window1_enabled[BG4] == true)?1:0,
+        (ppu.bg_window1_enabled[OAM] == true)?1:0,
+        (ppu.bg_window2_enabled[BG1] == true)?1:0, (ppu.bg_window2_enabled[BG2] == true)?1:0,
+        (ppu.bg_window2_enabled[BG3] == true)?1:0, (ppu.bg_window2_enabled[BG4] == true)?1:0,
+        (ppu.bg_window2_enabled[OAM] == true)?1:0,
+        (ppu.bg_window1_clipmode[BG1] == 1)?"in":"out", (ppu.bg_window1_clipmode[BG2] == 1)?"in":"out",
+        (ppu.bg_window1_clipmode[BG3] == 1)?"in":"out", (ppu.bg_window1_clipmode[BG4] == 1)?"in":"out",
+        (ppu.bg_window1_clipmode[OAM] == 1)?"in":"out",
+        (ppu.bg_window2_clipmode[BG1] == 1)?"in":"out", (ppu.bg_window2_clipmode[BG2] == 1)?"in":"out",
+        (ppu.bg_window2_clipmode[BG3] == 1)?"in":"out", (ppu.bg_window2_clipmode[BG4] == 1)?"in":"out",
+        (ppu.bg_window2_clipmode[BG4] == 1)?"in":"out",
+        (ppu.bg_windowing_enabled[BG1] == true)?1:0, (ppu.bg_windowing_enabled[BG2] == true)?1:0,
+        (ppu.bg_windowing_enabled[BG3] == true)?1:0, (ppu.bg_windowing_enabled[BG4] == true)?1:0,
+        (ppu.bg_windowing_enabled[OAM] == true)?1:0,
+        (ppu.ss_bg_windowing_enabled[BG1] == true)?1:0, (ppu.ss_bg_windowing_enabled[BG2] == true)?1:0,
+        (ppu.ss_bg_windowing_enabled[BG3] == true)?1:0, (ppu.ss_bg_windowing_enabled[BG4] == true)?1:0,
+        (ppu.ss_bg_windowing_enabled[OAM] == true)?1:0,
+        ppu.bg_window_mask[BG1], ppu.bg_window_mask[BG2],
+        ppu.bg_window_mask[BG3], ppu.bg_window_mask[BG4], ppu.bg_window_mask[OAM],
+        (ppu.color_window1_enabled == true)?1:0, (ppu.color_window2_enabled == true)?1:0,
+        ppu.color_window1_clipmode, ppu.color_window2_clipmode, ppu.color_window_mask,
+        ppu.color_mask, ppu.ss_color_mask, ppu.addsub_mode, ppu.color_mode, ppu.color_halve,
+        (ppu.bg_color_enabled[BG1] == true)?1:0, (ppu.bg_color_enabled[BG2]  == true)?1:0,
+        (ppu.bg_color_enabled[BG3] == true)?1:0, (ppu.bg_color_enabled[BG4]  == true)?1:0,
+        (ppu.bg_color_enabled[OAM] == true)?1:0, (ppu.bg_color_enabled[BACK] == true)?1:0,
+        ppu.color_r, ppu.color_g, ppu.color_b,
+        (ppu.vcounter_enabled == true)?"Yes":"No", (ppu.hcounter_enabled == true)?"Yes":"No",
+        ppu.virq_pos, ppu.hirq_pos,
+        (ppu.mode7_vflip == true)?"Yes":"No", (ppu.mode7_hflip == true)?"Yes":"No",
+        ppu.m7a, (float)ppu.m7a / 256, ppu.m7b, (float)ppu.m7b / 256,
+        ppu.m7c, (float)ppu.m7c / 256, ppu.m7d, (float)ppu.m7d / 256,
+        ppu.m7x, ppu.m7y
+      );
+      fclose(fp);
+      break;
+    case DCPU_TRACE:
+      if(debugger.trace_enabled == true) {
+        fclose(debugger.trace_fp);
+        debugger.trace_enabled = false;
+      } else {
+        debugger.trace_fp = fopen("trace.log", "wb");
+        debugger.trace_enabled = true;
+      }
+      break;
+    }
+  }
+
+  return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+void CreateDCPU(void) {
+int i;
+  for(i=0;i<20;i++)strcpy(dcpu_disas_mem[i], "");
+  CreateWindowEx(WS_EX_STATICEDGE, "STATIC", "", WS_CHILD|WS_VISIBLE,     5,   5, 580, 285, hwndDCPU, (HMENU)DCPU_DISAS, GetModuleHandle(0), 0);
+
+  CreateWindow("BUTTON", "Run",                   WS_CHILD|WS_VISIBLE,  590,   5,  80,  20, hwndDCPU, (HMENU)DCPU_RUN,     GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Step",                  WS_CHILD|WS_VISIBLE,  590,  25,  80,  20, hwndDCPU, (HMENU)DCPU_STEP,    GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Export Mem",            WS_CHILD|WS_VISIBLE,  590,  45,  80,  20, hwndDCPU, (HMENU)DCPU_PROCEED, GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Info",                  WS_CHILD|WS_VISIBLE,  590,  65,  80,  20, hwndDCPU, (HMENU)DCPU_INFO,    GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Trace", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,  590,  85,  80,  20, hwndDCPU, (HMENU)DCPU_TRACE,   GetModuleHandle(0), 0);
+
+  CreateWindow("STATIC", "Scanline: 0\nCycles: 0", WS_CHILD|WS_VISIBLE, 590, 260,  80,  30, hwndDCPU, (HMENU)DCPU_CYCLES,  GetModuleHandle(0), 0);
+
+  SendDlgItemMessage(hwndDCPU, DCPU_DISAS,   WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDCPU, DCPU_RUN,     WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDCPU, DCPU_STEP,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDCPU, DCPU_PROCEED, WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDCPU, DCPU_INFO,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDCPU, DCPU_TRACE,   WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDCPU, DCPU_CYCLES,  WM_SETFONT, (WPARAM)hFont,      TRUE);
+}
+
diff --git a/bsnes/win/gui_mem.cpp b/bsnes/win/gui_mem.cpp
new file mode 100644
index 00000000..ba68a08a
--- /dev/null
+++ b/bsnes/win/gui_mem.cpp
@@ -0,0 +1,252 @@
+#define DMEM_VIEW        100
+#define DMEM_EDITWRAM    101
+#define DMEM_UP40        102
+#define DMEM_DOWN40      103
+#define DMEM_UP400       104
+#define DMEM_DOWN400     105
+#define DMEM_UP4000      106
+#define DMEM_DOWN4000    107
+#define DMEM_UP40000     108
+#define DMEM_DOWN40000   109
+#define DMEM_TOWRAM      110
+#define DMEM_TOROM       111
+#define DMEM_TOVRAM      112
+#define DMEM_TOCGRAM     113
+#define DMEM_TOOAM       114
+#define DMEM_TOOFFSET    115
+#define DMEM_EDITLOC     116
+#define DMEM_EDITVAL     117
+#define DMEM_STATIC1     118
+#define DMEM_STATIC2     119
+
+#define DMEMMODE_WRAM  0
+#define DMEMMODE_VRAM  1
+#define DMEMMODE_CGRAM 2
+#define DMEMMODE_OAM   3
+ulong dmem_mode = DMEMMODE_WRAM;
+
+HWND hwndDMEM;
+
+void debug_refresh_mem(void) {
+char str[64*16], t[16];
+ulong ptr;
+int x, y;
+  if(debug_get_state() == DEBUGMODE_DISABLED)return;
+
+  ptr = debugger.mem_ptr;
+  strcpy(str, "");
+
+  if(dmem_mode == DMEMMODE_WRAM) {
+    ptr &= 0xffffff;
+    for(y=0;y<16;y++) {
+      sprintf(t, "%0.6x: ", ptr);
+      strcat(str, t);
+      for(x=0;x<16;x++) {
+        sprintf(t, "%0.2x", gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, ptr++, MEMACCESS_DEBUGGER));
+        ptr &= 0xffffff;
+        strcat(str, t);
+        if(x != 15)strcat(str, " ");
+      }
+      if(y != 15)strcat(str, "\n");
+    }
+  } else if(dmem_mode == DMEMMODE_VRAM) {
+    ptr &= 0xffff;
+    for(y=0;y<16;y++) {
+      sprintf(t, "--%0.4x: ", ptr);
+      strcat(str, t);
+      for(x=0;x<16;x++) {
+        sprintf(t, "%0.2x", ppu.vram[ptr++]);
+        ptr &= 0xffff;
+        strcat(str, t);
+        if(x != 15)strcat(str, " ");
+      }
+      if(y != 15)strcat(str, "\n");
+    }
+  } else if(dmem_mode == DMEMMODE_CGRAM) {
+    ptr &= 0x01ff;
+    for(y=0;y<16;y++) {
+      sprintf(t, "---%0.3x: ", ptr);
+      strcat(str, t);
+      for(x=0;x<16;x++) {
+        sprintf(t, "%0.2x", ppu.cgram[ptr++]);
+        ptr &= 0x01ff;
+        strcat(str, t);
+        if(x != 15)strcat(str, " ");
+      }
+      if(y != 15)strcat(str, "\n");
+    }
+  } else if(dmem_mode == DMEMMODE_OAM) {
+    ptr &= 0x03ff;
+    for(y=0;y<16;y++) {
+      sprintf(t, "---%0.3x: ", ptr);
+      strcat(str, t);
+      for(x=0;x<16;x++) {
+        sprintf(t, "%0.2x", oam_read(ptr++));
+        ptr &= 0x03ff;
+        strcat(str, t);
+        if(x != 15)strcat(str, " ");
+      }
+      if(y != 15)strcat(str, "\n");
+    }
+  }
+
+  SetDlgItemText(hwndDMEM, DMEM_VIEW, str);
+}
+
+void __mask_mem_ptr(void) {
+  if(dmem_mode == DMEMMODE_WRAM )debugger.mem_ptr &= 0xffffff;
+  if(dmem_mode == DMEMMODE_VRAM )debugger.mem_ptr &= 0x00ffff;
+  if(dmem_mode == DMEMMODE_CGRAM)debugger.mem_ptr &= 0x0001ff;
+  if(dmem_mode == DMEMMODE_OAM  )debugger.mem_ptr &= 0x0003ff;
+}
+
+long __stdcall wndprocDMEM(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
+char str[256];
+ulong pos, val;
+  if(msg == WM_DESTROY || msg == WM_CLOSE)return 0; //don't allow debugger to be closed (yet)
+
+  if(msg == WM_COMMAND) {
+    switch(LOWORD(wparam)) {
+    case DMEM_EDITWRAM:
+      GetDlgItemText(hwndDMEM, DMEM_EDITLOC, str, 255);
+      pos = strhex(str);
+      GetDlgItemText(hwndDMEM, DMEM_EDITVAL, str, 255);
+      val = strhex(str);
+      if(dmem_mode == DMEMMODE_WRAM) {
+        gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, pos & 0xffffff, val, MEMACCESS_DEBUGGER);
+      } else if(dmem_mode == DMEMMODE_VRAM) {
+        ppu.vram[pos & 0xffff] = val;
+      } else if(dmem_mode == DMEMMODE_CGRAM) {
+        ppu.cgram[pos & 0x01ff] = val;
+      } else if(dmem_mode == DMEMMODE_OAM) {
+        oam_write(pos, val);
+      }
+      debug_refresh_mem();
+      break;
+    case DMEM_UP40:
+      debugger.mem_ptr -= 0x40;
+      debug_refresh_mem();
+      __mask_mem_ptr();
+      break;
+    case DMEM_DOWN40:
+      debugger.mem_ptr += 0x40;
+      debug_refresh_mem();
+      __mask_mem_ptr();
+      break;
+    case DMEM_UP400:
+      debugger.mem_ptr -= 0x400;
+      debug_refresh_mem();
+      __mask_mem_ptr();
+      break;
+    case DMEM_DOWN400:
+      debugger.mem_ptr += 0x400;
+      debug_refresh_mem();
+      __mask_mem_ptr();
+      break;
+    case DMEM_UP4000:
+      debugger.mem_ptr -= 0x4000;
+      debug_refresh_mem();
+      __mask_mem_ptr();
+      break;
+    case DMEM_DOWN4000:
+      debugger.mem_ptr += 0x4000;
+      debug_refresh_mem();
+      __mask_mem_ptr();
+      break;
+    case DMEM_UP40000:
+      debugger.mem_ptr -= 0x40000;
+      debug_refresh_mem();
+      __mask_mem_ptr();
+      break;
+    case DMEM_DOWN40000:
+      debugger.mem_ptr += 0x40000;
+      debug_refresh_mem();
+      __mask_mem_ptr();
+      break;
+    case DMEM_TOWRAM:
+      dmem_mode = DMEMMODE_WRAM;
+      debugger.mem_ptr = 0x7e0000;
+      SetWindowText(hwndDMEM, "g65816 memory editor -- snes memory mode");
+      debug_refresh_mem();
+      break;
+    case DMEM_TOROM:
+      dmem_mode = DMEMMODE_WRAM;
+      if(gx816->map == MEMMAP_LOROM)debugger.mem_ptr = 0x008000;
+      else if(gx816->map == MEMMAP_HIROM)debugger.mem_ptr = 0xc00000;
+      SetWindowText(hwndDMEM, "g65816 memory editor -- snes memory mode");
+      debug_refresh_mem();
+      break;
+    case DMEM_TOVRAM:
+      dmem_mode = DMEMMODE_VRAM;
+      debugger.mem_ptr = 0x0000;
+      SetWindowText(hwndDMEM, "g65816 memory editor -- ppu vram mode");
+      debug_refresh_mem();
+      break;
+    case DMEM_TOCGRAM:
+      dmem_mode = DMEMMODE_CGRAM;
+      debugger.mem_ptr = 0x0000;
+      SetWindowText(hwndDMEM, "g65816 memory editor -- ppu cgram mode");
+      debug_refresh_mem();
+      break;
+    case DMEM_TOOAM:
+      dmem_mode = DMEMMODE_OAM;
+      debugger.mem_ptr = 0x0000;
+      SetWindowText(hwndDMEM, "g65816 memory editor -- ppu oam mode");
+      debug_refresh_mem();
+      break;
+    case DMEM_TOOFFSET:
+      GetDlgItemText(hwndDMEM, DMEM_EDITLOC, str, 255);
+      debugger.mem_ptr = strhex(str);
+      __mask_mem_ptr();
+      debug_refresh_mem();
+      break;
+    }
+  }
+
+  return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+void CreateDMEM(void) {
+  CreateWindowEx(WS_EX_STATICEDGE, "STATIC", "", WS_CHILD|WS_VISIBLE, 5, 5, 390, 228, hwndDMEM, (HMENU)DMEM_VIEW, GetModuleHandle(0), 0);
+  CreateWindow("STATIC", "Offset:        Val:", WS_CHILD|WS_VISIBLE, 400, 5, 100, 15, hwndDMEM, (HMENU)DMEM_STATIC1, GetModuleHandle(0), 0);
+  CreateWindowEx(WS_EX_CLIENTEDGE,  "EDIT", "000000", WS_CHILD|WS_VISIBLE, 400, 20, 60, 23, hwndDMEM, (HMENU)DMEM_EDITLOC, GetModuleHandle(0), 0);
+  CreateWindowEx(WS_EX_CLIENTEDGE,  "EDIT", "00",     WS_CHILD|WS_VISIBLE, 460, 20, 30, 23, hwndDMEM, (HMENU)DMEM_EDITVAL, GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Edit Memory", WS_CHILD|WS_VISIBLE, 400,  45,  90, 20, hwndDMEM, (HMENU)DMEM_EDITWRAM,  GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "-40",         WS_CHILD|WS_VISIBLE, 400,  70,  45, 20, hwndDMEM, (HMENU)DMEM_UP40,      GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "+40",         WS_CHILD|WS_VISIBLE, 445,  70,  45, 20, hwndDMEM, (HMENU)DMEM_DOWN40,    GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "-400",        WS_CHILD|WS_VISIBLE, 400,  90,  45, 20, hwndDMEM, (HMENU)DMEM_UP400,     GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "+400",        WS_CHILD|WS_VISIBLE, 445,  90,  45, 20, hwndDMEM, (HMENU)DMEM_DOWN400,   GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "-4000",       WS_CHILD|WS_VISIBLE, 400, 110,  45, 20, hwndDMEM, (HMENU)DMEM_UP4000,    GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "+4000",       WS_CHILD|WS_VISIBLE, 445, 110,  45, 20, hwndDMEM, (HMENU)DMEM_DOWN4000,  GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "-40000",      WS_CHILD|WS_VISIBLE, 400, 130,  45, 20, hwndDMEM, (HMENU)DMEM_UP40000,   GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "+40000",      WS_CHILD|WS_VISIBLE, 445, 130,  45, 20, hwndDMEM, (HMENU)DMEM_DOWN40000, GetModuleHandle(0), 0);
+  CreateWindow("STATIC", "Seek To:",    WS_CHILD|WS_VISIBLE, 400, 155, 100, 15, hwndDMEM, (HMENU)DMEM_STATIC2,   GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "WRAM",        WS_CHILD|WS_VISIBLE, 400, 173,  45, 20, hwndDMEM, (HMENU)DMEM_TOWRAM,    GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "ROM",         WS_CHILD|WS_VISIBLE, 445, 173,  45, 20, hwndDMEM, (HMENU)DMEM_TOROM,     GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "VRAM",        WS_CHILD|WS_VISIBLE, 400, 193,  45, 20, hwndDMEM, (HMENU)DMEM_TOVRAM,    GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "CGRAM",       WS_CHILD|WS_VISIBLE, 445, 193,  45, 20, hwndDMEM, (HMENU)DMEM_TOCGRAM,   GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "OAM",         WS_CHILD|WS_VISIBLE, 400, 213,  45, 20, hwndDMEM, (HMENU)DMEM_TOOAM,     GetModuleHandle(0), 0);
+  CreateWindow("BUTTON", "Offset",      WS_CHILD|WS_VISIBLE, 445, 213,  45, 20, hwndDMEM, (HMENU)DMEM_TOOFFSET,  GetModuleHandle(0), 0);
+
+  SendDlgItemMessage(hwndDMEM, DMEM_VIEW,      WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_EDITLOC,   WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_EDITVAL,   WM_SETFONT, (WPARAM)hFontFixed, TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_STATIC1,   WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_EDITWRAM,  WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_UP40,      WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_DOWN40,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_UP400,     WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_DOWN400,   WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_UP4000,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_DOWN4000,  WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_UP40000,   WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_DOWN40000, WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_STATIC2,   WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_TOWRAM,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_TOROM,     WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_TOVRAM,    WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_TOCGRAM,   WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_TOOAM,     WM_SETFONT, (WPARAM)hFont,      TRUE);
+  SendDlgItemMessage(hwndDMEM, DMEM_TOOFFSET,  WM_SETFONT, (WPARAM)hFont,      TRUE);
+}
+
diff --git a/bsnes/win/render.cpp b/bsnes/win/render.cpp
new file mode 100644
index 00000000..d3bff380
--- /dev/null
+++ b/bsnes/win/render.cpp
@@ -0,0 +1,269 @@
+#include <ddraw.h>
+
+LPDIRECTDRAW        lpdd  = 0;
+LPDIRECTDRAWSURFACE lpdds = 0, lpddsb = 0;
+LPDIRECTDRAWCLIPPER lpddc = 0;
+DDSURFACEDESC       ddsd;
+DDSCAPS             ddscaps;
+
+void DestroyDDraw(void) {
+  if(lpddc) {
+    lpddc->Release();
+    lpddc = 0;
+  }
+  if(lpddsb) {
+    lpddsb->Release();
+    lpddsb = 0;
+  }
+  if(lpdds) {
+    lpdds->Release();
+    lpdds = 0;
+  }
+  if(lpdd) {
+    lpdd->Release();
+    lpdd = 0;
+  }
+}
+
+void CreateDDraw_Win(void) {
+  DestroyDDraw();
+
+  DirectDrawCreate(0, &lpdd, 0);
+  lpdd->SetCooperativeLevel(hwndMain, DDSCL_NORMAL);
+
+  memset(&ddsd, 0, sizeof(DDSURFACEDESC));
+  ddsd.dwSize = sizeof(DDSURFACEDESC);
+  ddsd.dwFlags = DDSD_CAPS;
+  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+  lpdd->CreateSurface(&ddsd, &lpdds, 0);
+
+  lpdd->CreateClipper(0, &lpddc, 0);
+  lpddc->SetHWnd(0, hwndMain);
+  lpdds->SetClipper(lpddc);
+
+  memset(&ddsd, 0, sizeof(DDSURFACEDESC));
+  ddsd.dwSize = sizeof(DDSURFACEDESC);
+  ddsd.dwFlags  = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+  ddsd.dwWidth  = 512;
+  ddsd.dwHeight = 480;
+  lpdd->CreateSurface(&ddsd, &lpddsb, 0);
+}
+
+void CreateDDraw_Full(void) {
+  DestroyDDraw();
+
+  DirectDrawCreate(0, &lpdd, 0);
+  lpdd->SetCooperativeLevel(hwndMain, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
+  lpdd->SetDisplayMode(640, 480, 16);
+
+  memset(&ddsd, 0, sizeof(DDSURFACEDESC));
+  ddsd.dwSize = sizeof(DDSURFACEDESC);
+  ddsd.dwFlags = DDSD_CAPS;
+  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+  lpdd->CreateSurface(&ddsd, &lpdds, 0);
+
+  memset(&ddsd, 0, sizeof(DDSURFACEDESC));
+  ddsd.dwSize = sizeof(DDSURFACEDESC);
+  ddsd.dwFlags  = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+  ddsd.dwWidth  = 512;
+  ddsd.dwHeight = 480;
+  lpdd->CreateSurface(&ddsd, &lpddsb, 0);
+}
+
+void InitDisplay(void) {
+  CreateDDraw_Win();
+}
+
+//size is doubled (mirrored) to prevent having to mask the top unused bit of snes color data
+ulong render_color_lookup[65536];
+
+void InitColorTable16(void) {
+int i, r, g, b;
+  for(i=0;i<65536;i++) {
+    r = (i      ) & 31;
+    g = (i >>  5) & 31;
+    b = (i >> 10) & 31;
+    render_color_lookup[i] = (r << 11) | (g << 6) | (b);
+  }
+}
+
+void InitColorTable24(void) {
+int i, r, g, b;
+  for(i=0;i<65536;i++) {
+    r = (i      ) & 31;
+    g = (i >>  5) & 31;
+    b = (i >> 10) & 31;
+    render_color_lookup[i] = (r << 19) | (g << 11) | (b << 3);
+  }
+}
+
+vfunc RenderScene;
+
+//sets up color table and sets render proc
+void CreateColorTable(void) {
+  lpdds->GetSurfaceDesc(&ddsd);
+  switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
+  case 16:
+    InitColorTable16();
+    break;
+  case 32:
+    InitColorTable24();
+    break;
+  default:
+    alert("Error: Bit depth [%d] unsupported (supported depths: 16, 32)", ddsd.ddpfPixelFormat.dwRGBBitCount);
+    exit(0);
+    break;
+  }
+}
+
+#include "render_modes.cpp"
+
+void SelectRenderer(void) {
+  lpdds->GetSurfaceDesc(&ddsd);
+  switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
+  case 16:
+    if       (render.snes_width == 512 && render.snes_height == 480) {
+      RenderScene = RenderScene16_512x480;
+    } else if(render.snes_width == 512 && render.snes_height == 448) {
+      RenderScene = RenderScene16_512x448;
+    } else if(render.snes_width == 512 && render.snes_height == 240) {
+      RenderScene = RenderScene16_512x240;
+    } else if(render.snes_width == 512 && render.snes_height == 224) {
+      RenderScene = RenderScene16_512x224;
+    } else if(render.snes_width == 256 && render.snes_height == 480) {
+      RenderScene = RenderScene16_256x480;
+    } else if(render.snes_width == 256 && render.snes_height == 448) {
+      RenderScene = RenderScene16_256x448;
+    } else if(render.snes_width == 256 && render.snes_height == 240) {
+      RenderScene = RenderScene16_256x240;
+    } else if(render.snes_width == 256 && render.snes_height == 224) {
+      RenderScene = RenderScene16_256x224;
+    } else {
+      alert("Error: Unsupported SNES Resolution: %dx%d", render.snes_width, render.snes_height);
+    }
+    break;
+  case 32:
+    if       (render.snes_width == 512 && render.snes_height == 480) {
+      RenderScene = RenderScene32_512x480;
+    } else if(render.snes_width == 512 && render.snes_height == 448) {
+      RenderScene = RenderScene32_512x448;
+    } else if(render.snes_width == 512 && render.snes_height == 240) {
+      RenderScene = RenderScene32_512x240;
+    } else if(render.snes_width == 512 && render.snes_height == 224) {
+      RenderScene = RenderScene32_512x224;
+    } else if(render.snes_width == 256 && render.snes_height == 480) {
+      RenderScene = RenderScene32_256x480;
+    } else if(render.snes_width == 256 && render.snes_height == 448) {
+      RenderScene = RenderScene32_256x448;
+    } else if(render.snes_width == 256 && render.snes_height == 240) {
+      RenderScene = RenderScene32_256x240;
+    } else if(render.snes_width == 256 && render.snes_height == 224) {
+      RenderScene = RenderScene32_256x224;
+    } else {
+      alert("Error: Unsupported SNES Resolution: %dx%d", render.snes_width, render.snes_height);
+    }
+    break;
+  default:
+    alert("Error: Bit depth [%d] unsupported (supported depths: 16, 32)", ddsd.ddpfPixelFormat.dwRGBBitCount);
+    exit(0);
+    break;
+  }
+}
+
+void UpdateDisplay(void) {
+RECT  rsrc, rdest;
+POINT p;
+HRESULT hr;
+  RenderScene();
+
+  p.x = p.y = 0;
+  if(render.fullscreen == true) {
+    SetRect(&rdest, 0, 0, 512, 448);
+    OffsetRect(&rdest, (640 - 512) / 2, (480 - 448) / 2);
+  } else {
+    ClientToScreen(hwndMain, &p);
+    GetClientRect(hwndMain, &rdest);
+    OffsetRect(&rdest, p.x, p.y);
+  }
+
+  SetRect(&rsrc, 0, 0, render.snes_width, render.snes_height);
+
+  hr = lpdds->Blt(&rdest, lpddsb, &rsrc, DDBLT_WAIT, 0);
+  if(hr == DDERR_SURFACELOST) {
+    lpdds->Restore();
+    lpddsb->Restore();
+  }
+}
+
+void UpdateDisplay_NoRender(void) {
+RECT  rsrc, rdest;
+POINT p;
+HRESULT hr;
+  p.x = p.y = 0;
+  if(render.fullscreen == true) {
+    SetRect(&rdest, 0, 0, 512, 448);
+    OffsetRect(&rdest, (640 - 512) / 2, (480 - 448) / 2);
+  } else {
+    ClientToScreen(hwndMain, &p);
+    GetClientRect(hwndMain, &rdest);
+    OffsetRect(&rdest, p.x, p.y);
+  }
+
+  SetRect(&rsrc, 0, 0, render.snes_width, render.snes_height);
+
+  hr = lpdds->Blt(&rdest, lpddsb, &rsrc, DDBLT_WAIT, 0);
+  if(hr == DDERR_SURFACELOST) {
+    lpdds->Restore();
+    lpddsb->Restore();
+  }
+}
+
+void video_setmode(bool fullscreen, word width, word height) {
+bool prev_mode = render.fullscreen;
+  render.fullscreen = fullscreen;
+  render.width      = width;
+  render.height     = height;
+
+  FixWindowSize(hwndMain, width, height);
+  ShowWindow(hwndMain, SW_NORMAL);
+
+  if(prev_mode != fullscreen) {
+    if(fullscreen == true) {
+      render.show_menu = false;
+      UpdateMainWindowStyle(true);
+      CreateDDraw_Full();
+      ShowWindow(hwndMain, SW_NORMAL);
+    } else {
+      render.show_menu = true;
+      UpdateMainWindowStyle(true);
+      CreateDDraw_Win();
+      FixWindowSize(hwndMain, width, height);
+      ShowWindow(hwndMain, SW_NORMAL);
+    }
+  }
+}
+
+void video_setsnesmode(void) {
+  if(ppu.bg_mode == 5 || ppu.bg_mode == 6) {
+    render.snes_width = 512;
+  } else {
+    render.snes_width = 256;
+  }
+  if(ppu.interlace == true) {
+    if(ppu.visible_scanlines == 240) {
+      render.snes_height = 480;
+    } else {
+      render.snes_height = 448;
+    }
+  } else {
+    if(ppu.visible_scanlines == 240) {
+      render.snes_height = 240;
+    } else {
+      render.snes_height = 224;
+    }
+  }
+
+  SelectRenderer();
+}
diff --git a/bsnes/win/render_modes.cpp b/bsnes/win/render_modes.cpp
new file mode 100644
index 00000000..40980dcb
--- /dev/null
+++ b/bsnes/win/render_modes.cpp
@@ -0,0 +1,303 @@
+void RenderScene16_256x224(void) {
+word *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 1;
+  for(y=0;y<224;y++) {
+    screen = (word*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<256;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene32_256x224(void) {
+ulong *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 2;
+  for(y=0;y<224;y++) {
+    screen = (ulong*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<256;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene16_256x240(void) {
+word *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 1;
+  for(y=0;y<240;y++) {
+    screen = (word*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<256;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene32_256x240(void) {
+ulong *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 2;
+  for(y=0;y<240;y++) {
+    screen = (ulong*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<256;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene16_256x448(void) {
+word *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 1;
+  for(y=0;y<448;y++) {
+    screen = (word*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<256;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene32_256x448(void) {
+ulong *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 2;
+  for(y=0;y<448;y++) {
+    screen = (ulong*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<256;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene16_256x480(void) {
+word *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 1;
+  for(y=0;y<480;y++) {
+    screen = (word*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<256;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene32_256x480(void) {
+ulong *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 2;
+  for(y=0;y<480;y++) {
+    screen = (ulong*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<256;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene16_512x224(void) {
+word *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 1;
+  for(y=0;y<224;y++) {
+    screen = (word*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<512;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene32_512x224(void) {
+ulong *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 2;
+  for(y=0;y<224;y++) {
+    screen = (ulong*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<512;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene16_512x240(void) {
+word *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 1;
+  for(y=0;y<240;y++) {
+    screen = (word*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<512;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene32_512x240(void) {
+ulong *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 2;
+  for(y=0;y<240;y++) {
+    screen = (ulong*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<512;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene16_512x448(void) {
+word *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 1;
+  for(y=0;y<448;y++) {
+    screen = (word*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<512;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene32_512x448(void) {
+ulong *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 2;
+  for(y=0;y<448;y++) {
+    screen = (ulong*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<512;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene16_512x480(void) {
+word *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 1;
+  for(y=0;y<480;y++) {
+    screen = (word*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<512;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}
+
+void RenderScene32_512x480(void) {
+ulong *screen;
+word *src;
+word pitch;
+HRESULT hr;
+int x, y;
+  hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
+  if(hr != DD_OK)return;
+  pitch  = ddsd.lPitch >> 2;
+  for(y=0;y<480;y++) {
+    screen = (ulong*)ddsd.lpSurface + (pitch * y);
+    src    = (word*)ppu.screen + y * 512;
+    for(x=0;x<512;x++) {
+      *screen++ = render_color_lookup[*src++];
+    }
+  }
+  lpddsb->Unlock(0);
+}