mirror of https://github.com/bsnes-emu/bsnes.git
Update to bsnes v002 ir9 release.
[No changelog available]
This commit is contained in:
parent
487491e6f2
commit
938609818f
|
@ -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
|
|
@ -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);
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
@nmake /NOLOGO
|
||||
@pause
|
|
@ -0,0 +1 @@
|
|||
@nmake /NOLOGO clean
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
};
|
|
@ -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
|
||||
};
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
};
|
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -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"
|
|
@ -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)); }
|
|
@ -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);
|
||||
}
|
|
@ -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); }
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
del c:\root\bsnes_testrom\bsnes.exe
|
||||
copy bsnes.exe c:\root\bsnes_testrom\bsnes.exe
|
||||
@pause
|
Binary file not shown.
|
@ -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;
|
|
@ -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();
|
||||
};
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue