Compare commits

..
11 Commits
Author SHA1 Message Date
byuu 6f7cf1bd31 Update to bsnes v005a release.
[No changelog available]
2005-02-06 04:04:32 +00:00
byuu 8751bc433f Update to bsnes v005 release.
Released a new version of bsnes today. Version 0.0.005 is up on the main page now.
The changes since .004 wip10 include: DRAM timing fix (now occurs mid-opcode), memory address speed fix, added CPU cycle condition 4 to all opcodes that use it, and fixed a bug where DRAM refresh was not changing start positions every other scanline.
With the new version, Chrono Trigger should get a little further, and Final Fantasy 5 should get in-game now. The only problem FF5 seems to have is sprite corrution in the menus. I´m too busy with the CPU timing to mess around with the PPU right now, though. Also, the APU is not bridged to the CPU in this release, so compatibility is (still) really low.
After I get the APU working fairly well, I´ll (try and) start keeping a what´s new file so that people can know what all changed between public releases of the emulator without having to follow this page. Sorry for the inconvenience in the mean time.

[No archive available]
2005-02-05 00:00:00 +00:00
byuu afbee40bc0 Update to bsnes v004 release.
[No changelog available]

[No archive available]
2004-12-24 00:00:00 +00:00
byuu 81e9be64d2 Update to bsnes v003r01 release.
[No changelog available]

[No archive available]
2004-12-13 00:00:00 +00:00
byuu 0cd4972d11 Update to bsnes v002 ir11 release.
Doubled the width of sprites when the width of the screen is 512. The SNES Test Program now runs through all of the character test correctly. The windows are off-by-one though.
Added the very bizarre 00:4300-00:437f memory region that is unique from 7e:4300-7e:437f. Then I added read support from $2180. This allowed the SNES Test Program to not crash after failing the electronics test, and it also fixed the horrible graphics corruption in Der Langrisser.
The fonts were still failing, so I went in with my tracer and found out what was causing it. The following code:
	gx816->regs.pc += (signed char)(arg + 2);
This is the code used to increment the pc counter after relative branches. The problem is that I had parinthesis around the + 2 as well as arg. Therefore, if arg was 0x7e, 0x7f, 0xfe, or 0xff, it would change the sign. This would in turn make the program counter off by 256 bytes. Very bad. Fixing this fixed the font in Der Langrisser, and also fixed Super Mario World, when Yoshi spits a turtle out, the game will no longer crash.
Next, via the Der Langrisser world map, I realized that anomie´s description of the BG/mode7 register latches was reversed: the BG registers (may) share a common latch between all of them, but the mode7 registers do not. I removed the common latches from the mode7 regs, but I haven´t added the latch to the BG registers yet.
I also realized that clearing the entire screen on a BG mode change would probably not be a good thing for games that change video modes mid-frame. So I tried working on getting the weird single-frame garble that pops up every minute or so to go away, but to no avail. I´m having a difficult time tracking down the exact cause of the error, but I believe it to be a buffer overflow, or something along those lines.

[No archive available]
2004-12-11 00:00:00 +00:00
byuu 938609818f Update to bsnes v002 ir9 release.
[No changelog available]
2004-12-07 01:12:32 +00:00
byuu 487491e6f2 Update to bsnes v002 ir7 release.
The bug in the Bahamut Lagoon mode7 screens turned out to be that I never added the dividend result to $4216/$4217. It always returned the multiplication of $4202/$4203. This also fixed the sprites in battles for Dai Kaijuu Monogatari. I added a bunch of window stuff, including a double size windowed mode, and a fullscreen mode. Lots of fixes to the interface, as well as code cleanup. It's still pretty buggy, there's a lot of variables to keep up with in the GUI at present...
I also added better tile caching, I just cache all tiles when they are rendered, for all 3 color depths (4, 16, 256). Seems to help a little. A portion of the speed gain was lost by fixing the dividend result, though. Very strange, since I wouldn't think much work would go into a simple line of code that's called 20 times a frame probably at best... oh well.

[No archive available]
2004-12-05 00:00:00 +00:00
byuu a6ccc7e5d2 Update to unreleased version.
First, I fixed some issues with the mode7 / scroll regs thanks to info from anomie. Qwertie's mode7 demo runs without modification now. Next, I fixed a small glitch with tiles getting cut off on the right edge of the screen, fixes some flickering on the edges in Zelda 3. Finally, I added tile caching to all 4 BG layers. It didn't really increase speed by much (~10%), and upped the RAM requirements by 1.2mb... I left the old code in case I need to fall back on it. My only guess (hope) is that the bottleneck lies somewhere else...

[No archive available]
2004-12-04 00:00:00 +00:00
byuu 39dd39cc09 Update to unreleased version.
Had a small glitch in the OAM $2102/$2103 register settings, fixed that and now both Zelda 3 and Super Mario World always show sprites perfectly. The only error to my knowledge in the below screenshots is that the large version of the mario sprite in the third pic is not shown at the top left of the screen. Which could be because I have no mosaic support. But at any rate, both games should be completely playable now, albeit very slowly. I tried to speed up things by caching some stuff in the PPU, but I couldn't find a nice way to implement it that would result in a significant speed increase. Oh yeah, Zelda won't follow you in Zelda 3, but you can just go to the throne room and push the picture to the right yourself, and she'll appear when you reach the sanctuary.
I also updated the debugger, it uses a smaller font, which is a bit harder to read, but saves a lot of screen space. This will definately be needed when I add in more of the debugging windows in the future, so it's better to get used to it now than later.

[No archive available]
2004-11-27 00:00:00 +00:00
byuu 1a017ff697 Update to unreleased version.
Added SRAM support. It's compatible with other emulators. It maps both the LoROM SRAM between $700000-$7dffff, and HiROM SRAM between $3n6000-$3n7fff (where n = 0 - f).
Modified the screen to redraw at scanline 224, instead of 0. Fixes some flickering between screens in some games.
Moved the lighting adjustment code ($2100 bits 0-3) directly into the PPU, rather than outside in the platform-specific code. This is because games have the ability to adjust this value per scanline. Also allowed the games to control the background enable ($2100 bit 7) flag per scanline now. This allowed Bahamut Lagoon's dragon intro to work.
I then added mode2 support, so now all that's missing is modes 5 and 6 (interlaced).
I also created an easy #define to select between the public domain mode7 code I wrote, and the snes9x mode7 code. I'll go through one of these days and rewrite the snes9x code in a clean environment (e.g. without using the current mode7 file as a reference) to avoid the issue altogether, but for now... the snes9x code is twice as fast, and that's good enough for me.
Lastly, I also added in a trace checkbox to enable tracing. As such, the zip file of my work up now has debug mode enabled by default. I really need an overhaul of the gui implementation, and a configuration file. I have a very nice string library system (that I wrote myself) that I would love to take advantage of in this project.
Here's some screenshots of the dragon intro. Lots of HDMA here, showing that I pretty much have HDMA down, now. I remember zsnes used to have a problem with these screens, and had to do something with an HDMA hack to get around it. They figured out what the problem was, eventually. I was actually quite surprised my emulator does not suffer from this same problem. Lucky for me, as they never did mention what the problem was to begin with. The HDMA is technically drawing too soon (at the start of the scanline instead of the end) which probably messes things up a bit, and I'm guessing the scroll registers are screwing up in one or two of the below pics. No mosaic support either.

[No archive available]
2004-11-21 00:00:00 +00:00
byuu 591adfcb25 Update to unreleased version.
Initial release

[No archive available]
2004-10-14 00:00:00 +00:00
902 changed files with 19155 additions and 150165 deletions

No files matched your search

Executable → Regular
+43 -70
View File
@@ -1,70 +1,43 @@
include nall/Makefile
snes := snes
gameboy := gameboy
profile := accuracy
ui := ui
# compiler
c := $(compiler) -std=gnu99
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
flags := -O3 -fomit-frame-pointer -I.
link :=
objects := libco
# profile-guided instrumentation
# flags += -fprofile-generate
# link += -lgcov
# profile-guided optimization
# flags += -fprofile-use
# platform
ifeq ($(platform),x)
link += -s -ldl -lX11 -lXext
else ifeq ($(platform),osx)
else ifeq ($(platform),win)
link += -mwindows
# link += -mconsole
link += -mthreads -s -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32
link += -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
else
unknown_platform: help;
endif
# implicit rules
compile = \
$(strip \
$(if $(filter %.c,$<), \
$(c) $(flags) $1 -c $< -o $@, \
$(if $(filter %.cpp,$<), \
$(cpp) $(flags) $1 -c $< -o $@ \
) \
) \
)
%.o: $<; $(call compile)
all: build;
obj/libco.o: libco/libco.c libco/*
include $(ui)/Makefile
# targets
clean:
-@$(call delete,obj/*.o)
-@$(call delete,obj/*.a)
-@$(call delete,obj/*.so)
-@$(call delete,obj/*.dylib)
-@$(call delete,obj/*.dll)
-@$(call delete,*.res)
-@$(call delete,*.pgd)
-@$(call delete,*.pgc)
-@$(call delete,*.ilk)
-@$(call delete,*.pdb)
-@$(call delete,*.manifest)
archive-all:
tar -cjf bsnes.tar.bz2 data gameboy libco nall obj out phoenix ruby snes ui ui-gameboy Makefile cc.bat clean.bat sync.sh
help:;
CC = cl
CFLAGS = /nologo /O2
OBJS = main.obj timing.obj g65816.obj d65816.obj spc700.obj dspc700.obj memory.obj mmio.obj bridge.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
spc700.obj: apu/spc700*.cpp apu/spc700*.h
$(CC) $(CFLAGS) /c apu/spc700.cpp
dspc700.obj: apu/dspc700.cpp
$(CC) $(CFLAGS) /c apu/dspc700.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
bridge.obj: bridge/bridge.cpp bridge/bridge.h
$(CC) $(CFLAGS) /c bridge/bridge.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
+314
View File
@@ -0,0 +1,314 @@
#include "../base.h"
#include "spc700.h"
extern sony_spc700 *spc700;
extern debugstate debugger;
char __disas_spc700_str[256];
word __disas_spc700_relb(byte arg, byte offset) {
word r = spc700->regs.pc + (signed char)arg;
r += offset;
return r;
}
void __disas_spc700_op(byte op, byte op0, byte op1) {
char *s = (char*)__disas_spc700_str;
word opw = (op1 << 8) | (op0);
switch(op) {
case 0x00:sprintf(s, "nop");break;
case 0x01:sprintf(s, "tcall 0");break;
case 0x02:sprintf(s, "set0 $%0.2x", op0);break;
case 0x03:sprintf(s, "bbs0 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x04:sprintf(s, "or a,$%0.2x", op0);break;
case 0x05:sprintf(s, "or a,$%0.4x", opw);break;
case 0x06:sprintf(s, "or a,(x)");break;
case 0x07:sprintf(s, "or a,($%0.2x+x)", op0);break;
case 0x08:sprintf(s, "or a,#$%0.2x", op0);break;
case 0x09:sprintf(s, "or ($%0.2x),($%0.2x)", op1, op0);break;
case 0x0a:sprintf(s, "or1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
case 0x0b:sprintf(s, "asl $%0.2x", op0);break;
case 0x0c:sprintf(s, "mov $%0.4x,y", opw);break;
case 0x0d:sprintf(s, "push psw");break;
case 0x0e:sprintf(s, "tset1 $%0.4x", opw);break;
case 0x0f:sprintf(s, "brk");break;
case 0x10:sprintf(s, "bpl $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0x11:sprintf(s, "tcall 1");break;
case 0x12:sprintf(s, "clr0 $%0.2x", op0);break;
case 0x13:sprintf(s, "bbc0 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x14:sprintf(s, "or a,$%0.2x+x", op0);break;
case 0x15:sprintf(s, "or a,$%0.4x+x", opw);break;
case 0x16:sprintf(s, "or a,$%0.4x+y", opw);break;
case 0x17:sprintf(s, "or a,($%0.2x)+y", op0);break;
case 0x18:sprintf(s, "or $%0.2x,#$%0.2x", op1, op0);break;
case 0x19:sprintf(s, "or (x),(y)");break;
case 0x1a:sprintf(s, "decw $%0.2x", op0);break;
case 0x1b:sprintf(s, "asl $%0.2x+x", op0);break;
case 0x1c:sprintf(s, "asl a");break;
case 0x1d:sprintf(s, "dec x");break;
case 0x1e:sprintf(s, "cmp x,$%0.4x", opw);break;
case 0x1f:sprintf(s, "jmp ($%0.4x+x)", opw);break;
case 0x20:sprintf(s, "clrp");break;
case 0x21:sprintf(s, "tcall 2");break;
case 0x22:sprintf(s, "set1 $%0.2x", op0);break;
case 0x23:sprintf(s, "bbs1 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x24:sprintf(s, "and a,$%0.2x", op0);break;
case 0x25:sprintf(s, "and a,$%0.4x", opw);break;
case 0x26:sprintf(s, "and a,(x)", op0);break;
case 0x27:sprintf(s, "and a,($%0.2x+x)", op0);break;
case 0x28:sprintf(s, "and a,#$%0.2x", op0);break;
case 0x29:sprintf(s, "and ($%0.2x),($%0.2x)", op1, op0);break;
case 0x2a:sprintf(s, "or1 c,!$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
case 0x2b:sprintf(s, "rol $%0.2x", op0);break;
case 0x2c:sprintf(s, "rol $%0.4x", opw);break;
case 0x2d:sprintf(s, "push a");break;
case 0x2e:sprintf(s, "cbne $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x2f:sprintf(s, "bra $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0x30:sprintf(s, "bmi $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0x31:sprintf(s, "tcall 3");break;
case 0x32:sprintf(s, "clr1 $%0.2x", op0);break;
case 0x33:sprintf(s, "bbc1 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x34:sprintf(s, "and a,$%0.2x+x", op0);break;
case 0x35:sprintf(s, "and a,$%0.4x+x", opw);break;
case 0x36:sprintf(s, "and a,$%0.4x+y", opw);break;
case 0x37:sprintf(s, "and a,($%0.2x)+y", op0);break;
case 0x38:sprintf(s, "and $%0.2x,#$%0.2x", op1, op0);break;
case 0x39:sprintf(s, "and (x),(y)");break;
case 0x3a:sprintf(s, "incw $%0.2x", op0);break;
case 0x3b:sprintf(s, "rol $%0.2x+x", op0);break;
case 0x3c:sprintf(s, "rol a");break;
case 0x3d:sprintf(s, "inc x");break;
case 0x3e:sprintf(s, "cmp x,$%0.2x", op0);break;
case 0x3f:sprintf(s, "call $%0.4x", opw);break;
case 0x40:sprintf(s, "setp");break;
case 0x41:sprintf(s, "tcall 4");break;
case 0x42:sprintf(s, "set2 $%0.2x", op0);break;
case 0x43:sprintf(s, "bbs2 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x44:sprintf(s, "eor a,$%0.2x", op0);break;
case 0x45:sprintf(s, "eor a,$%0.4x", opw);break;
case 0x46:sprintf(s, "eor a,(x)");break;
case 0x47:sprintf(s, "eor a,($%0.2x+x)", op0);break;
case 0x48:sprintf(s, "eor a,#$%0.2x", op0);break;
case 0x49:sprintf(s, "eor ($%0.2x),($%0.2x)", op1, op0);break;
case 0x4a:sprintf(s, "and1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
case 0x4b:sprintf(s, "lsr $%0.2x", op0);break;
case 0x4c:sprintf(s, "lsr $%0.4x", opw);break;
case 0x4d:sprintf(s, "push x");break;
case 0x4e:sprintf(s, "tclr1 $%0.4x", opw);break;
case 0x4f:sprintf(s, "pcall $%0.2x", op0);break;
case 0x50:sprintf(s, "bvc $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0x51:sprintf(s, "tcall 5");break;
case 0x52:sprintf(s, "clr2 $%0.2x", op0);break;
case 0x53:sprintf(s, "bbc2 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x54:sprintf(s, "eor a,$%0.2x+x", op0);break;
case 0x55:sprintf(s, "eor a,$%0.4x+x", opw);break;
case 0x56:sprintf(s, "eor a,$%0.4x+y", opw);break;
case 0x57:sprintf(s, "eor a,($%0.2x)+y", op0);break;
case 0x58:sprintf(s, "eor $%0.2x,#$%0.2x", op1, op0);break;
case 0x59:sprintf(s, "eor (x),(y)", op0);break;
case 0x5a:sprintf(s, "cmpw ya,$%0.2x", op0);break;
case 0x5b:sprintf(s, "lsr $%0.2x+x", op0);break;
case 0x5c:sprintf(s, "lsr a");break;
case 0x5d:sprintf(s, "mov x,a");break;
case 0x5e:sprintf(s, "cmp y,$%0.4x", opw);break;
case 0x5f:sprintf(s, "jmp $%0.4x", opw);break;
case 0x60:sprintf(s, "clrc");break;
case 0x61:sprintf(s, "tcall 6");break;
case 0x62:sprintf(s, "set3 $%0.2x", op0);break;
case 0x63:sprintf(s, "bbs3 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x64:sprintf(s, "cmp a,$%0.2x", op0);break;
case 0x65:sprintf(s, "cmp a,$%0.4x", opw);break;
case 0x66:sprintf(s, "cmp a,(x)", op0);break;
case 0x67:sprintf(s, "cmp a,($%0.2x+x)", op0);break;
case 0x68:sprintf(s, "cmp a,#$%0.2x", op0);break;
case 0x69:sprintf(s, "cmp ($%0.2x),($%0.2x)", op1, op0);break;
case 0x6a:sprintf(s, "and1 c,!$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
case 0x6b:sprintf(s, "ror $%0.2x", op0);break;
case 0x6c:sprintf(s, "ror $%0.4x", opw);break;
case 0x6d:sprintf(s, "push y");break;
case 0x6e:sprintf(s, "dbnz $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x6f:sprintf(s, "ret");break;
case 0x70:sprintf(s, "bvs $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0x71:sprintf(s, "tcall 7");break;
case 0x72:sprintf(s, "clr3 $%0.2x", op0);break;
case 0x73:sprintf(s, "bbc3 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x74:sprintf(s, "cmp a,$%0.2x+x", op0);break;
case 0x75:sprintf(s, "cmp a,$%0.4x+x", opw);break;
case 0x76:sprintf(s, "cmp a,$%0.4x+y", opw);break;
case 0x77:sprintf(s, "cmp a,($%0.2x)+y", op0);break;
case 0x78:sprintf(s, "cmp $%0.2x,#$%0.2x", op1, op0);break;
case 0x79:sprintf(s, "cmp (x),(y)");break;
case 0x7a:sprintf(s, "addw ya,$%0.2x", op0);break;
case 0x7b:sprintf(s, "ror $%0.2x+x", op0);break;
case 0x7c:sprintf(s, "ror a");break;
case 0x7d:sprintf(s, "mov a,x");break;
case 0x7e:sprintf(s, "cmp y,$%0.2x", op0);break;
case 0x7f:sprintf(s, "reti");break;
case 0x80:sprintf(s, "setc");break;
case 0x81:sprintf(s, "tcall 8");break;
case 0x82:sprintf(s, "set4 $%0.2x", op0);break;
case 0x83:sprintf(s, "bbs4 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x84:sprintf(s, "adc a,$%0.2x", op0);break;
case 0x85:sprintf(s, "adc a,$%0.4x", opw);break;
case 0x86:sprintf(s, "adc a,(x)", op0);break;
case 0x87:sprintf(s, "adc a,($%0.2x+x)", op0);break;
case 0x88:sprintf(s, "adc a,#$%0.2x", op0);break;
case 0x89:sprintf(s, "adc ($%0.2x),($%0.2x)", op1, op0);break;
case 0x8a:sprintf(s, "eor1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
case 0x8b:sprintf(s, "dec $%0.2x", op0);break;
case 0x8c:sprintf(s, "dec $%0.4x", opw);break;
case 0x8d:sprintf(s, "mov y,#$%0.2x", op0);break;
case 0x8e:sprintf(s, "pop psw");break;
case 0x8f:sprintf(s, "mov $%0.2x,#$%0.2x", op1, op0);break;
case 0x90:sprintf(s, "bcc $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0x91:sprintf(s, "tcall 9");break;
case 0x92:sprintf(s, "clr4 $%0.2x", op0);break;
case 0x93:sprintf(s, "bbc4 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0x94:sprintf(s, "adc a,$%0.2x+x", op0);break;
case 0x95:sprintf(s, "adc a,$%0.4x+x", opw);break;
case 0x96:sprintf(s, "adc a,$%0.4x+y", opw);break;
case 0x97:sprintf(s, "adc a,($%0.2x)+y", op0);break;
case 0x98:sprintf(s, "adc $%0.2x,#$%0.2x", op1, op0);break;
case 0x99:sprintf(s, "adc (x),(y)", op0);break;
case 0x9a:sprintf(s, "subw ya,$%0.2x", op0);break;
case 0x9b:sprintf(s, "dec $%0.2x+x", op0);break;
case 0x9c:sprintf(s, "dec a");break;
case 0x9d:sprintf(s, "mov x,sp");break;
case 0x9e:sprintf(s, "div ya,x");break;
case 0x9f:sprintf(s, "xcn a");break;
case 0xa0:sprintf(s, "ei");break;
case 0xa1:sprintf(s, "tcall 10");break;
case 0xa2:sprintf(s, "set5 $%0.2x", op0);break;
case 0xa3:sprintf(s, "bbs5 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0xa4:sprintf(s, "sbc a,$%0.2x", op0);break;
case 0xa5:sprintf(s, "sbc a,$%0.4x", opw);break;
case 0xa6:sprintf(s, "sbc a,(x)", op0);break;
case 0xa7:sprintf(s, "sbc a,($%0.2x+x)", op0);break;
case 0xa8:sprintf(s, "sbc a,#$%0.2x", op0);break;
case 0xa9:sprintf(s, "sbc ($%0.2x),($%0.2x)", op1, op0);break;
case 0xaa:sprintf(s, "mov1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
case 0xab:sprintf(s, "inc $%0.2x", op0);break;
case 0xac:sprintf(s, "inc $%0.4x", opw);break;
case 0xad:sprintf(s, "cmp y,#$%0.2x", op0);break;
case 0xae:sprintf(s, "pop a");break;
case 0xaf:sprintf(s, "mov (x)+,a");break;
case 0xb0:sprintf(s, "bcs $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0xb1:sprintf(s, "tcall 11");break;
case 0xb2:sprintf(s, "clr5 $%0.2x", op0);break;
case 0xb3:sprintf(s, "bbc5 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0xb4:sprintf(s, "sbc a,$%0.2x+x", op0);break;
case 0xb5:sprintf(s, "sbc a,$%0.4x+x", opw);break;
case 0xb6:sprintf(s, "sbc a,$%0.4x+y", opw);break;
case 0xb7:sprintf(s, "sbc a,($%0.2x)+y", op0);break;
case 0xb8:sprintf(s, "sbc $%0.2x,#$%0.2x", op1, op0);break;
case 0xb9:sprintf(s, "sbc (x),(y)", op0);break;
case 0xba:sprintf(s, "movw ya,$%0.2x", op0);break;
case 0xbb:sprintf(s, "inc $%0.2x+x", op0);break;
case 0xbc:sprintf(s, "inc a");break;
case 0xbd:sprintf(s, "mov sp,x");break;
case 0xbe:sprintf(s, "das a");break;
case 0xbf:sprintf(s, "mov a,(x)+");break;
case 0xc0:sprintf(s, "di");break;
case 0xc1:sprintf(s, "tcall 12");break;
case 0xc2:sprintf(s, "set6 $%0.2x", op0);break;
case 0xc3:sprintf(s, "bbs6 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0xc4:sprintf(s, "mov $%0.2x,a", op0);break;
case 0xc5:sprintf(s, "mov $%0.4x,a", opw);break;
case 0xc6:sprintf(s, "mov (x),a");break;
case 0xc7:sprintf(s, "mov ($%0.2x+x),a", op0);break;
case 0xc8:sprintf(s, "cmp x,#$%0.2x", op0);break;
case 0xc9:sprintf(s, "mov $%0.4x,x", opw);break;
case 0xca:sprintf(s, "mov1 $%0.4x,%d,c", opw & 0x1fff, opw >> 13);break;
case 0xcb:sprintf(s, "mov $%0.2x,y", op0);break;
case 0xcc:sprintf(s, "asl $%0.4x", opw);break;
case 0xcd:sprintf(s, "mov x,#$%0.2x", op0);break;
case 0xce:sprintf(s, "pop x");break;
case 0xcf:sprintf(s, "mul ya");break;
case 0xd0:sprintf(s, "bne $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0xd1:sprintf(s, "tcall 13");break;
case 0xd2:sprintf(s, "clr6 $%0.2x", op0);break;
case 0xd3:sprintf(s, "bbc6 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0xd4:sprintf(s, "mov $%0.2x+x,a", op0);break;
case 0xd5:sprintf(s, "mov $%0.4x+x,a", opw);break;
case 0xd6:sprintf(s, "mov $%0.4x+y,a", opw);break;
case 0xd7:sprintf(s, "mov ($%0.2x)+y,a", op0);break;
case 0xd8:sprintf(s, "mov $%0.2x,x", op0);break;
case 0xd9:sprintf(s, "mov $%0.2x+y,x", op0);break;
case 0xda:sprintf(s, "movw $%0.2x,ya", op0);break;
case 0xdb:sprintf(s, "mov $%0.2x+x,y", op0);break;
case 0xdc:sprintf(s, "dec y");break;
case 0xdd:sprintf(s, "mov a,y");break;
case 0xde:sprintf(s, "cbne $%0.2x+x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0xdf:sprintf(s, "daa a");break;
case 0xe0:sprintf(s, "clrv");break;
case 0xe1:sprintf(s, "tcall 14");break;
case 0xe2:sprintf(s, "set7 $%0.2x", op0);break;
case 0xe3:sprintf(s, "bbs7 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0xe4:sprintf(s, "mov a,$%0.2x", op0);break;
case 0xe5:sprintf(s, "mov a,$%0.4x", opw);break;
case 0xe6:sprintf(s, "mov a,(x)");break;
case 0xe7:sprintf(s, "mov a,($%0.2x+x)", op0);break;
case 0xe8:sprintf(s, "mov a,#$%0.2x", op0);break;
case 0xe9:sprintf(s, "mov x,$%0.4x", opw);break;
case 0xea:sprintf(s, "not1 $%0.4x,%d", opw & 0x1fff, opw >> 13);break;
case 0xeb:sprintf(s, "mov y,$%0.2x", op0);break;
case 0xec:sprintf(s, "mov y,$%0.4x", opw);break;
case 0xed:sprintf(s, "notc");break;
case 0xee:sprintf(s, "pop y");break;
case 0xef:sprintf(s, "sleep");break;
case 0xf0:sprintf(s, "beq $%0.4x", __disas_spc700_relb(op0, 2));break;
case 0xf1:sprintf(s, "tcall 15");break;
case 0xf2:sprintf(s, "clr7 $%0.2x", op0);break;
case 0xf3:sprintf(s, "bbc7 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
case 0xf4:sprintf(s, "mov a,$%0.2x+x", op0);break;
case 0xf5:sprintf(s, "mov a,$%0.4x+x", opw);break;
case 0xf6:sprintf(s, "mov a,$%0.4x+y", opw);break;
case 0xf7:sprintf(s, "mov a,($%0.2x)+y", op0);break;
case 0xf8:sprintf(s, "mov x,$%0.2x", op0);break;
case 0xf9:sprintf(s, "mov x,$%0.2x+y", op0);break;
case 0xfa:sprintf(s, "mov ($%0.2x),($%0.2x)", op1, op0);break;
case 0xfb:sprintf(s, "mov y,$%0.2x+x", op0);break;
case 0xfc:sprintf(s, "inc y");break;
case 0xfd:sprintf(s, "mov y,a");break;
case 0xfe:sprintf(s, "dbnz y,$%0.4x", __disas_spc700_relb(op0, 2));break;
case 0xff:sprintf(s, "stop");break;
}
}
void disas_spc700_op(void) {
byte op;
byte op0, op1;
word offset;
char flags[256];
char *s = (char*)__disas_spc700_str;
int i;
if(debug_write_status() == DEBUGWRITE_NONE)return;
//use offset instead of spc700->regs.pc + n to avoid going above 65535
offset = spc700->regs.pc;
op = spc700->ram[offset++];
op0 = spc700->ram[offset++];
op1 = spc700->ram[offset ];
strcpy(__disas_spc700_str, "???");
__disas_spc700_op(op, op0, op1);
i = strlen(s);
while(i < 23) {
s[i++] = ' ';
s[i] = 0;
}
sprintf(flags, "%c%c%c%c%c%c%c%c",
(spc700->regs.p & 0x80)?'N':'n',
(spc700->regs.p & 0x40)?'V':'v',
(spc700->regs.p & 0x20)?'P':'p',
(spc700->regs.p & 0x10)?'B':'b',
(spc700->regs.p & 0x08)?'H':'h',
(spc700->regs.p & 0x04)?'I':'i',
(spc700->regs.p & 0x02)?'Z':'z',
(spc700->regs.p & 0x01)?'C':'c');
dprintf(DEBUGMSG_APU, "--%0.4x %s A:%0.2x X:%0.2x Y:%0.2x SP:%0.2x YA:%0.4x %s",
spc700->regs.pc, __disas_spc700_str,
spc700->regs.a, spc700->regs.x, spc700->regs.y, spc700->regs.sp,
(spc700->regs.y << 8) | (spc700->regs.a), flags);
}
+49
View File
@@ -0,0 +1,49 @@
#include "../base.h"
#include "../timing/timing.h"
#include "../bridge/bridge.h"
#include "spc700_iplrom.h"
#include "spc700.h"
extern snes_timer *snes_time;
extern debugstate debugger;
extern port_bridge *cpu_apu_bridge;
sony_spc700 *spc700;
#include "spc700_ops.cpp"
void sony_spc700::Reset(void) {
memset(ram, 0, 65536);
memcpy(ram + 0xffc0, spc700_iplrom, 64);
regs.pc = 0xffc0;
regs.a = regs.x = regs.y = regs.sp = 0x00;
regs.p = 0x02;
regs.dp = 0x0000;
}
void sony_spc700::exec_op(void) {
byte op;
op = spc700->ram[spc700->regs.pc];
spc700_optbl[op]();
debugger.apu_op_executed = true;
debugger.disas_apu_op = true;
debug_test_bp(BPSRC_SPCRAM, BP_EXEC, spc700->regs.pc, 0);
}
void sony_spc700::Run(void) {
if(snes_time->bridge.cpu_cycles >= snes_time->bridge.apu_cycles) {
exec_op();
}
if(snes_time->bridge.cpu_cycles >= 65536 && snes_time->bridge.apu_cycles >= 65536) {
snes_time->bridge.cpu_cycles &= 65535;
snes_time->bridge.apu_cycles &= 65535;
}
}
sony_spc700::sony_spc700() {
ram = (byte*)malloc(65536);
}
sony_spc700::~sony_spc700() {
if(ram)free(ram);
}
+24
View File
@@ -0,0 +1,24 @@
class sony_spc700 {
public:
struct {
word pc;
byte a, x, y, sp, p;
word dp;
}regs;
byte *ram;
void Reset(void);
void Run(void);
void exec_op(void);
word convert_address(byte mode, word addr);
byte mem_getbyte(word addr);
void mem_putbyte(word addr, byte value);
word mem_read(byte mode, byte size, word addr);
void mem_write(byte mode, byte size, word addr, word value);
byte stack_read(void);
void stack_write(byte value);
sony_spc700();
~sony_spc700();
};
+35
View File
@@ -0,0 +1,35 @@
byte spc700_iplrom[64] = {
/*ffc0*/ 0xcd, 0xef, //mov x,#$ef
/*ffc2*/ 0xbd, //mov sp,x
/*ffc3*/ 0xe8, 0x00, //mov a,#$00
/*ffc5*/ 0xc6, //mov (x),a
/*ffc6*/ 0x1d, //dec x
/*ffc7*/ 0xd0, 0xfc, //bne $ffc5
/*ffc9*/ 0x8f, 0xaa, 0xf4, //mov $f4,#$aa
/*ffcc*/ 0x8f, 0xbb, 0xf5, //mov $f5,#$bb
/*ffcf*/ 0x78, 0xcc, 0xf4, //cmp $f4,#$cc
/*ffd2*/ 0xd0, 0xfb, //bne $ffcf
/*ffd4*/ 0x2f, 0x19, //bra $ffef
/*ffd6*/ 0xeb, 0xf4, //mov y,$f4
/*ffd8*/ 0xd0, 0xfc, //bne $ffd6
/*ffda*/ 0x7e, 0xf4, //cmp y,$f4
/*ffdc*/ 0xd0, 0x0b, //bne $ffe9
/*ffde*/ 0xe4, 0xf5, //mov a,$f5
/*ffe0*/ 0xcb, 0xf4, //mov $f4,y
/*ffe2*/ 0xd7, 0x00, //mov ($00)+y,a
/*ffe4*/ 0xfc, //inc y
/*ffe5*/ 0xd0, 0xf3, //bne $ffda
/*ffe7*/ 0xab, 0x01, //inc $01
/*ffe9*/ 0x10, 0xef, //bpl $ffda
/*ffeb*/ 0x7e, 0xf4, //cmp y,$f4
/*ffed*/ 0x10, 0xeb, //bpl $ffda
/*ffef*/ 0xba, 0xf6, //movw ya,$f6
/*fff1*/ 0xda, 0x00, //movw $00,ya
/*fff3*/ 0xba, 0xf4, //movw ya,$f4
/*fff5*/ 0xc4, 0xf4, //mov $f4,a
/*fff7*/ 0xdd, //mov a,y
/*fff8*/ 0x5d, //mov x,a
/*fff9*/ 0xd0, 0xdb, //bne $ffd6
/*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x)
/*fffe*/ 0xc0, 0xff //---reset vector location ($ffc0)
};
+194
View File
@@ -0,0 +1,194 @@
#define spc700_setn() spc700->regs.p |= SPF_N
#define spc700_clrn() spc700->regs.p &= ~SPF_N
#define spc700_setv() spc700->regs.p |= SPF_V
#define spc700_clrv() spc700->regs.p &= ~SPF_V
#define spc700_setp() spc700->regs.p |= SPF_P;spc700->regs.dp = 0x0100
#define spc700_clrp() spc700->regs.p &= ~SPF_P;spc700->regs.dp = 0x0000
#define spc700_setb() spc700->regs.p |= SPF_B
#define spc700_clrb() spc700->regs.p &= ~SPF_B
#define spc700_seth() spc700->regs.p |= SPF_H
#define spc700_clrh() spc700->regs.p &= ~SPF_H
#define spc700_seti() spc700->regs.p |= SPF_I
#define spc700_clri() spc700->regs.p &= ~SPF_I
#define spc700_setz() spc700->regs.p |= SPF_Z
#define spc700_clrz() spc700->regs.p &= ~SPF_Z
#define spc700_setc() spc700->regs.p |= SPF_C
#define spc700_clrc() spc700->regs.p &= ~SPF_C
#define spc700_testn(x) if(x)spc700_setn(); else spc700_clrn()
#define spc700_testv(x) if(x)spc700_setv(); else spc700_clrv()
#define spc700_testp(x) if(x)spc700_setp(); else spc700_clrp()
#define spc700_testb(x) if(x)spc700_setb(); else spc700_clrb()
#define spc700_testh(x) if(x)spc700_seth(); else spc700_clrh()
#define spc700_testi(x) if(x)spc700_seti(); else spc700_clri()
#define spc700_testz(x) if(x)spc700_setz(); else spc700_clrz()
#define spc700_testc(x) if(x)spc700_setc(); else spc700_clrc()
#define spc700_incpc(__n) spc700->regs.pc += __n
#define spc700_prefetchb() \
byte arg = spc700->ram[(spc700->regs.pc + 1) & 0xffff]
#define spc700_prefetch2b() \
byte arg0 = spc700->ram[(spc700->regs.pc + 1) & 0xffff]; \
byte arg1 = spc700->ram[(spc700->regs.pc + 2) & 0xffff]
#define spc700_prefetchw() \
word arg = spc700->ram[(spc700->regs.pc + 1) & 0xffff] | (spc700->ram[(spc700->regs.pc + 2) & 0xffff] << 8)
#define APUMODE_NONE 0
#define APUMODE_DP 1
#define APUMODE_DPX 2
#define APUMODE_DPY 3
#define APUMODE_IDP 4
#define APUMODE_ADDR 5
#define APUMODE_IX 6
#define APUMODE_ADDRX 7
#define APUMODE_ADDRY 8
#define APUMODE_IDPX 9
#define APUMODE_IDPY 10
#define APUMODE_IADDRX 11
#define APUMODE_IY 12
word sony_spc700::convert_address(byte mode, word addr) {
word r;
switch(mode) {
case APUMODE_NONE:
r = addr;
case APUMODE_DP:
r = spc700->regs.dp | (byte)addr;
break;
case APUMODE_DPX:
r = spc700->regs.dp | (byte)(addr + spc700->regs.x);
break;
case APUMODE_DPY:
r = spc700->regs.dp | (byte)(addr + spc700->regs.y);
break;
case APUMODE_IDP:
r = spc700->regs.dp | (byte)addr;
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
break;
case APUMODE_ADDR:
r = addr;
break;
case APUMODE_IX:
r = spc700->regs.dp | spc700->regs.x;
break;
case APUMODE_ADDRX:
r = addr + spc700->regs.x;
break;
case APUMODE_ADDRY:
r = addr + spc700->regs.y;
break;
case APUMODE_IDPX:
r = spc700->regs.dp | (byte)(addr + spc700->regs.x);
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
break;
case APUMODE_IDPY:
r = spc700->regs.dp | (byte)addr;
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
r += spc700->regs.y;
break;
case APUMODE_IADDRX:
r = (spc700->ram[(addr + spc700->regs.x )]) |
(spc700->ram[(addr + spc700->regs.x + 1)] << 8);
break;
case APUMODE_IY:
r = spc700->regs.dp | spc700->regs.y;
break;
}
return r;
}
byte sony_spc700::mem_getbyte(word addr) {
if(addr >= 0x00f4 && addr <= 0x00f7) {
return cpu_apu_bridge->apu_read(addr - 0x00f4);
} else {
return spc700->ram[addr];
}
}
void sony_spc700::mem_putbyte(word addr, byte value) {
if(addr >= 0x00f4 && addr <= 0x00f7) {
cpu_apu_bridge->apu_write(addr - 0x00f4, value);
} else if(addr < 0xffc0) {
spc700->ram[addr] = value;
}
}
word sony_spc700::mem_read(byte mode, byte size, word addr) {
word r;
addr = convert_address(mode, addr);
switch(size) {
case MEMSIZE_BYTE:
r = mem_getbyte(addr);
break;
case MEMSIZE_WORD:
r = mem_getbyte(addr) | (mem_getbyte(addr + 1) << 8);
break;
}
return r;
}
void sony_spc700::mem_write(byte mode, byte size, word addr, word value) {
addr = convert_address(mode, addr);
switch(size) {
case MEMSIZE_BYTE:
mem_putbyte(addr, value);
break;
case MEMSIZE_WORD:
mem_putbyte(addr , value);
mem_putbyte(addr + 1, value >> 8);
break;
}
}
byte sony_spc700::stack_read(void) {
word addr;
spc700->regs.sp++;
addr = 0x0100 | spc700->regs.sp;
return mem_getbyte(addr);
}
void sony_spc700::stack_write(byte value) {
word addr;
addr = 0x0100 | spc700->regs.sp;
spc700->regs.sp--;
mem_putbyte(addr, value);
}
#include "spc700_ops_adc.cpp"
#include "spc700_ops_and.cpp"
#include "spc700_ops_cmp.cpp"
#include "spc700_ops_eor.cpp"
#include "spc700_ops_flags.cpp"
#include "spc700_ops_incdec.cpp"
#include "spc700_ops_misc.cpp"
#include "spc700_ops_mov.cpp"
#include "spc700_ops_or.cpp"
#include "spc700_ops_pc.cpp"
#include "spc700_ops_sbc.cpp"
#include "spc700_ops_shift.cpp"
#include "spc700_ops_stack.cpp"
vfunc spc700_optbl[256] = {
// -----------------------------x0, -----------------------------x1, -----------------------------x2, -----------------------------x3, -------- -----------------------------x4, -----------------------------x5, -----------------------------x6, -----------------------------x7, -------- -----------------------------x8, -----------------------------x9, -----------------------------xa, -----------------------------xb, -------- -----------------------------xc, -----------------------------xd, -----------------------------xe, -----------------------------xf,
/* 0x */ spc700_op_nop, spc700_op_tcall_0, spc700_op_set0_dp, spc700_op_bbc0, /* 0x */ spc700_op_or_a_dp, spc700_op_or_a_addr, spc700_op_or_a_ix, spc700_op_or_a_idpx, /* 0x */ spc700_op_or_a_const, spc700_op_or_dp_dp, spc700_op_or1_bit, spc700_op_asl_dp, /* 0x */ spc700_op_mov_addr_y, spc700_op_push_p, spc700_op_tset1_addr, spc700_op_brk,
/* 1x */ spc700_op_bpl, spc700_op_tcall_1, spc700_op_clr0_dp, spc700_op_bbs0, /* 1x */ spc700_op_or_a_dpx, spc700_op_or_a_addrx, spc700_op_or_a_addry, spc700_op_or_a_idpy, /* 1x */ spc700_op_or_dp_imm, spc700_op_or_ix_iy, spc700_op_decw_dp, spc700_op_asl_dpx, /* 1x */ spc700_op_asl_a, spc700_op_dec_x, spc700_op_cmp_x_addr, spc700_op_jmp_iaddrx,
/* 2x */ spc700_op_clrp, spc700_op_tcall_2, spc700_op_set1_dp, spc700_op_bbc1, /* 2x */ spc700_op_and_a_dp, spc700_op_and_a_addr, spc700_op_and_a_ix, spc700_op_and_a_idpx, /* 2x */ spc700_op_and_a_const, spc700_op_and_dp_dp, spc700_op_or1_notbit, spc700_op_rol_dp, /* 2x */ spc700_op_rol_addr, spc700_op_push_a, spc700_op_cbne_dp, spc700_op_bra,
/* 3x */ spc700_op_bmi, spc700_op_tcall_3, spc700_op_clr1_dp, spc700_op_bbs1, /* 3x */ spc700_op_and_a_dpx, spc700_op_and_a_addrx, spc700_op_and_a_addry, spc700_op_and_a_idpy, /* 3x */ spc700_op_and_dp_imm, spc700_op_and_ix_iy, spc700_op_incw_dp, spc700_op_rol_dpx, /* 3x */ spc700_op_rol_a, spc700_op_inc_x, spc700_op_cmp_x_dp, spc700_op_call,
/* 4x */ spc700_op_setp, spc700_op_tcall_4, spc700_op_set2_dp, spc700_op_bbc2, /* 4x */ spc700_op_eor_a_dp, spc700_op_eor_a_addr, spc700_op_eor_a_ix, spc700_op_eor_a_idpx, /* 4x */ spc700_op_eor_a_const, spc700_op_eor_dp_dp, spc700_op_and1_bit, spc700_op_lsr_dp, /* 4x */ spc700_op_lsr_addr, spc700_op_push_x, spc700_op_tclr1_addr, spc700_op_pcall,
/* 5x */ spc700_op_bvc, spc700_op_tcall_5, spc700_op_clr2_dp, spc700_op_bbs2, /* 5x */ spc700_op_eor_a_dpx, spc700_op_eor_a_addrx, spc700_op_eor_a_addry, spc700_op_eor_a_idpy, /* 5x */ spc700_op_eor_dp_imm, spc700_op_eor_ix_iy, spc700_op_cmpw_ya_dp, spc700_op_lsr_dpx, /* 5x */ spc700_op_lsr_a, spc700_op_mov_x_a, spc700_op_cmp_y_addr, spc700_op_jmp_addr,
/* 6x */ spc700_op_clrc, spc700_op_tcall_6, spc700_op_set3_dp, spc700_op_bbc3, /* 6x */ spc700_op_cmp_a_dp, spc700_op_cmp_a_addr, spc700_op_cmp_a_ix, spc700_op_cmp_a_idpx, /* 6x */ spc700_op_cmp_a_const, spc700_op_cmp_dp_dp, spc700_op_and1_notbit, spc700_op_ror_dp, /* 6x */ spc700_op_ror_addr, spc700_op_push_y, spc700_op_dbnz_dp, spc700_op_ret,
/* 7x */ spc700_op_bvs, spc700_op_tcall_7, spc700_op_clr3_dp, spc700_op_bbs3, /* 7x */ spc700_op_cmp_a_dpx, spc700_op_cmp_a_addrx, spc700_op_cmp_a_addry, spc700_op_cmp_a_idpy, /* 7x */ spc700_op_cmp_dp_imm, spc700_op_cmp_ix_iy, spc700_op_addw_ya_dp, spc700_op_ror_dpx, /* 7x */ spc700_op_ror_a, spc700_op_mov_a_x, spc700_op_cmp_y_dp, spc700_op_reti,
/* 8x */ spc700_op_setc, spc700_op_tcall_8, spc700_op_set4_dp, spc700_op_bbc4, /* 8x */ spc700_op_adc_a_dp, spc700_op_adc_a_addr, spc700_op_adc_a_ix, spc700_op_adc_a_idpx, /* 8x */ spc700_op_adc_a_const, spc700_op_adc_dp_dp, spc700_op_eor1_bit, spc700_op_dec_dp, /* 8x */ spc700_op_dec_addr, spc700_op_mov_y_const, spc700_op_pop_p, spc700_op_mov_dp_imm,
/* 9x */ spc700_op_bcc, spc700_op_tcall_9, spc700_op_clr4_dp, spc700_op_bbs4, /* 9x */ spc700_op_adc_a_dpx, spc700_op_adc_a_addrx, spc700_op_adc_a_addry, spc700_op_adc_a_idpy, /* 9x */ spc700_op_adc_dp_imm, spc700_op_adc_ix_iy, spc700_op_subw_ya_dp, spc700_op_dec_dpx, /* 9x */ spc700_op_dec_a, spc700_op_mov_x_sp, spc700_op_div_ya_x, spc700_op_xcn_a,
/* ax */ spc700_op_ei, spc700_op_tcall_10, spc700_op_set5_dp, spc700_op_bbc5, /* ax */ spc700_op_sbc_a_dp, spc700_op_sbc_a_addr, spc700_op_sbc_a_ix, spc700_op_sbc_a_idpx, /* ax */ spc700_op_sbc_a_const, spc700_op_sbc_dp_dp, spc700_op_mov1_c_bit, spc700_op_inc_dp, /* ax */ spc700_op_inc_addr, spc700_op_cmp_y_const, spc700_op_pop_a, spc700_op_mov_ixinc_a,
/* bx */ spc700_op_bcs, spc700_op_tcall_11, spc700_op_clr5_dp, spc700_op_bbs5, /* bx */ spc700_op_sbc_a_dpx, spc700_op_sbc_a_addrx, spc700_op_sbc_a_addry, spc700_op_sbc_a_idpy, /* bx */ spc700_op_sbc_dp_imm, spc700_op_sbc_ix_iy, spc700_op_mov_ya_dp, spc700_op_inc_dpx, /* bx */ spc700_op_inc_a, spc700_op_mov_sp_x, spc700_op_das_a, spc700_op_mov_a_ixinc,
/* cx */ spc700_op_di, spc700_op_tcall_12, spc700_op_set6_dp, spc700_op_bbc6, /* cx */ spc700_op_mov_dp_a, spc700_op_mov_addr_a, spc700_op_mov_ix_a, spc700_op_mov_idpx_a, /* cx */ spc700_op_cmp_x_const, spc700_op_mov_addr_x, spc700_op_mov1_bit_c, spc700_op_mov_dp_y, /* cx */ spc700_op_asl_addr, spc700_op_mov_x_const, spc700_op_pop_x, spc700_op_mul_ya,
/* dx */ spc700_op_bne, spc700_op_tcall_13, spc700_op_clr6_dp, spc700_op_bbs6, /* dx */ spc700_op_mov_dpx_a, spc700_op_mov_addrx_a, spc700_op_mov_addry_a, spc700_op_mov_idpy_a, /* dx */ spc700_op_mov_dp_x, spc700_op_mov_dpy_x, spc700_op_mov_dp_ya, spc700_op_mov_dpx_y, /* dx */ spc700_op_dec_y, spc700_op_mov_a_y, spc700_op_cbne_dpx, spc700_op_daa_a,
/* ex */ spc700_op_clrv, spc700_op_tcall_14, spc700_op_set7_dp, spc700_op_bbc7, /* ex */ spc700_op_mov_a_dp, spc700_op_mov_a_addr, spc700_op_mov_a_ix, spc700_op_mov_a_idpx, /* ex */ spc700_op_mov_a_const, spc700_op_mov_x_addr, spc700_op_not1_bit, spc700_op_mov_y_dp, /* ex */ spc700_op_mov_y_addr, spc700_op_notc, spc700_op_pop_y, spc700_op_sleep,
/* fx */ spc700_op_beq, spc700_op_tcall_15, spc700_op_clr7_dp, spc700_op_bbs7, /* fx */ spc700_op_mov_a_dpx, spc700_op_mov_a_addrx, spc700_op_mov_a_addry, spc700_op_mov_a_idpy, /* fx */ spc700_op_mov_x_dp, spc700_op_mov_x_dpy, spc700_op_mov_dp_dp, spc700_op_mov_y_dpx, /* fx */ spc700_op_inc_y, spc700_op_mov_y_a, spc700_op_dbnz_y, spc700_op_stop
};
+114
View File
@@ -0,0 +1,114 @@
byte spc700_op_adc(byte x, byte y) {
word r = x + y + (spc700->regs.p & SPF_C);
spc700_testn(r & 0x80);
spc700_testv((~(x ^ y) & (y ^ (byte)r) & 0x80));
spc700_testh((x ^ y ^ (byte)r) & 0x10);
spc700_testz((byte)r == 0);
spc700_testc(r >= 0x100);
return (byte)r;
}
void spc700_op_adc_a_const(void) {
spc700_prefetchb();
spc700->regs.a = spc700_op_adc(spc700->regs.a, arg);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_adc_a_ix(void) {
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_adc_a_dp(void) {
spc700_prefetchb();
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_adc_a_dpx(void) {
spc700_prefetchb();
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_adc_a_addr(void) {
spc700_prefetchw();
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_adc_a_addrx(void) {
spc700_prefetchw();
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_adc_a_addry(void) {
spc700_prefetchw();
spc700->regs.a += spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
spc700->regs.a += (spc700->regs.p & PF_C);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_adc_a_idpx(void) {
spc700_prefetchb();
word i;
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_adc_a_idpy(void) {
spc700_prefetchb();
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_adc_ix_iy(void) {
byte x = spc700_op_adc(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
spc700_incpc(1);
add_apu_cycles(5);
}
void spc700_op_adc_dp_dp(void) {
spc700_prefetch2b();
byte x = spc700_op_adc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_adc_dp_imm(void) {
spc700_prefetch2b();
byte x = spc700_op_adc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_addw_ya_dp(void) {
spc700_prefetchb();
word ya = (spc700->regs.y << 8) | spc700->regs.a;
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
ulong r = ya + dp;
spc700_testn(r & 0x8000);
spc700_testv(~(ya ^ dp) & (dp ^ (word)r) & 0x8000);
spc700_testh((ya ^ dp ^ (word)r) & 0x1000);
spc700_testz((word)r == 0);
spc700_testc(r >= 0x10000);
spc700->regs.a = r;
spc700->regs.y = r >> 8;
spc700_incpc(2);
add_apu_cycles(5);
}
+147
View File
@@ -0,0 +1,147 @@
void spc700_op_and_a_const(void) {
spc700_prefetchb();
spc700->regs.a &= arg;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_and_a_ix(void) {
spc700->regs.a &= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_and_a_dp(void) {
spc700_prefetchb();
spc700->regs.a &= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_and_a_dpx(void) {
spc700_prefetchb();
spc700->regs.a &= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_and_a_addr(void) {
spc700_prefetchw();
spc700->regs.a &= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_and_a_addrx(void) {
spc700_prefetchw();
spc700->regs.a &= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_and_a_addry(void) {
spc700_prefetchw();
spc700->regs.a &= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_and_a_idpx(void) {
spc700_prefetchb();
word i;
spc700->regs.a &= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_and_a_idpy(void) {
spc700_prefetchb();
word i;
spc700->regs.a &= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_and_ix_iy(void) {
word i;
byte x;
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
x &= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(1);
add_apu_cycles(5);
}
void spc700_op_and_dp_dp(void) {
spc700_prefetch2b();
byte x;
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
x &= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_and_dp_imm(void) {
spc700_prefetch2b();
byte x;
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
x &= arg0;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_and1_bit(void) {
spc700_prefetchw();
word addr = arg & 0x1fff;
byte bit = arg >> 13;
byte x;
if(spc700->regs.p & SPF_C) {
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
if(!(x & (1 << bit))) {
spc700_clrc();
}
}
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_and1_notbit(void) {
spc700_prefetchw();
word addr = arg & 0x1fff;
byte bit = arg >> 13;
byte x;
if(spc700->regs.p & SPF_C) {
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
if(x & (1 << bit)) {
spc700_clrc();
}
}
spc700_incpc(3);
add_apu_cycles(4);
}
+142
View File
@@ -0,0 +1,142 @@
void spc700_op_cmp(byte x, byte y) {
short r = (short)x - (short)y;
spc700_testn(r & 0x80);
spc700_testz((byte)r == 0);
spc700_testc(r >= 0);
}
void spc700_op_cmp_a_const(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.a, arg);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_cmp_a_ix(void) {
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_cmp_a_dp(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_cmp_a_dpx(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_cmp_a_addr(void) {
spc700_prefetchw();
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_cmp_a_addrx(void) {
spc700_prefetchw();
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_cmp_a_addry(void) {
spc700_prefetchw();
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_cmp_a_idpx(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_cmp_a_idpy(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_cmp_ix_iy(void) {
spc700_op_cmp(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
spc700_incpc(1);
add_apu_cycles(5);
}
void spc700_op_cmp_dp_dp(void) {
spc700_prefetch2b();
spc700_op_cmp(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_cmp_dp_imm(void) {
spc700_prefetch2b();
spc700_op_cmp(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_cmp_x_const(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.x, arg);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_cmp_x_dp(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.x, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_cmp_x_addr(void) {
spc700_prefetchw();
spc700_op_cmp(spc700->regs.x, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_cmp_y_const(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.y, arg);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_cmp_y_dp(void) {
spc700_prefetchb();
spc700_op_cmp(spc700->regs.y, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_cmp_y_addr(void) {
spc700_prefetchw();
spc700_op_cmp(spc700->regs.y, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_cmpw_ya_dp(void) {
spc700_prefetchb();
word ya = ((spc700->regs.y << 8) | spc700->regs.a);
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
long r = (long)ya - (long)dp;
spc700_testn(r & 0x8000);
spc700_testz((word)r == 0);
spc700_testc(r >= 0);
spc700_incpc(2);
add_apu_cycles(5);
}
+148
View File
@@ -0,0 +1,148 @@
void spc700_op_eor_a_const(void) {
spc700_prefetchb();
spc700->regs.a ^= arg;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_eor_a_ix(void) {
spc700->regs.a ^= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_eor_a_dp(void) {
spc700_prefetchb();
spc700->regs.a ^= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_eor_a_dpx(void) {
spc700_prefetchb();
spc700->regs.a ^= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_eor_a_addr(void) {
spc700_prefetchw();
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_eor_a_addrx(void) {
spc700_prefetchw();
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_eor_a_addry(void) {
spc700_prefetchw();
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_eor_a_idpx(void) {
spc700_prefetchb();
word i;
spc700->regs.a ^= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_eor_a_idpy(void) {
spc700_prefetchb();
word i;
spc700->regs.a ^= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_eor_ix_iy(void) {
word i;
byte x;
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
x ^= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(1);
add_apu_cycles(5);
}
void spc700_op_eor_dp_dp(void) {
spc700_prefetch2b();
byte x;
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
x ^= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_eor_dp_imm(void) {
spc700_prefetch2b();
byte x;
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
x ^= arg0;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_eor1_bit(void) {
spc700_prefetchw();
word addr = arg & 0x1fff;
byte bit = arg >> 13;
byte x;
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
if(spc700->regs.p & SPF_C) {
if(x & (1 << bit)) {
spc700_clrc();
}
} else {
if(x & (1 << bit)) {
spc700_setc();
}
}
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_not1_bit(void) {
spc700_prefetchw();
word addr = arg & 0x1fff;
byte bit = arg >> 13;
byte x;
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
x ^= (1 << bit);
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, addr, x);
spc700_incpc(3);
add_apu_cycles(5);
}
+48
View File
@@ -0,0 +1,48 @@
void spc700_op_clrc(void) {
spc700_clrc();
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_setc(void) {
spc700_setc();
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_notc(void) {
spc700->regs.p ^= SPF_C;
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_clrv(void) {
spc700_clrv();
spc700_clrh();
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_clrp(void) {
spc700_clrp();
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_setp(void) {
spc700_setp();
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_di(void) {
spc700_clri();
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_ei(void) {
spc700_seti();
spc700_incpc(1);
add_apu_cycles(2);
}
+135
View File
@@ -0,0 +1,135 @@
void spc700_op_inc_a(void) {
spc700->regs.a++;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_inc_x(void) {
spc700->regs.x++;
spc700_testn(spc700->regs.x & 0x80);
spc700_testz(spc700->regs.x == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_inc_y(void) {
spc700->regs.y++;
spc700_testn(spc700->regs.y & 0x80);
spc700_testz(spc700->regs.y == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_inc_dp(void) {
spc700_prefetchb();
byte r;
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg) + 1;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, r);
spc700_testn(r & 0x80);
spc700_testz(r == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_inc_dpx(void) {
spc700_prefetchb();
byte r;
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg) + 1;
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, r);
spc700_testn(r & 0x80);
spc700_testz(r == 0);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_inc_addr(void) {
spc700_prefetchw();
byte r;
r = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg) + 1;
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, r);
spc700_testn(r & 0x80);
spc700_testz(r == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_dec_a(void) {
spc700->regs.a--;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_dec_x(void) {
spc700->regs.x--;
spc700_testn(spc700->regs.x & 0x80);
spc700_testz(spc700->regs.x == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_dec_y(void) {
spc700->regs.y--;
spc700_testn(spc700->regs.y & 0x80);
spc700_testz(spc700->regs.y == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_dec_dp(void) {
spc700_prefetchb();
byte r;
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg) - 1;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, r);
spc700_testn(r & 0x80);
spc700_testz(r == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_dec_dpx(void) {
spc700_prefetchb();
byte r;
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg) - 1;
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, r);
spc700_testn(r & 0x80);
spc700_testz(r == 0);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_dec_addr(void) {
spc700_prefetchw();
byte r;
r = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg) - 1;
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, r);
spc700_testn(r & 0x80);
spc700_testz(r == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_incw_dp(void) {
spc700_prefetchb();
word r;
r = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg) + 1;
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, r);
spc700_testn(r & 0x8000);
spc700_testz(r == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_decw_dp(void) {
spc700_prefetchb();
word r;
r = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg) - 1;
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, r);
spc700_testn(r & 0x8000);
spc700_testz(r == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
+241
View File
@@ -0,0 +1,241 @@
void spc700_op_nop(void) {
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_sleep(void) {
add_apu_cycles(3);
}
void spc700_op_stop(void) {
add_apu_cycles(3);
}
void spc700_op_xcn_a(void) {
spc700->regs.a = (spc700->regs.a >> 4) | (spc700->regs.a << 4);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(5);
}
void spc700_op_daa_a(void) {
int a = spc700->regs.a;
if(((a ) & 15) > 9)a += 6;
if(((a >> 4) & 15) > 9)a += 6 << 4;
spc700->regs.a = a;
spc700_testn(a & 0x80);
spc700_testz(a == 0);
spc700_testc(a >= 0x0100);
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_das_a(void) {
int a = spc700->regs.a;
if(((a ) & 15) > 9)a -= 6;
if(((a >> 4) & 15) > 9)a -= 6 << 4;
spc700->regs.a = a;
spc700_testn(a & 0x80);
spc700_testz(a == 0);
spc700_testc(a < 0);
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_set0_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x |= 0x01;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_clr0_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x &= ~0x01;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_set1_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x |= 0x02;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_clr1_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x &= ~0x02;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_set2_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x |= 0x04;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_clr2_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x &= ~0x04;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_set3_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x |= 0x08;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_clr3_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x &= ~0x08;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_set4_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x |= 0x10;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_clr4_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x &= ~0x10;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_set5_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x |= 0x20;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_clr5_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x &= ~0x20;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_set6_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x |= 0x40;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_clr6_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x &= ~0x40;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_set7_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x |= 0x80;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_clr7_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
x &= ~0x80;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_tset1_addr(void) {
spc700_prefetchw();
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
x |= spc700->regs.a;
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_tclr1_addr(void) {
spc700_prefetchw();
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
x &= ~spc700->regs.a;
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_mul_ya(void) {
word ya;
ya = spc700->regs.y * spc700->regs.a;
spc700->regs.a = ya;
spc700->regs.y = ya >> 8;
spc700_testn(ya & 0x8000);
spc700_testz(ya == 0);
spc700_incpc(1);
add_apu_cycles(9);
}
/*
v/h flags not set, may have result backwards
(a and y may need to be swapped)
*/
void spc700_op_div_ya_x(void) {
word ya = (spc700->regs.y << 8) | spc700->regs.a;
if(spc700->regs.x == 0) {
spc700->regs.a = 0;
spc700->regs.y = 0;
} else {
spc700->regs.a = ya / spc700->regs.x;
spc700->regs.y = ya % spc700->regs.x;
}
ya = (spc700->regs.y << 8) | spc700->regs.a;
spc700_testn(ya & 0x8000);
spc700_testz(ya == 0);
spc700_incpc(1);
add_apu_cycles(12);
}
+377
View File
@@ -0,0 +1,377 @@
void spc700_op_mov_a_x(void) {
spc700->regs.a = spc700->regs.x;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_mov_a_y(void) {
spc700->regs.a = spc700->regs.y;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_mov_x_a(void) {
spc700->regs.x = spc700->regs.a;
spc700_testn(spc700->regs.x & 0x80);
spc700_testz(spc700->regs.x == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_mov_y_a(void) {
spc700->regs.y = spc700->regs.a;
spc700_testn(spc700->regs.y & 0x80);
spc700_testz(spc700->regs.y == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_mov_x_sp(void) {
spc700->regs.x = spc700->regs.sp;
spc700_testn(spc700->regs.x & 0x80);
spc700_testz(spc700->regs.x == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_mov_sp_x(void) {
spc700->regs.sp = spc700->regs.x;
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_mov_dp_dp(void) {
spc700_prefetch2b();
byte x;
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_mov_dp_imm(void) {
spc700_prefetch2b();
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, arg0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_mov_a_const(void) {
spc700_prefetchb();
spc700->regs.a = arg;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_mov_x_const(void) {
spc700_prefetchb();
spc700->regs.x = arg;
spc700_testn(spc700->regs.x & 0x80);
spc700_testz(spc700->regs.x == 0);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_mov_y_const(void) {
spc700_prefetchb();
spc700->regs.y = arg;
spc700_testn(spc700->regs.y & 0x80);
spc700_testz(spc700->regs.y == 0);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_mov_ix_a(void) {
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, spc700->regs.a);
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_mov_ixinc_a(void) {
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, spc700->regs.a);
spc700->regs.x++;
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_mov_dp_a(void) {
spc700_prefetchb();
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.a);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_mov_dpx_a(void) {
spc700_prefetchb();
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, spc700->regs.a);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_mov_addr_a(void) {
spc700_prefetchw();
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.a);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_mov_addrx_a(void) {
spc700_prefetchw();
spc700->mem_write(APUMODE_ADDRX, MEMSIZE_BYTE, arg, spc700->regs.a);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_mov_addry_a(void) {
spc700_prefetchw();
spc700->mem_write(APUMODE_ADDRY, MEMSIZE_BYTE, arg, spc700->regs.a);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_mov_idpx_a(void) {
spc700_prefetchb();
word i;
spc700->mem_write(APUMODE_IDPX, MEMSIZE_BYTE, arg, spc700->regs.a);
spc700_incpc(2);
add_apu_cycles(7);
}
void spc700_op_mov_idpy_a(void) {
spc700_prefetchb();
word i;
spc700->mem_write(APUMODE_IDPY, MEMSIZE_BYTE, arg, spc700->regs.a);
spc700_incpc(2);
add_apu_cycles(7);
}
void spc700_op_mov_dp_x(void) {
spc700_prefetchb();
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.x);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_mov_dpy_x(void) {
spc700_prefetchb();
spc700->mem_write(APUMODE_DPY, MEMSIZE_BYTE, arg, spc700->regs.x);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_mov_addr_x(void) {
spc700_prefetchw();
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.x);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_mov_dp_y(void) {
spc700_prefetchb();
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.y);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_mov_dpx_y(void) {
spc700_prefetchb();
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, spc700->regs.y);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_mov_addr_y(void) {
spc700_prefetchw();
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.y);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_mov_a_ix(void) {
spc700->regs.a = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_mov_a_ixinc(void) {
spc700->regs.a = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
spc700->regs.x++;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_mov_a_dp(void) {
spc700_prefetchb();
spc700->regs.a = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_mov_a_dpx(void) {
spc700_prefetchb();
spc700->regs.a = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_mov_a_addr(void) {
spc700_prefetchw();
spc700->regs.a = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_mov_a_addrx(void) {
spc700_prefetchw();
spc700->regs.a = spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_mov_a_addry(void) {
spc700_prefetchw();
spc700->regs.a = spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_mov_a_idpx(void) {
spc700_prefetchb();
word i;
spc700->regs.a = spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_mov_a_idpy(void) {
spc700_prefetchb();
word i;
spc700->regs.a = spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_mov_x_dp(void) {
spc700_prefetchb();
spc700->regs.x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.x & 0x80);
spc700_testz(spc700->regs.x == 0);
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_mov_x_dpy(void) {
spc700_prefetchb();
spc700->regs.x = spc700->mem_read(APUMODE_DPY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.x & 0x80);
spc700_testz(spc700->regs.x == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_mov_x_addr(void) {
spc700_prefetchw();
spc700->regs.x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.x & 0x80);
spc700_testz(spc700->regs.x == 0);
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_mov_y_dp(void) {
spc700_prefetchb();
spc700->regs.y = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.y & 0x80);
spc700_testz(spc700->regs.y == 0);
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_mov_y_dpx(void) {
spc700_prefetchb();
spc700->regs.y = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.y & 0x80);
spc700_testz(spc700->regs.y == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_mov_y_addr(void) {
spc700_prefetchw();
spc700->regs.y = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.y & 0x80);
spc700_testz(spc700->regs.y == 0);
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_mov_ya_dp(void) {
spc700_prefetchb();
word ya;
ya = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
spc700->regs.a = ya;
spc700->regs.y = ya >> 8;
spc700_testn(ya & 0x8000);
spc700_testz(ya == 0);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_mov_dp_ya(void) {
spc700_prefetchb();
word ya = (spc700->regs.y << 8) | spc700->regs.a;
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, ya);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_mov1_c_bit(void) {
spc700_prefetchw();
word addr = arg & 0x1fff;
byte bit = arg >> 13;
byte x;
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
spc700_testc(x & (1 << bit));
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_mov1_bit_c(void) {
spc700_prefetchw();
word addr = arg & 0x1fff;
byte bit = arg >> 13;
byte x;
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
if(spc700->regs.p & SPF_C) {
x |= (1 << bit);
} else {
x &= ~(1 << bit);
}
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, addr, x);
spc700_incpc(3);
add_apu_cycles(5);
}
+147
View File
@@ -0,0 +1,147 @@
void spc700_op_or_a_const(void) {
spc700_prefetchb();
spc700->regs.a |= arg;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_or_a_ix(void) {
spc700->regs.a |= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_or_a_dp(void) {
spc700_prefetchb();
spc700->regs.a |= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_or_a_dpx(void) {
spc700_prefetchb();
spc700->regs.a |= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_or_a_addr(void) {
spc700_prefetchw();
spc700->regs.a |= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_or_a_addrx(void) {
spc700_prefetchw();
spc700->regs.a |= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_or_a_addry(void) {
spc700_prefetchw();
spc700->regs.a |= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_or_a_idpx(void) {
spc700_prefetchb();
word i;
spc700->regs.a |= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_or_a_idpy(void) {
spc700_prefetchb();
word i;
spc700->regs.a |= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_or_ix_iy(void) {
word i;
byte x;
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
x |= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(1);
add_apu_cycles(5);
}
void spc700_op_or_dp_dp(void) {
spc700_prefetch2b();
byte x;
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
x |= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_or_dp_imm(void) {
spc700_prefetch2b();
byte x;
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
x |= arg0;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_or1_bit(void) {
spc700_prefetchw();
word addr = arg & 0x1fff;
byte bit = arg >> 13;
byte x;
if(!(spc700->regs.p & SPF_C)) {
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
if(x & (1 << bit)) {
spc700_setc();
}
}
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_or1_notbit(void) {
spc700_prefetchw();
word addr = arg & 0x1fff;
byte bit = arg >> 13;
byte x;
if(!(spc700->regs.p & SPF_C)) {
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
if(!(x & (1 << bit))) {
spc700_setc();
}
}
spc700_incpc(3);
add_apu_cycles(5);
}
+342
View File
@@ -0,0 +1,342 @@
void spc700_op_bra(void) {
spc700_prefetchb();
spc700->regs.pc += (signed char)arg;
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_bcc(void) {
spc700_prefetchb();
if(!(spc700->regs.p & SPF_C)) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(4);
} else {
add_apu_cycles(2);
}
spc700_incpc(2);
}
void spc700_op_bcs(void) {
spc700_prefetchb();
if((spc700->regs.p & SPF_C)) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(4);
} else {
add_apu_cycles(2);
}
spc700_incpc(2);
}
void spc700_op_beq(void) {
spc700_prefetchb();
if((spc700->regs.p & SPF_Z)) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(4);
} else {
add_apu_cycles(2);
}
spc700_incpc(2);
}
void spc700_op_bmi(void) {
spc700_prefetchb();
if((spc700->regs.p & SPF_N)) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(4);
} else {
add_apu_cycles(2);
}
spc700_incpc(2);
}
void spc700_op_bne(void) {
spc700_prefetchb();
if(!(spc700->regs.p & SPF_Z)) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(4);
} else {
add_apu_cycles(2);
}
spc700_incpc(2);
}
void spc700_op_bpl(void) {
spc700_prefetchb();
if(!(spc700->regs.p & SPF_N)) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(4);
} else {
add_apu_cycles(2);
}
spc700_incpc(2);
}
void spc700_op_bvc(void) {
spc700_prefetchb();
if(!(spc700->regs.p & SPF_V)) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(4);
} else {
add_apu_cycles(2);
}
spc700_incpc(2);
}
void spc700_op_bvs(void) {
spc700_prefetchb();
if((spc700->regs.p & SPF_V)) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(4);
} else {
add_apu_cycles(2);
}
spc700_incpc(2);
}
#define spc700_op_bbc(__n) \
void spc700_op_bbc##__n##(void) { \
spc700_prefetch2b(); \
byte r; \
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0); \
if(!(r & (1 << __n))) { \
spc700->regs.pc += (signed char)arg1; \
add_apu_cycles(7); \
} else { \
add_apu_cycles(5); \
} \
spc700_incpc(3); \
}
#define spc700_op_bbs(__n) \
void spc700_op_bbs##__n##(void) { \
spc700_prefetch2b(); \
byte r; \
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0); \
if(r & (1 << __n)) { \
spc700->regs.pc += (signed char)arg1; \
add_apu_cycles(7); \
} else { \
add_apu_cycles(5); \
} \
spc700_incpc(3); \
}
spc700_op_bbc(0)
spc700_op_bbc(1)
spc700_op_bbc(2)
spc700_op_bbc(3)
spc700_op_bbc(4)
spc700_op_bbc(5)
spc700_op_bbc(6)
spc700_op_bbc(7)
spc700_op_bbs(0)
spc700_op_bbs(1)
spc700_op_bbs(2)
spc700_op_bbs(3)
spc700_op_bbs(4)
spc700_op_bbs(5)
spc700_op_bbs(6)
spc700_op_bbs(7)
void spc700_op_cbne_dp(void) {
spc700_prefetch2b();
byte r;
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
if(r != spc700->regs.a) {
spc700->regs.pc += (signed char)arg1;
add_apu_cycles(7);
} else {
add_apu_cycles(5);
}
spc700_incpc(3);
}
void spc700_op_cbne_dpx(void) {
spc700_prefetch2b();
byte r;
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg0);
if(r != spc700->regs.a) {
spc700->regs.pc += (signed char)arg1;
add_apu_cycles(8);
} else {
add_apu_cycles(6);
}
spc700_incpc(3);
}
void spc700_op_dbnz_dp(void) {
spc700_prefetch2b();
byte r;
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0) - 1;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg0, r);
if(r != 0) {
spc700->regs.pc += (signed char)arg1;
add_apu_cycles(7);
} else {
add_apu_cycles(5);
}
spc700_incpc(3);
}
void spc700_op_dbnz_y(void) {
spc700_prefetchb();
spc700->regs.y--;
if(spc700->regs.y != 0) {
spc700->regs.pc += (signed char)arg;
add_apu_cycles(6);
} else {
add_apu_cycles(4);
}
spc700_incpc(2);
}
void spc700_op_jmp_addr(void) {
spc700_prefetchw();
spc700->regs.pc = arg;
add_apu_cycles(3);
}
void spc700_op_jmp_iaddrx(void) {
spc700_prefetchw();
spc700->regs.pc = spc700->mem_read(APUMODE_IADDRX, MEMSIZE_WORD, arg);
add_apu_cycles(3);
}
void spc700_op_call(void) {
spc700_prefetchw();
word r = spc700->regs.pc + 3;
spc700_incpc(3);
spc700->stack_write(r);
spc700->stack_write(r >> 8);
spc700->regs.pc = arg;
add_apu_cycles(8);
}
void spc700_op_pcall(void) {
spc700_prefetchb();
word r = spc700->regs.pc + 2;
spc700->stack_write(r);
spc700->stack_write(r >> 8);
spc700->regs.pc = 0xff00 | arg;
add_apu_cycles(6);
}
void spc700_op_tcall_0(void) {
dprintf("* spc700 opcode tcall 0 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_1(void) {
dprintf("* spc700 opcode tcall 1 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_2(void) {
dprintf("* spc700 opcode tcall 2 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_3(void) {
dprintf("* spc700 opcode tcall 3 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_4(void) {
dprintf("* spc700 opcode tcall 4 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_5(void) {
dprintf("* spc700 opcode tcall 5 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_6(void) {
dprintf("* spc700 opcode tcall 6 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_7(void) {
dprintf("* spc700 opcode tcall 7 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_8(void) {
dprintf("* spc700 opcode tcall 8 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_9(void) {
dprintf("* spc700 opcode tcall 9 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_10(void) {
dprintf("* spc700 opcode tcall 10 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_11(void) {
dprintf("* spc700 opcode tcall 11 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_12(void) {
dprintf("* spc700 opcode tcall 12 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_13(void) {
dprintf("* spc700 opcode tcall 13 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_14(void) {
dprintf("* spc700 opcode tcall 14 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_tcall_15(void) {
dprintf("* spc700 opcode tcall 15 not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_brk(void) {
dprintf("* spc700 opcode brk not implemented");
spc700_incpc(1);
add_apu_cycles(8);
}
void spc700_op_ret(void) {
word r;
r = spc700->stack_read();
r |= spc700->stack_read() << 8;
spc700->regs.pc = r;
add_apu_cycles(5);
}
void spc700_op_reti(void) {
word r;
spc700->regs.p = spc700->stack_read();
r = spc700->stack_read();
r |= spc700->stack_read() << 8;
spc700->regs.pc = r;
add_apu_cycles(6);
}
+111
View File
@@ -0,0 +1,111 @@
byte spc700_op_sbc(byte x, byte y) {
short r = (short)x - (short)y - (short)(!(spc700->regs.p & SPF_C));
spc700_testn(r & 0x80);
spc700_testv(((x ^ y) & 0x80) && ((x ^ (byte)r) & 0x80));
spc700_testh(((x ^ y ^ (byte)r) & 0x10) == 0);
spc700_testz((byte)r == 0);
spc700_testc(r >= 0);
return (byte)r;
}
void spc700_op_sbc_a_const(void) {
spc700_prefetchb();
spc700->regs.a = spc700_op_sbc(spc700->regs.a, arg);
spc700_incpc(2);
add_apu_cycles(2);
}
void spc700_op_sbc_a_ix(void) {
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
spc700_incpc(1);
add_apu_cycles(3);
}
void spc700_op_sbc_a_dp(void) {
spc700_prefetchb();
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(3);
}
void spc700_op_sbc_a_dpx(void) {
spc700_prefetchb();
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_sbc_a_addr(void) {
spc700_prefetchw();
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(4);
}
void spc700_op_sbc_a_addrx(void) {
spc700_prefetchw();
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_sbc_a_addry(void) {
spc700_prefetchw();
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg));
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_sbc_a_idpx(void) {
spc700_prefetchb();
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_sbc_a_idpy(void) {
spc700_prefetchb();
word i;
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
spc700_incpc(2);
add_apu_cycles(6);
}
void spc700_op_sbc_ix_iy(void) {
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
spc700_incpc(1);
add_apu_cycles(5);
}
void spc700_op_sbc_dp_dp(void) {
spc700_prefetch2b();
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_incpc(3);
add_apu_cycles(6);
}
void spc700_op_sbc_dp_imm(void) {
spc700_prefetch2b();
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_subw_ya_dp(void) {
spc700_prefetchb();
word ya = (spc700->regs.y << 8) | spc700->regs.a;
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
long r = (long)ya - (long)dp;
spc700_testn(r & 0x8000);
spc700_testv(((ya ^ dp) & 0x8000) && ((ya ^ (word)r) & 0x8000));
spc700_testh(((ya ^ dp ^ (word)r) & 0x1000) == 0);
spc700_testz((word)r == 0);
spc700_testc(r >= 0);
spc700->regs.a = r;
spc700->regs.y = r >> 8;
spc700_incpc(2);
add_apu_cycles(5);
}
+195
View File
@@ -0,0 +1,195 @@
void spc700_op_asl_a(void) {
spc700_testc(spc700->regs.a & 0x80);
spc700->regs.a <<= 1;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_asl_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x80);
x <<= 1;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_asl_dpx(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x80);
x <<= 1;
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_asl_addr(void) {
spc700_prefetchw();
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x80);
x <<= 1;
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_lsr_a(void) {
spc700_testc(spc700->regs.a & 0x01);
spc700->regs.a >>= 1;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_lsr_dp(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x01);
x >>= 1;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_lsr_dpx(void) {
spc700_prefetchb();
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x01);
x >>= 1;
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_lsr_addr(void) {
spc700_prefetchw();
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x01);
x >>= 1;
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_rol_a(void) {
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
spc700_testc(spc700->regs.a & 0x80);
spc700->regs.a <<= 1;
spc700->regs.a |= c;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_rol_dp(void) {
spc700_prefetchb();
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x80);
x <<= 1;
x |= c;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_rol_dpx(void) {
spc700_prefetchb();
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x80);
x <<= 1;
x |= c;
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_rol_addr(void) {
spc700_prefetchw();
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x80);
x <<= 1;
x |= c;
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
void spc700_op_ror_a(void) {
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
spc700_testc(spc700->regs.a & 0x01);
spc700->regs.a >>= 1;
spc700->regs.a |= c;
spc700_testn(spc700->regs.a & 0x80);
spc700_testz(spc700->regs.a == 0);
spc700_incpc(1);
add_apu_cycles(2);
}
void spc700_op_ror_dp(void) {
spc700_prefetchb();
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x01);
x >>= 1;
x |= c;
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(2);
add_apu_cycles(4);
}
void spc700_op_ror_dpx(void) {
spc700_prefetchb();
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x01);
x >>= 1;
x |= c;
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(2);
add_apu_cycles(5);
}
void spc700_op_ror_addr(void) {
spc700_prefetchw();
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
spc700_testc(x & 0x01);
x >>= 1;
x |= c;
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
spc700_testn(x & 0x80);
spc700_testz(x == 0);
spc700_incpc(3);
add_apu_cycles(5);
}
+48
View File
@@ -0,0 +1,48 @@
void spc700_op_push_a(void) {
spc700->stack_write(spc700->regs.a);
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_push_x(void) {
spc700->stack_write(spc700->regs.x);
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_push_y(void) {
spc700->stack_write(spc700->regs.y);
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_push_p(void) {
spc700->stack_write(spc700->regs.p);
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_pop_a(void) {
spc700->regs.a = spc700->stack_read();
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_pop_x(void) {
spc700->regs.x = spc700->stack_read();
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_pop_y(void) {
spc700->regs.y = spc700->stack_read();
spc700_incpc(1);
add_apu_cycles(4);
}
void spc700_op_pop_p(void) {
spc700->regs.p = spc700->stack_read();
spc700_incpc(1);
add_apu_cycles(4);
spc700->regs.dp = (spc700->regs.p & SPF_P)?0x0100:0x0000;
}
+424
View File
@@ -0,0 +1,424 @@
#define NO_SPC700
#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
#define SH_512 9
#define SH_1024 10
#define SH_2048 11
#define SH_4096 12
/*************************
*** 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 {
bool rom_loaded;
ulong sram_save_tick_count;
char rom_name[4096], sram_name[4096];
}emustate;
/***********************
*** video functions ***
**********************/
void video_setmode(bool fullscreen, word width, word height);
void video_setsnesmode(void);
#define LINE_DOUBLEWIDTH 1
#define LINE_DOUBLEHEIGHT 2
//global export: render
typedef struct {
word display_width, display_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];
byte line[239];
}videostate;
/***************************
*** debugging functions ***
**************************/
#define DEBUGMSG_INFO 0
#define DEBUGMSG_CPU 1
#define DEBUGMSG_APU 2
#define DEBUGWRITE_NONE 0
#define DEBUGWRITE_CONSOLE 1
#define DEBUGWRITE_TRACE 2
enum {
DEBUGMODE_DISABLED = 0,
DEBUGMODE_WAIT,
DEBUGMODE_RUN,
DEBUGMODE_CPUSTEP,
DEBUGMODE_APUSTEP,
DEBUGMODE_PROCEED
};
#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
#define BP_OFF 0
#define BP_READ 1
#define BP_WRITE 2
#define BP_EXEC 4
#define BP_VAL 8
#define BPSRC_MEM 0
#define BPSRC_VRAM 1
#define BPSRC_CGRAM 2
#define BPSRC_OAM 3
#define BPSRC_SPCRAM 4
void debug_test_breakpoint(byte source, byte flag, ulong offset, byte value);
#define debug_get_state() debugger.mode
#define debugger_enabled() ((debugger.mode == DEBUGMODE_DISABLED)?false:true)
#define debug_test_bp(__source, __flag, __offset, __value) \
if(debug_get_state() != DEBUGMODE_DISABLED) { \
debug_test_breakpoint(__source, __flag, __offset, __value); \
}
void debug_set_state(byte state);
void dprintf(char *s, ...);
void dprintf(ulong msg_type, char *s, ...);
void debug_refresh_mem(void);
void debug_refresh_bp(void);
void debug_update_status(void);
ulong debug_write_status(void);
typedef struct {
byte mode;
ulong mem_ptr; //position of wram ptr for debug window
bool disas_cpu_op, disas_apu_op;
bool refresh_mem;
bool refresh_bp;
bool refresh_status;
bool cpu_op_executed;
bool apu_op_executed;
bool output_cpu_instrs;
bool output_apu_instrs;
bool output_debug_info;
bool trace_enabled;
bool trace_output_enabled;
bool lock_up, lock_down, lock_left, lock_right;
bool lock_a, lock_b, lock_x, lock_y;
bool lock_l, lock_r, lock_select, lock_start;
struct {
ulong offset;
byte flags;
byte source;
byte value;
ulong hit_count;
}bp_list[16];
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
bool overscan;
byte visible_scanlines;
bool sprite_halve;
bool interlace, toggle_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_write_buffer;
word vram_read_buffer;
word vram_remap_mode;
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;
ulong r_2134;
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 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;
byte mode7_repeat;
bool mode7_extbg;
bool mode7_vflip, mode7_hflip;
byte io4201;
bool counter_latched;
byte mmio_mem_43xx[0x80];
}ppustate;
/*********************
*** cpu functions ***
********************/
#define CPUSTATE_RUN 0
#define CPUSTATE_DMA 1
#define CPUSTATE_STP 2
#define MEMSPEED_SLOWROM 0
#define MEMSPEED_FASTROM 1
void add_apu_cycles(int n);
//g65816 cpu flags
#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
//spc700 cpu flags
#define SPF_N 0x80
#define SPF_V 0x40
#define SPF_P 0x20
#define SPF_B 0x10
#define SPF_H 0x08
#define SPF_I 0x04
#define SPF_Z 0x02
#define SPF_C 0x01
/************************
*** memory functions ***
***********************/
#define MEMSPEED_FAST 6
#define MEMSPEED_SLOW 8
#define MEMSPEED_XSLOW 12
#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]
//opcode memory access types
OPMODE_DBR,
OPMODE_PBR,
OPMODE_LONG,
OPMODE_DP,
OPMODE_SP,
OPMODE_ADDR
};
#define MEMSIZE_BYTE 1
#define MEMSIZE_WORD 2
#define MEMSIZE_LONG 3
/***********************
*** misc. functions ***
**********************/
//main.cpp
void InitSNES(void);
void RunSNES(void);
void ResetSNES(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);
//apu/dspc700.cpp
void disas_spc700_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);
void ppu_update_dma(void);
//win/render.cpp
void UpdateDisplay(void);
//misc/libstr.cpp
ulong strhex(char *str);
ulong strdec(char *str);
+26
View File
@@ -0,0 +1,26 @@
#include "../base.h"
#include "bridge.h"
port_bridge *cpu_apu_bridge;
port_bridge::port_bridge() {
cputoapu_port[0] = cputoapu_port[1] =
cputoapu_port[2] = cputoapu_port[3] =
aputocpu_port[0] = aputocpu_port[1] =
aputocpu_port[2] = aputocpu_port[3] = 0;
}
byte port_bridge::cpu_read(byte port) {
return aputocpu_port[port & 3];
}
byte port_bridge::apu_read(byte port) {
return cputoapu_port[port & 3];
}
void port_bridge::cpu_write(byte port, byte value) {
cputoapu_port[port & 3] = value;
}
void port_bridge::apu_write(byte port, byte value) {
aputocpu_port[port & 3] = value;
}
+11
View File
@@ -0,0 +1,11 @@
class port_bridge {
public:
byte cputoapu_port[4]; //holds values written to CPU at $2140-$2143
byte aputocpu_port[4]; //holds values written to APU at $f4-$f7
port_bridge();
byte cpu_read(byte port);
byte apu_read(byte port);
void cpu_write(byte port, byte value);
void apu_write(byte port, byte value);
};
BIN
View File
Binary file not shown.
Executable → Regular
+2 -2
View File
@@ -1,2 +1,2 @@
@mingw32-make -j 2
@pause
@nmake /NOLOGO
@pause
Executable → Regular
+1 -1
View File
@@ -1 +1 @@
@mingw32-make clean
@nmake /NOLOGO clean
+339
View File
@@ -0,0 +1,339 @@
#include "../base.h"
#include "g65816.h"
extern g65816 *gx816;
extern debugstate debugger;
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, op0, op1, op2;
char str0[256], str1[256], str2[256];
if(debug_write_status() == DEBUGWRITE_NONE)return;
op = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc, MEMACCESS_DEBUGGER);
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);
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(DEBUGMSG_CPU, "%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);
}
+240
View File
@@ -0,0 +1,240 @@
#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;
wai_interrupt_occurred = false;
InitializeWRAM(0x00);
PPUInit(first_time);
UpdateDisplay();
snes_time->set_speed_map(MEMSPEED_SLOWROM);
cpu_state = CPUSTATE_RUN;
}
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;
wai_interrupt_occurred = false;
PPUInit(0); //0 blocks reallocating memory for vram, cgram, etc.
UpdateDisplay();
snes_time->set_speed_map(MEMSPEED_SLOWROM);
cpu_state = CPUSTATE_RUN;
}
/***********
*** IRQ ***
***********
cycles:
[1] pbr,pc ; io
[2] pbr,pc ; io
[3] 0,s ; pbr
[4] 0,s-1 ; pch
[5] 0,s-2 ; pcl
[6] 0,s-3 ; p
[7] 0,va ; aavl
[8] 0,va+1 ; aavh
*/
void g65816::InvokeIRQ(word addr) {
snes_time->add_cpu_icycles(2); //1,2 [i/o]
gx816->stack_write(gx816->regs.pc >> 16); //3 [write pbr]
gx816->stack_write(gx816->regs.pc >> 8); //4 [write pch]
gx816->stack_write(gx816->regs.pc); //5 [write pcl]
gx816->stack_write(gx816->regs.p); //6 [write p]
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, addr); //7 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, addr + 1); //8 [read high]
gx816->regs.pc = gx816->op.r.w;
gx816->regs.p |= PF_I;
wai_interrupt_occurred = true;
snes_time->update_timer();
}
void g65816::exec_op(void) {
FILE *fp;
byte op;
int i;
static ulong sram_save_tick = 0;
if(cpu_state == CPUSTATE_RUN || cpu_state == CPUSTATE_STP) {
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;
}
debugger.cpu_op_executed = true;
debugger.disas_cpu_op = true;
snes_time->update_timer();
} else if(cpu_state == CPUSTATE_DMA) {
ppu_update_dma();
snes_time->update_timer();
}
snes_time->update_timer_events();
ppu_update_scanline();
//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);
}
}
debug_test_bp(BPSRC_MEM, BP_EXEC, gx816->regs.pc, 0);
}
void g65816::Run(void) {
if(snes_time->bridge.apu_cycles >= snes_time->bridge.cpu_cycles) {
exec_op();
}
if(snes_time->bridge.cpu_cycles >= 65536 && snes_time->bridge.apu_cycles >= 65536) {
snes_time->bridge.cpu_cycles &= 65535;
snes_time->bridge.apu_cycles &= 65535;
}
}
g65816::g65816() {
int i;
rom = (byte*)malloc(0x600000);
wram = (byte*)malloc(0x020000);
sram = (byte*)malloc(0x0e0000);
nmi_enabled = false;
nmi_pin = 0;
op.dp = op.sp = 0x00;
op.r.l = 0x000000;
op.aa.l = 0x000000;
}
g65816::~g65816() {
if(rom)free(rom);
if(wram)free(wram);
if(sram)free(sram);
}
+87
View File
@@ -0,0 +1,87 @@
/*
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
byte cpu_state;
struct {
ulong pc;
union {
byte b;
word w;
struct { byte l, h; }p;
}a;
word x, y, d, s;
byte db, p;
bool e;
}regs;
struct {
byte dp, sp;
union {
byte b;
word w;
ulong l;
struct { byte l, h, b; }p;
}r;
union {
word w;
ulong l;
struct { byte l, h, b; }p;
}aa;
ulong addr, iaddr;
bool c2, c4;
}op;
byte memory_speed;
byte nmi_pin;
bool nmi_enabled;
bool wai_interrupt_occurred;
//memory declarations
byte *wram, *sram, *rom;
ulong map;
ulong sram_size;
//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 exec_op(void);
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 read_operand(byte size);
byte op_read(byte mode, ulong addr);
void op_write(byte mode, ulong addr, byte value);
byte stack_read(void);
void stack_write(byte value);
void op_cond(byte c, ulong n0 = 0, ulong n1 = 0);
ulong rom_read(ulong addr, byte read_size);
void rom_write(ulong addr, ulong v, byte write_size);
g65816();
~g65816();
};
+162
View File
@@ -0,0 +1,162 @@
#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()
//increment program counter, wrap around pbr
#define g65816_incpc(__n) gx816->regs.pc = (gx816->regs.pc & 0xff0000) | (word)(gx816->regs.pc + __n)
/*
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)
*/
//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_brk, g65816_op_ora_idpxb, g65816_op_cop, 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_brk, g65816_op_ora_idpxb, g65816_op_cop, 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_brk, g65816_op_ora_idpxb, g65816_op_cop, 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_brk, g65816_op_ora_idpxw, g65816_op_cop, 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_brk, g65816_op_ora_idpxw, g65816_op_cop, 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
};
+526
View File
@@ -0,0 +1,526 @@
void g65816_flags_adc_b(void) {
int r = gx816->regs.a.b + gx816->op.r.b + (gx816->regs.p & PF_C);
//bcd
if(gx816->regs.p & PF_D) {
if(((r ) & 15) > 9)r += 6;
if(((r >> 4) & 15) > 9)r += 6 << 4;
}
g65816_testn(r & 0x80);
g65816_testv(~(gx816->regs.a.b ^ gx816->op.r.b) & (gx816->regs.a.b ^ (byte)r) & 0x80);
g65816_testz((byte)r == 0);
g65816_testc(r > 0xff);
gx816->regs.a.b = r;
}
void g65816_flags_adc_w(void) {
int r = gx816->regs.a.w + gx816->op.r.w + (gx816->regs.p & PF_C);
//bcd
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;
}
g65816_testn(r & 0x8000);
g65816_testv(~(gx816->regs.a.w ^ gx816->op.r.w) & (gx816->regs.a.w ^ (word)r) & 0x8000);
g65816_testz((word)r == 0);
g65816_testc(r > 0xffff);
gx816->regs.a.w = r;
}
/************************
*** 0x69: adc #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void g65816_op_adc_constb(void) {
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_constw(void) {
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
g65816_flags_adc_w();
g65816_incpc(3);
}
/**********************
*** 0x6d: adc addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void g65816_op_adc_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
g65816_flags_adc_b();
g65816_incpc(3);
}
void g65816_op_adc_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
g65816_flags_adc_w();
g65816_incpc(3);
}
/************************
*** 0x7d: adc addr,x ***
************************
cycles:
[1 ] pbr,pc ; operadc
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void g65816_op_adc_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
g65816_flags_adc_b();
g65816_incpc(3);
}
void g65816_op_adc_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
g65816_flags_adc_w();
g65816_incpc(3);
}
/********************
*** 0x65: adc dp ***
********************
cycles:
[1 ] pbr,pc ; operadc
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void g65816_op_adc_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
/**********************
*** 0x72: adc (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void g65816_op_adc_idpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_idpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
/**********************
*** 0x67: adc [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void g65816_op_adc_ildpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_ildpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
/**********************
*** 0x6f: adc long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void g65816_op_adc_longb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
g65816_flags_adc_b();
g65816_incpc(4);
}
void g65816_op_adc_longw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
g65816_flags_adc_w();
g65816_incpc(4);
}
/************************
*** 0x7f: adc long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void g65816_op_adc_longxb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
g65816_flags_adc_b();
g65816_incpc(4);
}
void g65816_op_adc_longxw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
g65816_flags_adc_w();
g65816_incpc(4);
}
/************************
*** 0x79: adc addr,y ***
************************
cycles:
[1 ] pbr,pc ; operadc
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_adc_addryb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
g65816_flags_adc_b();
g65816_incpc(3);
}
void g65816_op_adc_addryw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
g65816_flags_adc_w();
g65816_incpc(3);
}
/**********************
*** 0x75: adc dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void g65816_op_adc_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
/************************
*** 0x61: adc (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void g65816_op_adc_idpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_idpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
/************************
*** 0x71: adc (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_adc_idpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_idpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
/************************
*** 0x77: adc [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void g65816_op_adc_ildpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_ildpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
/**********************
*** 0x63: adc sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void g65816_op_adc_srb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_srw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
/**************************
*** 0x73: adc (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_adc_isryb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
g65816_flags_adc_b();
g65816_incpc(2);
}
void g65816_op_adc_isryw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
g65816_flags_adc_w();
g65816_incpc(2);
}
+504
View File
@@ -0,0 +1,504 @@
void g65816_flags_and_b() {
g65816_testn(gx816->regs.a.b & 0x80);
g65816_testz(gx816->regs.a.b == 0);
}
void g65816_flags_and_w() {
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
}
/************************
*** 0x29: and #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void g65816_op_and_constb(void) {
gx816->regs.a.b &= gx816->read_operand(1); //1,2 [op fetch]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_constw(void) {
gx816->regs.a.w &= gx816->read_operand(2); //1,2,2a [op fetch]
g65816_flags_and_w();
g65816_incpc(3);
}
/**********************
*** 0x2d: and addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void g65816_op_and_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
g65816_flags_and_b();
g65816_incpc(3);
}
void g65816_op_and_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
g65816_flags_and_w();
g65816_incpc(3);
}
/************************
*** 0x3d: and addr,x ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void g65816_op_and_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
g65816_flags_and_b();
g65816_incpc(3);
}
void g65816_op_and_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
g65816_flags_and_w();
g65816_incpc(3);
}
/********************
*** 0x25: and dp ***
********************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void g65816_op_and_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->regs.a.b &= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
/**********************
*** 0x32: and (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void g65816_op_and_idpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_idpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
/**********************
*** 0x27: and [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void g65816_op_and_ildpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_ildpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
/**********************
*** 0x2f: and long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void g65816_op_and_longb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
g65816_flags_and_b();
g65816_incpc(4);
}
void g65816_op_and_longw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
g65816_flags_and_w();
g65816_incpc(4);
}
/************************
*** 0x3f: and long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void g65816_op_and_longxb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
g65816_flags_and_b();
g65816_incpc(4);
}
void g65816_op_and_longxw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
g65816_flags_and_w();
g65816_incpc(4);
}
/************************
*** 0x39: and addr,y ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_and_addryb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
g65816_flags_and_b();
g65816_incpc(3);
}
void g65816_op_and_addryw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
g65816_flags_and_w();
g65816_incpc(3);
}
/**********************
*** 0x35: and dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void g65816_op_and_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.b &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
/************************
*** 0x21: and (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void g65816_op_and_idpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_idpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
/************************
*** 0x31: and (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_and_idpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_idpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
/************************
*** 0x37: and [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void g65816_op_and_ildpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_ildpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
/**********************
*** 0x23: and sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void g65816_op_and_srb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.b &= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_srw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
/**************************
*** 0x33: and (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_and_isryb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
g65816_flags_and_b();
g65816_incpc(2);
}
void g65816_op_and_isryw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
g65816_flags_and_w();
g65816_incpc(2);
}
+508
View File
@@ -0,0 +1,508 @@
void g65816_flags_cmp_b() {
int r = gx816->regs.a.b - gx816->op.r.b;
g65816_testn(r & 0x80);
g65816_testz((byte)r == 0);
g65816_testc(r >= 0);
}
void g65816_flags_cmp_w() {
int r = gx816->regs.a.w - gx816->op.r.w;
g65816_testn(r & 0x8000);
g65816_testz((word)r == 0);
g65816_testc(r >= 0);
}
/************************
*** 0xc9: cmp #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void g65816_op_cmp_constb(void) {
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_constw(void) {
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
g65816_flags_cmp_w();
g65816_incpc(3);
}
/**********************
*** 0xcd: cmp addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void g65816_op_cmp_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
g65816_flags_cmp_b();
g65816_incpc(3);
}
void g65816_op_cmp_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
g65816_flags_cmp_w();
g65816_incpc(3);
}
/************************
*** 0xdd: cmp addr,x ***
************************
cycles:
[1 ] pbr,pc ; opercmp
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void g65816_op_cmp_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
g65816_flags_cmp_b();
g65816_incpc(3);
}
void g65816_op_cmp_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
g65816_flags_cmp_w();
g65816_incpc(3);
}
/********************
*** 0xc5: cmp dp ***
********************
cycles:
[1 ] pbr,pc ; opercmp
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void g65816_op_cmp_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
/**********************
*** 0xd2: cmp (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void g65816_op_cmp_idpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_idpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
/**********************
*** 0xc7: cmp [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void g65816_op_cmp_ildpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_ildpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
/**********************
*** 0xcf: cmp long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void g65816_op_cmp_longb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
g65816_flags_cmp_b();
g65816_incpc(4);
}
void g65816_op_cmp_longw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
g65816_flags_cmp_w();
g65816_incpc(4);
}
/************************
*** 0xdf: cmp long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void g65816_op_cmp_longxb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
g65816_flags_cmp_b();
g65816_incpc(4);
}
void g65816_op_cmp_longxw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
g65816_flags_cmp_w();
g65816_incpc(4);
}
/************************
*** 0xd9: cmp addr,y ***
************************
cycles:
[1 ] pbr,pc ; opercmp
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_cmp_addryb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
g65816_flags_cmp_b();
g65816_incpc(3);
}
void g65816_op_cmp_addryw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
g65816_flags_cmp_w();
g65816_incpc(3);
}
/**********************
*** 0xd5: cmp dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void g65816_op_cmp_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
/************************
*** 0xc1: cmp (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void g65816_op_cmp_idpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_idpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
/************************
*** 0xd1: cmp (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_cmp_idpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_idpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
/************************
*** 0xd7: cmp [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void g65816_op_cmp_ildpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_ildpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
/**********************
*** 0xc3: cmp sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void g65816_op_cmp_srb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_srw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
/**************************
*** 0xd3: cmp (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_cmp_isryb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
g65816_flags_cmp_b();
g65816_incpc(2);
}
void g65816_op_cmp_isryw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
g65816_flags_cmp_w();
g65816_incpc(2);
}
+504
View File
@@ -0,0 +1,504 @@
void g65816_flags_eor_b() {
g65816_testn(gx816->regs.a.b & 0x80);
g65816_testz(gx816->regs.a.b == 0);
}
void g65816_flags_eor_w() {
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
}
/************************
*** 0x49: eor #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void g65816_op_eor_constb(void) {
gx816->regs.a.b ^= gx816->read_operand(1); //1,2 [op fetch]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_constw(void) {
gx816->regs.a.w ^= gx816->read_operand(2); //1,2,2a [op fetch]
g65816_flags_eor_w();
g65816_incpc(3);
}
/**********************
*** 0x4d: eor addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void g65816_op_eor_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
g65816_flags_eor_b();
g65816_incpc(3);
}
void g65816_op_eor_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
g65816_flags_eor_w();
g65816_incpc(3);
}
/************************
*** 0x5d: eor addr,x ***
************************
cycles:
[1 ] pbr,pc ; opereor
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void g65816_op_eor_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
g65816_flags_eor_b();
g65816_incpc(3);
}
void g65816_op_eor_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
g65816_flags_eor_w();
g65816_incpc(3);
}
/********************
*** 0x45: eor dp ***
********************
cycles:
[1 ] pbr,pc ; opereor
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void g65816_op_eor_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
/**********************
*** 0x52: eor (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void g65816_op_eor_idpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_idpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
/**********************
*** 0x47: eor [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void g65816_op_eor_ildpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_ildpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
/**********************
*** 0x4f: eor long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void g65816_op_eor_longb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
g65816_flags_eor_b();
g65816_incpc(4);
}
void g65816_op_eor_longw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
g65816_flags_eor_w();
g65816_incpc(4);
}
/************************
*** 0x5f: eor long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void g65816_op_eor_longxb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
g65816_flags_eor_b();
g65816_incpc(4);
}
void g65816_op_eor_longxw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
g65816_flags_eor_w();
g65816_incpc(4);
}
/************************
*** 0x59: eor addr,y ***
************************
cycles:
[1 ] pbr,pc ; opereor
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_eor_addryb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
g65816_flags_eor_b();
g65816_incpc(3);
}
void g65816_op_eor_addryw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
g65816_flags_eor_w();
g65816_incpc(3);
}
/**********************
*** 0x55: eor dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void g65816_op_eor_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
/************************
*** 0x41: eor (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void g65816_op_eor_idpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_idpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
/************************
*** 0x51: eor (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_eor_idpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_idpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
/************************
*** 0x57: eor [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void g65816_op_eor_ildpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_ildpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
/**********************
*** 0x43: eor sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void g65816_op_eor_srb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.b ^= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_srw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
/**************************
*** 0x53: eor (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_eor_isryb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
g65816_flags_eor_b();
g65816_incpc(2);
}
void g65816_op_eor_isryw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
g65816_flags_eor_w();
g65816_incpc(2);
}
+511
View File
@@ -0,0 +1,511 @@
/*****************
*** 0x1a: inc ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_incb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.a.b++;
g65816_testn(gx816->regs.a.b & 0x80);
g65816_testz(gx816->regs.a.b == 0);
g65816_incpc(1);
}
void g65816_op_incw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.a.w++;
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
g65816_incpc(1);
}
/**********************
*** 0xee: inc addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void g65816_op_inc_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->op.r.b++;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_inc_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->op.r.w++;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/************************
*** 0xfe: inc addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void g65816_op_inc_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.b++;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_inc_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.w++;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/********************
*** 0xe6: inc dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void g65816_op_inc_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.b++;
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_inc_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.w++;
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/**********************
*** 0xf6: inc dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void g65816_op_inc_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->op.r.b++;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_inc_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->op.r.w++;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/*****************
*** 0xe8: inx ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_inxb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.x++;
gx816->regs.x &= 0xff;
g65816_testn(gx816->regs.x & 0x80);
g65816_testz(gx816->regs.x == 0);
g65816_incpc(1);
}
void g65816_op_inxw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.x++;
g65816_testn(gx816->regs.x & 0x8000);
g65816_testz(gx816->regs.x == 0);
g65816_incpc(1);
}
/*****************
*** 0xc8: iny ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_inyb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.y++;
gx816->regs.y &= 0xff;
g65816_testn(gx816->regs.y & 0x80);
g65816_testz(gx816->regs.y == 0);
g65816_incpc(1);
}
void g65816_op_inyw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.y++;
g65816_testn(gx816->regs.y & 0x8000);
g65816_testz(gx816->regs.y == 0);
g65816_incpc(1);
}
/*****************
*** 0x3a: dec ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_decb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.a.b--;
g65816_testn(gx816->regs.a.b & 0x80);
g65816_testz(gx816->regs.a.b == 0);
g65816_incpc(1);
}
void g65816_op_decw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.a.w--;
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
g65816_incpc(1);
}
/**********************
*** 0xce: dec addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void g65816_op_dec_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->op.r.b--;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_dec_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->op.r.w--;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/************************
*** 0xde: dec addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void g65816_op_dec_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.b--;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_dec_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.w--;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/********************
*** 0xc6: dec dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void g65816_op_dec_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.b--;
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_dec_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.w--;
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/**********************
*** 0xd6: dec dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void g65816_op_dec_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->op.r.b--;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_dec_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->op.r.w--;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/*****************
*** 0xca: dex ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_dexb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.x--;
gx816->regs.x &= 0xff;
g65816_testn(gx816->regs.x & 0x80);
g65816_testz(gx816->regs.x == 0);
g65816_incpc(1);
}
void g65816_op_dexw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.x--;
g65816_testn(gx816->regs.x & 0x8000);
g65816_testz(gx816->regs.x == 0);
g65816_incpc(1);
}
/*****************
*** 0x88: dey ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_deyb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.y--;
gx816->regs.y &= 0xff;
g65816_testn(gx816->regs.y & 0x80);
g65816_testz(gx816->regs.y == 0);
g65816_incpc(1);
}
void g65816_op_deyw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->regs.y--;
g65816_testn(gx816->regs.y & 0x8000);
g65816_testz(gx816->regs.y == 0);
g65816_incpc(1);
}
+504
View File
@@ -0,0 +1,504 @@
void g65816_flags_lda_b(void) {
g65816_testn(gx816->regs.a.b & 0x80);
g65816_testz(gx816->regs.a.b == 0);
}
void g65816_flags_lda_w(void) {
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
}
/************************
*** 0xa9: lda #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void g65816_op_lda_constb(void) {
gx816->regs.a.b = gx816->read_operand(1); //1,2 [op fetch]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_constw(void) {
gx816->regs.a.w = gx816->read_operand(2); //1,2,2a [op fetch]
g65816_flags_lda_w();
g65816_incpc(3);
}
/**********************
*** 0xad: lda addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void g65816_op_lda_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
g65816_flags_lda_b();
g65816_incpc(3);
}
void g65816_op_lda_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
g65816_flags_lda_w();
g65816_incpc(3);
}
/************************
*** 0xbd: lda addr,x ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void g65816_op_lda_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
g65816_flags_lda_b();
g65816_incpc(3);
}
void g65816_op_lda_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
g65816_flags_lda_w();
g65816_incpc(3);
}
/********************
*** 0xa5: lda dp ***
********************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void g65816_op_lda_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->regs.a.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
/**********************
*** 0xb2: lda (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void g65816_op_lda_idpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_idpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
/**********************
*** 0xa7: lda [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void g65816_op_lda_ildpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_ildpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
/**********************
*** 0xaf: lda long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void g65816_op_lda_longb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
g65816_flags_lda_b();
g65816_incpc(4);
}
void g65816_op_lda_longw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
g65816_flags_lda_w();
g65816_incpc(4);
}
/************************
*** 0xbf: lda long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void g65816_op_lda_longxb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
g65816_flags_lda_b();
g65816_incpc(4);
}
void g65816_op_lda_longxw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
g65816_flags_lda_w();
g65816_incpc(4);
}
/************************
*** 0xb9: lda addr,y ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_lda_addryb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
g65816_flags_lda_b();
g65816_incpc(3);
}
void g65816_op_lda_addryw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
g65816_flags_lda_w();
g65816_incpc(3);
}
/**********************
*** 0xb5: lda dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void g65816_op_lda_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
/************************
*** 0xa1: lda (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void g65816_op_lda_idpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_idpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
/************************
*** 0xb1: lda (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_lda_idpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_idpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
/************************
*** 0xb7: lda [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void g65816_op_lda_ildpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_ildpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
/**********************
*** 0xa3: lda sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void g65816_op_lda_srb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_srw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
/**************************
*** 0xb3: lda (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_lda_isryb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
g65816_flags_lda_b();
g65816_incpc(2);
}
void g65816_op_lda_isryw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
g65816_flags_lda_w();
g65816_incpc(2);
}
File diff suppressed because it is too large. Load diff
+504
View File
@@ -0,0 +1,504 @@
void g65816_flags_ora_b() {
g65816_testn(gx816->regs.a.b & 0x80);
g65816_testz(gx816->regs.a.b == 0);
}
void g65816_flags_ora_w() {
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
}
/************************
*** 0x09: ora #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void g65816_op_ora_constb(void) {
gx816->regs.a.b |= gx816->read_operand(1); //1,2 [op fetch]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_constw(void) {
gx816->regs.a.w |= gx816->read_operand(2); //1,2,2a [op fetch]
g65816_flags_ora_w();
g65816_incpc(3);
}
/**********************
*** 0x0d: ora addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void g65816_op_ora_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
g65816_flags_ora_b();
g65816_incpc(3);
}
void g65816_op_ora_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
g65816_flags_ora_w();
g65816_incpc(3);
}
/************************
*** 0x1d: ora addr,x ***
************************
cycles:
[1 ] pbr,pc ; operora
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void g65816_op_ora_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
g65816_flags_ora_b();
g65816_incpc(3);
}
void g65816_op_ora_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
g65816_flags_ora_w();
g65816_incpc(3);
}
/********************
*** 0x05: ora dp ***
********************
cycles:
[1 ] pbr,pc ; operora
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void g65816_op_ora_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->regs.a.b |= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
/**********************
*** 0x12: ora (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void g65816_op_ora_idpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_idpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
/**********************
*** 0x07: ora [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void g65816_op_ora_ildpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_ildpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
/**********************
*** 0x0f: ora long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void g65816_op_ora_longb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
g65816_flags_ora_b();
g65816_incpc(4);
}
void g65816_op_ora_longw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
g65816_flags_ora_w();
g65816_incpc(4);
}
/************************
*** 0x1f: ora long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void g65816_op_ora_longxb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
g65816_flags_ora_b();
g65816_incpc(4);
}
void g65816_op_ora_longxw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
g65816_flags_ora_w();
g65816_incpc(4);
}
/************************
*** 0x19: ora addr,y ***
************************
cycles:
[1 ] pbr,pc ; operora
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_ora_addryb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
g65816_flags_ora_b();
g65816_incpc(3);
}
void g65816_op_ora_addryw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
g65816_flags_ora_w();
g65816_incpc(3);
}
/**********************
*** 0x15: ora dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void g65816_op_ora_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.b |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
/************************
*** 0x01: ora (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void g65816_op_ora_idpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_idpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
/************************
*** 0x11: ora (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_ora_idpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_idpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
/************************
*** 0x17: ora [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void g65816_op_ora_ildpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_ildpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
/**********************
*** 0x03: ora sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void g65816_op_ora_srb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.b |= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_srw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
/**************************
*** 0x13: ora (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_ora_isryb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
g65816_flags_ora_b();
g65816_incpc(2);
}
void g65816_op_ora_isryw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
g65816_flags_ora_w();
g65816_incpc(2);
}
+497
View File
@@ -0,0 +1,497 @@
/**********************
*** 0x4c: jmp addr ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; new pcl
[3] pbr,pc+2 ; new pch
*/
void g65816_op_jmp_addr(void) {
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
}
/**********************
*** 0x5c: jml long ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; new pcl
[3] pbr,pc+2 ; new pch
[4] pbr,pc+3 ; new pbr
*/
void g65816_op_jmp_long(void) {
gx816->regs.pc = gx816->read_operand(3); //1-4 [op fetch]
}
/************************
*** 0x6c: jmp (addr) ***
************************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] pbr,pc+2 ; aah
[4] 0,aa ; new pcl
[5] 0,aa+1 ; new pch
*/
void g65816_op_jmp_iaddr(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 1); //5 [read high]
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
}
/**************************
*** 0x7c: jmp (addr,x) ***
**************************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] pbr,pc+2 ; aah
[4] pbr,pc+2 ; io
[5] pbr,aa+x ; new pcl
[6] pbr,aa+x+1 ; new pch
*/
void g65816_op_jmp_iaddrx(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x + 1); //6 [read high]
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
}
/************************
*** 0xdc: jmp [addr] ***
************************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] pbr,pc+2 ; aah
[4] 0,aa ; new pcl
[5] 0,aa+1 ; new pch
[6] 0,aa+2 ; new pbr
*/
void g65816_op_jmp_iladdr(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 1); //5 [read high]
gx816->op.r.p.b = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 2); //6 [read bank]
gx816->regs.pc = gx816->op.r.l;
}
/**********************
*** 0x20: jsr addr ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; new pcl
[3] pbr,pc+2 ; new pch
[4] pbr,pc+2 ; io
[5] 0,s ; pch
[6] 0,s-1 ; pcl
*/
void g65816_op_jsr_addr(void) {
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->regs.pc += 2;
gx816->stack_write(gx816->regs.pc >> 8); //5 [write high]
gx816->stack_write(gx816->regs.pc); //6 [write low]
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
}
/**********************
*** 0x22: jsl long ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; new pcl
[3] pbr,pc+2 ; new pch
[4] 0,s ; pbr
[5] 0,s ; io
[6] pbr,pc+3 ; new pbr
[7] 0,s-1 ; pch
[8] 0,s-2 ; pcl
*/
void g65816_op_jsr_long(void) {
gx816->op.r.l = gx816->read_operand(3); //1-3,6 [op fetch]
gx816->regs.pc += 3;
gx816->stack_write(gx816->regs.pc >> 16); //4 [write bank]
snes_time->add_cpu_icycles(1); //5 [i/o]
gx816->stack_write(gx816->regs.pc >> 8); //7 [write high]
gx816->stack_write(gx816->regs.pc); //8 [write low]
gx816->regs.pc = gx816->op.r.l;
}
/**************************
*** 0xfc: jsr (addr,x) ***
**************************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] 0,s ; pch
[4] 0,s-1 ; pcl
[5] pbr,pc+2 ; aah
[6] pbr,pc+2 ; io
[7] pbr,aa+x ; new pcl
[8] pbr,aa+x+1 ; new pch
*/
void g65816_op_jsr_iaddrx(void) {
gx816->op.aa.w = gx816->read_operand(2); //1,2,5 [op fetch]
gx816->regs.pc += 2;
gx816->stack_write(gx816->regs.pc >> 8); //3 [write high]
gx816->stack_write(gx816->regs.pc); //4 [write low]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x); //7 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x + 1); //8 [read high]
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
}
/*****************
*** 0x40: rti ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
[3] pbr,pc+1 ; io
[4] 0,s+1 ; p
[5] 0,s+2 ; new pcl
[6] 0,s+3 ; new pch
[7] 0,s+4 ; pbr [7]
*/
void g65816_op_rtie(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.p = gx816->stack_read(); //4 [read p]
gx816->op.r.p.l = gx816->stack_read(); //5 [read pcl]
gx816->op.r.p.h = gx816->stack_read(); //6 [read pch]
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
gx816->regs.p &= ~ PF_I;
}
void g65816_op_rtin(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.p = gx816->stack_read(); //4 [read p]
gx816->op.r.p.l = gx816->stack_read(); //5 [read pcl]
gx816->op.r.p.h = gx816->stack_read(); //6 [read pch]
gx816->op.r.p.b = gx816->stack_read(); //7 [read pbr]
gx816->regs.pc = gx816->op.r.l;
if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
gx816->regs.p &= ~ PF_I;
}
/*****************
*** 0x60: rts ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
[3] pbr,pc+1 ; io
[4] 0,s+1 ; pcl
[5] 0,s+2 ; pch
[6] 0,s+2 ; io
*/
void g65816_op_rts(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->op.r.p.l = gx816->stack_read(); //4 [read low]
gx816->op.r.p.h = gx816->stack_read(); //5 [read high]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
g65816_incpc(1);
}
/*****************
*** 0x6b: rtl ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
[3] pbr,pc+1 ; io
[4] 0,s+1 ; pcl
[5] 0,s+2 ; pch
[6] 0,s+3 ; pbr
*/
void g65816_op_rtl(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->op.r.p.l = gx816->stack_read(); //4 [read low]
gx816->op.r.p.h = gx816->stack_read(); //5 [read high]
gx816->op.r.p.b = gx816->stack_read(); //6 [read bank]
gx816->regs.pc = gx816->op.r.l;
g65816_incpc(1);
}
/**********************
*** 0x80: bra near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_bra(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
g65816_incpc(2);
}
/*********************
*** 0x82: brl far ***
*********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; offset low
[3] pbr,pc+2 ; offset high
[4] pbr,pc+2 ; io
*/
void g65816_op_brl(void) {
word r;
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
r = gx816->regs.pc + (signed short)gx816->op.r.w;
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
g65816_incpc(3);
}
/**********************
*** 0x90: bcc near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_bcc(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
if(!(gx816->regs.p & PF_C)) {
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
}
g65816_incpc(2);
}
/**********************
*** 0xb0: bcs near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_bcs(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
if(gx816->regs.p & PF_C) {
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
}
g65816_incpc(2);
}
/**********************
*** 0xd0: bne near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_bne(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
if(!(gx816->regs.p & PF_Z)) {
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
}
g65816_incpc(2);
}
/**********************
*** 0xf0: beq near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_beq(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
if(gx816->regs.p & PF_Z) {
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
}
g65816_incpc(2);
}
/**********************
*** 0x10: bpl near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_bpl(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
if(!(gx816->regs.p & PF_N)) {
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
}
g65816_incpc(2);
}
/**********************
*** 0x30: bmi near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_bmi(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
if(gx816->regs.p & PF_N) {
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
}
g65816_incpc(2);
}
/**********************
*** 0x50: bvc near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_bvc(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
if(!(gx816->regs.p & PF_V)) {
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
}
g65816_incpc(2);
}
/**********************
*** 0x70: bvs near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void g65816_op_bvs(void) {
word r;
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
if(gx816->regs.p & PF_V) {
snes_time->add_cpu_icycles(1); //2a [i/o]
r = gx816->regs.pc + (signed char)gx816->op.r.b;
if(gx816->regs.e == true) {
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
snes_time->add_cpu_icycles(1); //2b [i/o]
}
}
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
}
g65816_incpc(2);
}
+526
View File
@@ -0,0 +1,526 @@
void g65816_flags_sbc_b() {
int r = gx816->regs.a.b - gx816->op.r.b - !(gx816->regs.p & PF_C);
//bcd
if(gx816->regs.p & PF_D) {
if(((r ) & 15) > 9)r -= 6;
if(((r >> 4) & 15) > 9)r -= 6 << 4;
}
g65816_testn(r & 0x80);
g65816_testv((gx816->regs.a.b ^ gx816->op.r.b) & (gx816->regs.a.b ^ (byte)r) & 0x80);
g65816_testz((byte)r == 0);
g65816_testc(r >= 0);
gx816->regs.a.b = r;
}
void g65816_flags_sbc_w() {
int r = gx816->regs.a.w - gx816->op.r.w - !(gx816->regs.p & PF_C);
//bcd
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;
}
g65816_testn(r & 0x8000);
g65816_testv((gx816->regs.a.w ^ gx816->op.r.w) & (gx816->regs.a.w ^ (word)r) & 0x8000);
g65816_testz((word)r == 0);
g65816_testc(r >= 0);
gx816->regs.a.w = r;
}
/************************
*** 0xe9: sbc #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void g65816_op_sbc_constb(void) {
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_constw(void) {
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
g65816_flags_sbc_w();
g65816_incpc(3);
}
/**********************
*** 0xed: sbc addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void g65816_op_sbc_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
g65816_flags_sbc_b();
g65816_incpc(3);
}
void g65816_op_sbc_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
g65816_flags_sbc_w();
g65816_incpc(3);
}
/************************
*** 0xfd: sbc addr,x ***
************************
cycles:
[1 ] pbr,pc ; opersbc
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void g65816_op_sbc_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
g65816_flags_sbc_b();
g65816_incpc(3);
}
void g65816_op_sbc_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
g65816_flags_sbc_w();
g65816_incpc(3);
}
/********************
*** 0xe5: sbc dp ***
********************
cycles:
[1 ] pbr,pc ; opersbc
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void g65816_op_sbc_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
/**********************
*** 0xf2: sbc (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void g65816_op_sbc_idpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_idpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
/**********************
*** 0xe7: sbc [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void g65816_op_sbc_ildpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_ildpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
/**********************
*** 0xef: sbc long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void g65816_op_sbc_longb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
g65816_flags_sbc_b();
g65816_incpc(4);
}
void g65816_op_sbc_longw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
g65816_flags_sbc_w();
g65816_incpc(4);
}
/************************
*** 0xff: sbc long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void g65816_op_sbc_longxb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
g65816_flags_sbc_b();
g65816_incpc(4);
}
void g65816_op_sbc_longxw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
g65816_flags_sbc_w();
g65816_incpc(4);
}
/************************
*** 0xf9: sbc addr,y ***
************************
cycles:
[1 ] pbr,pc ; opersbc
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_sbc_addryb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
g65816_flags_sbc_b();
g65816_incpc(3);
}
void g65816_op_sbc_addryw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
g65816_flags_sbc_w();
g65816_incpc(3);
}
/**********************
*** 0xf5: sbc dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void g65816_op_sbc_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
/************************
*** 0xe1: sbc (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void g65816_op_sbc_idpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_idpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
/************************
*** 0xf1: sbc (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_sbc_idpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_idpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
/************************
*** 0xf7: sbc [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void g65816_op_sbc_ildpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_ildpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
/**********************
*** 0xe3: sbc sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void g65816_op_sbc_srb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_srw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
/**************************
*** 0xf3: sbc (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_sbc_isryb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
g65816_flags_sbc_b();
g65816_incpc(2);
}
void g65816_op_sbc_isryw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
g65816_flags_sbc_w();
g65816_incpc(2);
}
+873
View File
@@ -0,0 +1,873 @@
/*****************
*** 0x0a: asl ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_aslb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
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);
}
void g65816_op_aslw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
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);
}
/**********************
*** 0x0e: asl addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void g65816_op_asl_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b <<= 1;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_asl_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.w & 0x8000);
gx816->op.r.w <<= 1;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/************************
*** 0x1e: asl addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void g65816_op_asl_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
snes_time->add_cpu_icycles(1); //6 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b <<= 1;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_asl_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
snes_time->add_cpu_icycles(1); //6 [i/o]
g65816_testc(gx816->op.r.w & 0x8000);
gx816->op.r.w <<= 1;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/********************
*** 0x06: asl dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void g65816_op_asl_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
snes_time->add_cpu_icycles(1); //4 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b <<= 1;
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_asl_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
snes_time->add_cpu_icycles(1); //4 [i/o]
g65816_testc(gx816->op.r.w & 0x8000);
gx816->op.r.w <<= 1;
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/**********************
*** 0x16: asl dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void g65816_op_asl_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b <<= 1;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_asl_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.w & 0x8000);
gx816->op.r.w <<= 1;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/*****************
*** 0x4a: lsr ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_lsrb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
g65816_testc(gx816->regs.a.b & 0x01);
gx816->regs.a.b >>= 1;
g65816_clrn();
g65816_testz(gx816->regs.a.b == 0);
g65816_incpc(1);
}
void g65816_op_lsrw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
g65816_testc(gx816->regs.a.w & 0x0001);
gx816->regs.a.w >>= 1;
g65816_clrn();
g65816_testz(gx816->regs.a.w == 0);
g65816_incpc(1);
}
/**********************
*** 0x4e: lsr addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void g65816_op_lsr_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.b & 0x01);
gx816->op.r.b >>= 1;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
g65816_clrn();
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_lsr_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.w & 0x0001);
gx816->op.r.w >>= 1;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
g65816_clrn();
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/************************
*** 0x5e: lsr addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void g65816_op_lsr_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
snes_time->add_cpu_icycles(1); //6 [i/o]
g65816_testc(gx816->op.r.b & 0x01);
gx816->op.r.b >>= 1;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
g65816_clrn();
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_lsr_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
snes_time->add_cpu_icycles(1); //6 [i/o]
g65816_testc(gx816->op.r.w & 0x0001);
gx816->op.r.w >>= 1;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
g65816_clrn();
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/********************
*** 0x46: lsr dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void g65816_op_lsr_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
snes_time->add_cpu_icycles(1); //4 [i/o]
g65816_testc(gx816->op.r.b & 0x01);
gx816->op.r.b >>= 1;
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
g65816_clrn();
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_lsr_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
snes_time->add_cpu_icycles(1); //4 [i/o]
g65816_testc(gx816->op.r.w & 0x0001);
gx816->op.r.w >>= 1;
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
g65816_clrn();
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/**********************
*** 0x56: lsr dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void g65816_op_lsr_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b >>= 1;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
g65816_clrn();
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_lsr_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.w & 0x001);
gx816->op.r.w >>= 1;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
g65816_clrn();
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/*****************
*** 0x2a: rol ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_rolb(void) {
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
g65816_testc(gx816->regs.a.b & 0x80);
gx816->regs.a.b <<= 1;
gx816->regs.a.b |= c;
g65816_testn(gx816->regs.a.b & 0x80);
g65816_testz(gx816->regs.a.b == 0);
g65816_incpc(1);
}
void g65816_op_rolw(void) {
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
g65816_testc(gx816->regs.a.w & 0x8000);
gx816->regs.a.w <<= 1;
gx816->regs.a.w |= c;
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
g65816_incpc(1);
}
/**********************
*** 0x2e: rol addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void g65816_op_rol_addrb(void) {
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b <<= 1;
gx816->op.r.b |= c;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_rol_addrw(void) {
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.w & 0x8000);
gx816->op.r.w <<= 1;
gx816->op.r.w |= c;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/************************
*** 0x3e: rol addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void g65816_op_rol_addrxb(void) {
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
snes_time->add_cpu_icycles(1); //6 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b <<= 1;
gx816->op.r.b |= c;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_rol_addrxw(void) {
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
snes_time->add_cpu_icycles(1); //6 [i/o]
g65816_testc(gx816->op.r.w & 0x8000);
gx816->op.r.w <<= 1;
gx816->op.r.w |= c;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/********************
*** 0x26: rol dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void g65816_op_rol_dpb(void) {
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
snes_time->add_cpu_icycles(1); //4 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b <<= 1;
gx816->op.r.b |= c;
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_rol_dpw(void) {
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
snes_time->add_cpu_icycles(1); //4 [i/o]
g65816_testc(gx816->op.r.w & 0x8000);
gx816->op.r.w <<= 1;
gx816->op.r.w |= c;
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/**********************
*** 0x36: rol dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void g65816_op_rol_dpxb(void) {
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b <<= 1;
gx816->op.r.b |= c;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_rol_dpxw(void) {
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.w & 0x8000);
gx816->op.r.w <<= 1;
gx816->op.r.w |= c;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/*****************
*** 0x6a: ror ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void g65816_op_rorb(void) {
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
g65816_testc(gx816->regs.a.b & 0x01);
gx816->regs.a.b >>= 1;
gx816->regs.a.b |= c;
g65816_testn(gx816->regs.a.b & 0x80);
g65816_testz(gx816->regs.a.b == 0);
g65816_incpc(1);
}
void g65816_op_rorw(void) {
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
g65816_testc(gx816->regs.a.w & 0x0001);
gx816->regs.a.w >>= 1;
gx816->regs.a.w |= c;
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
g65816_incpc(1);
}
/**********************
*** 0x6e: ror addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void g65816_op_ror_addrb(void) {
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.b & 0x01);
gx816->op.r.b >>= 1;
gx816->op.r.b |= c;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_ror_addrw(void) {
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.w & 0x0001);
gx816->op.r.w >>= 1;
gx816->op.r.w |= c;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/************************
*** 0x7e: ror addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void g65816_op_ror_addrxb(void) {
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
snes_time->add_cpu_icycles(1); //6 [i/o]
g65816_testc(gx816->op.r.b & 0x01);
gx816->op.r.b >>= 1;
gx816->op.r.b |= c;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(3);
}
void g65816_op_ror_addrxw(void) {
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
snes_time->add_cpu_icycles(1); //6 [i/o]
g65816_testc(gx816->op.r.w & 0x0001);
gx816->op.r.w >>= 1;
gx816->op.r.w |= c;
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(3);
}
/********************
*** 0x66: ror dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void g65816_op_ror_dpb(void) {
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
snes_time->add_cpu_icycles(1); //4 [i/o]
g65816_testc(gx816->op.r.b & 0x01);
gx816->op.r.b >>= 1;
gx816->op.r.b |= c;
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_ror_dpw(void) {
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
snes_time->add_cpu_icycles(1); //4 [i/o]
g65816_testc(gx816->op.r.w & 0x0001);
gx816->op.r.w >>= 1;
gx816->op.r.w |= c;
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
/**********************
*** 0x76: ror dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void g65816_op_ror_dpxb(void) {
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.b & 0x80);
gx816->op.r.b >>= 1;
gx816->op.r.b |= c;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
g65816_testn(gx816->op.r.b & 0x80);
g65816_testz(gx816->op.r.b == 0);
g65816_incpc(2);
}
void g65816_op_ror_dpxw(void) {
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
snes_time->add_cpu_icycles(1); //5 [i/o]
g65816_testc(gx816->op.r.w & 0x001);
gx816->op.r.w >>= 1;
gx816->op.r.w |= c;
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
g65816_testn(gx816->op.r.w & 0x8000);
g65816_testz(gx816->op.r.w == 0);
g65816_incpc(2);
}
+443
View File
@@ -0,0 +1,443 @@
/**********************
*** 0x8d: sta addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void g65816_op_sta_addrb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //4 [write]
g65816_incpc(3);
}
void g65816_op_sta_addrw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //4 [write low]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //4a [write high]
g65816_incpc(3);
}
/************************
*** 0x9d: sta addr,x ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void g65816_op_sta_addrxb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //3a [write i/o]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->regs.a.b); //4 [write]
g65816_incpc(3);
}
void g65816_op_sta_addrxw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //3a [write i/o]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->regs.a.p.l); //4 [write low]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->regs.a.p.h); //4a [write high]
g65816_incpc(3);
}
/********************
*** 0x85: sta dp ***
********************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void g65816_op_sta_dpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->regs.a.b); //3 [write]
g65816_incpc(2);
}
void g65816_op_sta_dpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->regs.a.p.l); //3 [write low]
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->regs.a.p.h); //3a [write high]
g65816_incpc(2);
}
/**********************
*** 0x92: sta (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void g65816_op_sta_idpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //5 [write]
g65816_incpc(2);
}
void g65816_op_sta_idpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //5 [write low]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //5a [write high]
g65816_incpc(2);
}
/**********************
*** 0x87: sta [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void g65816_op_sta_ildpb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.b); //6 [write]
g65816_incpc(2);
}
void g65816_op_sta_ildpw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.p.l); //6 [write low]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + 1, gx816->regs.a.p.h); //6a [write high]
g65816_incpc(2);
}
/**********************
*** 0x8f: sta long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void g65816_op_sta_longb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.b); //5 [write]
g65816_incpc(4);
}
void g65816_op_sta_longw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.p.l); //5 [write]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + 1, gx816->regs.a.p.h); //5a [write]
g65816_incpc(4);
}
/************************
*** 0x9f: sta long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void g65816_op_sta_longxb(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x, gx816->regs.a.b); //5 [write]
g65816_incpc(4);
}
void g65816_op_sta_longxw(void) {
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x, gx816->regs.a.p.l); //5 [write]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1, gx816->regs.a.p.h); //5a [write]
g65816_incpc(4);
}
/************************
*** 0x99: sta addr,y ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_sta_addryb(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //3a [write i/o]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //4 [write]
g65816_incpc(3);
}
void g65816_op_sta_addryw(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //3a [write i/o]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //4 [write low]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //4a [write high]
g65816_incpc(3);
}
/**********************
*** 0x95: sta dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void g65816_op_sta_dpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->regs.a.b); //4 [write]
g65816_incpc(2);
}
void g65816_op_sta_dpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->regs.a.p.l); //4 [write low]
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->regs.a.p.h); //4a [write high]
g65816_incpc(2);
}
/************************
*** 0x81: sta (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void g65816_op_sta_idpxb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //6 [write]
g65816_incpc(2);
}
void g65816_op_sta_idpxw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //6 [write low]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //6 [write high]
g65816_incpc(2);
}
/************************
*** 0x91: sta (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_sta_idpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
snes_time->add_cpu_icycles(1); //4a [write i/o]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //5 [write]
g65816_incpc(2);
}
void g65816_op_sta_idpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
snes_time->add_cpu_icycles(1); //4a [write i/o]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //5 [write low]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //5a [write high]
g65816_incpc(2);
}
/************************
*** 0x97: sta [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void g65816_op_sta_ildpyb(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y, gx816->regs.a.b); //6 [write]
g65816_incpc(2);
}
void g65816_op_sta_ildpyw(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [dl!=0]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y, gx816->regs.a.p.l); //6 [write low]
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1, gx816->regs.a.p.h); //6a [write high]
g65816_incpc(2);
}
/**********************
*** 0x83: sta sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void g65816_op_sta_srb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op_write(OPMODE_SP, gx816->op.sp, gx816->regs.a.b); //4 [write]
g65816_incpc(2);
}
void g65816_op_sta_srw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op_write(OPMODE_SP, gx816->op.sp, gx816->regs.a.p.l); //4 [write low]
gx816->op_write(OPMODE_SP, gx816->op.sp + 1, gx816->regs.a.p.h); //4a [write high]
g65816_incpc(2);
}
/**************************
*** 0x93: sta (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void g65816_op_sta_isryb(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //7 [write]
g65816_incpc(2);
}
void g65816_op_sta_isryw(void) {
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
snes_time->add_cpu_icycles(1); //3 [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
snes_time->add_cpu_icycles(1); //6 [i/o]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //7 [write low]
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //7a [write high]
g65816_incpc(2);
}
+357
View File
@@ -0,0 +1,357 @@
/*****************
*** 0x48: pha ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void g65816_op_phab(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.a.b); //3 [reg low]
g65816_incpc(1);
}
void g65816_op_phaw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.a.p.h); //3a [reg high]
gx816->stack_write(gx816->regs.a.p.l); //3 [reg low]
g65816_incpc(1);
}
/*****************
*** 0x8b: phb ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void g65816_op_phb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.db); //3 [reg low]
g65816_incpc(1);
}
/*****************
*** 0x0b: phd ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void g65816_op_phd(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.d >> 8); //3a [reg high]
gx816->stack_write(gx816->regs.d); //3 [reg low]
g65816_incpc(1);
}
/*****************
*** 0x4b: phk ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void g65816_op_phk(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.pc >> 16); //3 [reg low]
g65816_incpc(1);
}
/*****************
*** 0x08: php ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void g65816_op_php(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.p); //3 [reg low]
g65816_incpc(1);
}
/*****************
*** 0xda: phx ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void g65816_op_phxb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.x); //3 [reg low]
g65816_incpc(1);
}
void g65816_op_phxw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.x >> 8); //3a [reg high]
gx816->stack_write(gx816->regs.x); //3 [reg low]
g65816_incpc(1);
}
/*****************
*** 0x5a: phy ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void g65816_op_phyb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.y); //3 [reg low]
g65816_incpc(1);
}
void g65816_op_phyw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(1); //2 [i/o]
gx816->stack_write(gx816->regs.y >> 8); //3a [reg high]
gx816->stack_write(gx816->regs.y); //3 [reg low]
g65816_incpc(1);
}
/*****************
*** 0x68: pla ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void g65816_op_plab(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.a.b = gx816->stack_read(); //4 [reg low]
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); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.a.p.l = gx816->stack_read(); //4 [reg low]
gx816->regs.a.p.h = gx816->stack_read(); //4a [reg high]
g65816_testn(gx816->regs.a.w & 0x8000);
g65816_testz(gx816->regs.a.w == 0);
g65816_incpc(1);
}
/*****************
*** 0xab: plb ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void g65816_op_plb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.db = gx816->stack_read(); //4 [reg low]
g65816_testn(gx816->regs.db & 0x80);
g65816_testz(gx816->regs.db == 0);
g65816_incpc(1);
}
/*****************
*** 0x2b: pld ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void g65816_op_pld(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.d = gx816->stack_read(); //4 [reg low]
gx816->regs.d |= gx816->stack_read() << 8; //4a [reg high]
g65816_testn(gx816->regs.d & 0x8000);
g65816_testz(gx816->regs.d == 0);
g65816_incpc(1);
}
/*****************
*** 0x28: plp ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void g65816_op_plp(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.p = gx816->stack_read(); //4 [reg low]
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; }
}
/*****************
*** 0xfa: plx ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void g65816_op_plxb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.x = gx816->stack_read(); //4 [reg low]
g65816_testn(gx816->regs.x & 0x80);
g65816_testz(gx816->regs.x == 0);
g65816_incpc(1);
}
void g65816_op_plxw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.x = gx816->stack_read(); //4 [reg low]
gx816->regs.x |= gx816->stack_read() << 8; //4a [reg high]
g65816_testn(gx816->regs.x & 0x8000);
g65816_testz(gx816->regs.x == 0);
g65816_incpc(1);
}
/*****************
*** 0x7a: ply ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void g65816_op_plyb(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.y = gx816->stack_read(); //4 [reg low]
g65816_testn(gx816->regs.y & 0x80);
g65816_testz(gx816->regs.y == 0);
g65816_incpc(1);
}
void g65816_op_plyw(void) {
snes_time->add_cpu_pcycles(1); //1 [op fetch]
snes_time->add_cpu_icycles(2); //2,3 [i/o]
gx816->regs.y = gx816->stack_read(); //4 [reg low]
gx816->regs.y |= gx816->stack_read() << 8; //4a [reg high]
g65816_testn(gx816->regs.y & 0x8000);
g65816_testz(gx816->regs.y == 0);
g65816_incpc(1);
}
/**********************
*** 0xf4: pea addr ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] pbr,pc+2 ; aah
[4] 0,s ; aah
[5] 0,s-1 ; aal
*/
void g65816_op_pea(void) {
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
gx816->stack_write(gx816->op.aa.p.h); //4 [write high]
gx816->stack_write(gx816->op.aa.p.l); //5 [write low]
g65816_incpc(3);
}
/**********************
*** 0xd4: pei (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,s ; aah
[6 ] 0,s-1 ; aal
*/
void g65816_op_pei(void) {
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
gx816->op_cond(2); //2a [i/o]
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read aal]
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [read aah]
gx816->stack_write(gx816->op.aa.p.h); //5 [write aah]
gx816->stack_write(gx816->op.aa.p.l); //6 [write aal]
g65816_incpc(2);
}
/**********************
*** 0x62: per addr ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; offset low
[3] pbr,pc+2 ; offset high
[4] pbr,pc+2 ; io
[5] 0,s ; pch+offset
[6] 0,s-1 ; pcl+offset
*/
void g65816_op_per(void) {
word r;
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
snes_time->add_cpu_icycles(1); //4 [i/o]
r = (gx816->regs.pc + (signed short)gx816->op.aa.w + 3);
gx816->stack_write(r >> 8); //5 [write pch]
gx816->stack_write(r); //6 [write pcl]
g65816_incpc(3);
}
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="bsnes" version="1.0.0.0" processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
</assembly>
-8
View File
@@ -1,8 +0,0 @@
[Desktop Entry]
Name=bsnes
Comment=SNES emulator
Exec=bsnes
Icon=bsnes
Terminal=false
Type=Application
Categories=Game;Emulator;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

-57307
View File
File diff suppressed because it is too large. Load diff
-12
View File
@@ -1,12 +0,0 @@
gameboy_objects := gameboy-system gameboy-scheduler
gameboy_objects += gameboy-memory gameboy-cartridge
gameboy_objects += gameboy-cpu gameboy-apu gameboy-lcd
objects += $(gameboy_objects)
obj/gameboy-system.o: $(gameboy)/system/system.cpp $(call rwildcard,$(gameboy)/system/)
obj/gameboy-scheduler.o: $(gameboy)/scheduler/scheduler.cpp $(call rwildcard,$(gameboy)/scheduler/)
obj/gameboy-cartridge.o: $(gameboy)/cartridge/cartridge.cpp $(call rwildcard,$(gameboy)/cartridge/)
obj/gameboy-memory.o: $(gameboy)/memory/memory.cpp $(call rwildcard,$(gameboy)/memory/)
obj/gameboy-cpu.o: $(gameboy)/cpu/cpu.cpp $(call rwildcard,$(gameboy)/cpu/)
obj/gameboy-apu.o: $(gameboy)/apu/apu.cpp $(call rwildcard,$(gameboy)/apu/)
obj/gameboy-lcd.o: $(gameboy)/lcd/lcd.cpp $(call rwildcard,$(gameboy)/lcd/)
-85
View File
@@ -1,85 +0,0 @@
#include <gameboy/gameboy.hpp>
#define APU_CPP
namespace GameBoy {
#include "mmio/mmio.cpp"
#include "serialization.cpp"
APU apu;
void APU::power() {
for(unsigned n = 0xff10; n <= 0xff3f; n++) bus.mmio[n] = this;
channel1.sweep_time = 0;
channel1.sweep_direction = 0;
channel1.sweep_shift = 0;
channel1.wave_pattern_duty = 0;
channel1.sound_length = 0;
channel1.initial_envelope_volume = 0;
channel1.envelope_direction = 0;
channel1.envelope_sweep = 0;
channel1.frequency = 0;
channel1.initialize = 0;
channel1.consecutive_selection = 0;
channel2.wave_pattern_duty = 0;
channel2.sound_length = 0;
channel2.initial_envelope_volume = 0;
channel2.envelope_direction = 0;
channel2.envelope_sweep = 0;
channel2.frequency = 0;
channel2.initialize = 0;
channel2.consecutive_selection = 0;
channel3.off = 0;
channel3.sound_length = 0;
channel3.output_level = 0;
channel3.frequency = 0;
channel3.initialize = 0;
channel3.consecutive_selection = 0;
for(unsigned n = 0; n < 16; n++) channel3.pattern[n] = 0;
channel4.sound_length = 0;
channel4.initial_envelope_volume = 0;
channel4.envelope_direction = 0;
channel4.envelope_sweep = 0;
channel4.shift_clock_frequency = 0;
channel4.counter_step_width = 0;
channel4.dividing_ratio = 0;
channel4.initialize = 0;
channel4.consecutive_selection = 0;
control.output_vin_to_so2 = 0;
control.so2_output_level = 0;
control.output_vin_to_so1 = 0;
control.so1_output_level = 0;
control.output_channel4_to_so2 = 0;
control.output_channel3_to_so2 = 0;
control.output_channel2_to_so2 = 0;
control.output_channel1_to_so2 = 0;
control.output_channel4_to_so1 = 0;
control.output_channel3_to_so1 = 0;
control.output_channel2_to_so1 = 0;
control.output_channel1_to_so1 = 0;
control.sound_on = 0;
control.channel4_on = 0;
control.channel3_on = 0;
control.channel2_on = 0;
control.channel1_on = 0;
}
}
-9
View File
@@ -1,9 +0,0 @@
struct APU : Processor, MMIO {
#include "mmio/mmio.hpp"
void power();
void serialize(serializer&);
};
extern APU apu;
-248
View File
@@ -1,248 +0,0 @@
#ifdef APU_CPP
uint8 APU::mmio_read(uint16 addr) {
if(addr == 0xff10) { //NR10
return (channel1.sweep_time << 4)
| (channel1.sweep_direction << 3)
| (channel1.sweep_shift << 0);
}
if(addr == 0xff11) { //NR11
return (channel1.wave_pattern_duty << 6);
}
if(addr == 0xff12) { //NR12
return (channel1.initial_envelope_volume << 4)
| (channel1.envelope_direction << 3)
| (channel1.envelope_sweep << 0);
}
if(addr == 0xff14) { //NR14
return (channel1.consecutive_selection << 6);
}
if(addr == 0xff16) { //NR21
return (channel2.wave_pattern_duty << 6);
}
if(addr == 0xff17) { //NR22
return (channel2.initial_envelope_volume << 4)
| (channel2.envelope_direction << 3)
| (channel2.envelope_sweep << 0);
}
if(addr == 0xff19) { //NR24
return (channel2.consecutive_selection << 6);
}
if(addr == 0xff1a) { //NR30
return (channel3.off << 7);
}
if(addr == 0xff1b) { //NR31
return (channel3.sound_length << 0);
}
if(addr == 0xff1c) { //NR32
return (channel3.output_level << 5);
}
if(addr == 0xff1e) { //NR34
return (channel3.consecutive_selection << 6);
}
if(addr == 0xff20) { //NR41
return (channel4.sound_length << 0);
}
if(addr == 0xff21) { //NR42
return (channel4.initial_envelope_volume << 4)
| (channel4.envelope_direction << 3)
| (channel4.envelope_sweep << 0);
}
if(addr == 0xff22) { //NR43
return (channel4.shift_clock_frequency << 4)
| (channel4.counter_step_width << 3)
| (channel4.dividing_ratio << 0);
}
if(addr == 0xff23) { //NR44
return (channel4.consecutive_selection << 6);
}
if(addr == 0xff24) { //NR50
return (control.output_vin_to_so2 << 7)
| (control.so2_output_level << 4)
| (control.output_vin_to_so1 << 3)
| (control.so1_output_level << 0);
}
if(addr == 0xff25) { //NR51
return (control.output_channel4_to_so2 << 7)
| (control.output_channel3_to_so2 << 6)
| (control.output_channel2_to_so2 << 5)
| (control.output_channel1_to_so2 << 4)
| (control.output_channel4_to_so1 << 3)
| (control.output_channel3_to_so1 << 2)
| (control.output_channel2_to_so1 << 1)
| (control.output_channel1_to_so1 << 0);
}
if(addr == 0xff26) { //NR52
return (control.sound_on << 7);
}
if(addr >= 0xff30 && addr <= 0xff3f) {
return channel3.pattern[addr & 15];
}
return 0x00;
}
void APU::mmio_write(uint16 addr, uint8 data) {
if(addr == 0xff10) { //NR10
channel1.sweep_time = (data >> 4) & 7;
channel1.sweep_direction = data & 0x08;
channel1.sweep_shift = data & 0x07;
return;
}
if(addr == 0xff11) { //NR11
channel1.wave_pattern_duty = (data >> 6) & 3;
channel1.sound_length = data & 0x3f;
return;
}
if(addr == 0xff12) { //NR12
channel1.initial_envelope_volume = (data >> 4) & 15;
channel1.envelope_direction = data & 0x08;
channel1.envelope_sweep = data & 0x07;
return;
}
if(addr == 0xff13) { //NR13
channel1.frequency = (channel1.frequency & 0x0700) | (data << 0);
return;
}
if(addr == 0xff14) { //NR14
channel1.initialize = data & 0x80;
channel1.consecutive_selection = data & 0x40;
channel1.frequency = ((data & 7) << 8) | (channel1.frequency & 0x00ff);
return;
}
if(addr == 0xff16) { //NR21
channel2.wave_pattern_duty = (data >> 6) & 3;
channel2.sound_length = data & 0x3f;
return;
}
if(addr == 0xff17) { //NR22
channel2.initial_envelope_volume = (data >> 4) & 15;
channel2.envelope_direction = data & 0x08;
channel2.envelope_sweep = data & 0x07;
return;
}
if(addr == 0xff18) { //NR23
channel2.frequency = (channel2.frequency & 0x0700) | (data << 0);
return;
}
if(addr == 0xff19) { //NR24
channel2.initialize = data & 0x80;
channel2.consecutive_selection = data & 0x40;
channel2.frequency = ((data & 7) << 8) | (channel2.frequency & 0x00ff);
return;
}
if(addr == 0xff1a) { //NR30
channel3.off = data & 0x80;
return;
}
if(addr == 0xff1b) { //NR31
channel3.sound_length = data;
return;
}
if(addr == 0xff1c) { //NR32
channel3.output_level = (data >> 5) & 3;
return;
}
if(addr == 0xff1d) { //NR33
channel3.frequency = (channel3.frequency & 0x0700) | (data << 0);
return;
}
if(addr == 0xff1e) { //NR34
channel3.initialize = data & 0x80;
channel3.consecutive_selection = data & 0x40;
channel3.frequency = ((data & 7) << 8) | (channel3.frequency & 0x00ff);
return;
}
if(addr == 0xff20) { //NR41
channel4.sound_length = data & 0x3f;
return;
}
if(addr == 0xff21) { //NR42
channel4.initial_envelope_volume = (data >> 3) & 15;
channel4.envelope_direction = data & 0x08;
channel4.envelope_sweep = data & 0x07;
return;
}
if(addr == 0xff22) { //NR43
channel4.shift_clock_frequency = (data >> 4) & 15;
channel4.counter_step_width = data & 0x08;
channel4.dividing_ratio = data & 0x07;
return;
}
if(addr == 0xff23) { //NR44
channel4.initialize = data & 0x80;
channel4.consecutive_selection = data & 0x40;
return;
}
if(addr == 0xff24) { //NR50
control.output_vin_to_so2 = data & 0x80;
control.so2_output_level = (data >> 4) & 7;
control.output_vin_to_so1 = data & 0x08;
control.so1_output_level = (data >> 0) & 7;
return;
}
if(addr == 0xff25) { //NR51
control.output_channel4_to_so2 = data & 0x80;
control.output_channel3_to_so2 = data & 0x40;
control.output_channel2_to_so2 = data & 0x20;
control.output_channel1_to_so2 = data & 0x10;
control.output_channel4_to_so1 = data & 0x08;
control.output_channel3_to_so1 = data & 0x04;
control.output_channel2_to_so1 = data & 0x02;
control.output_channel1_to_so1 = data & 0x01;
return;
}
if(addr == 0xff26) { //NR52
control.sound_on = data & 0x80;
control.channel4_on = data & 0x08;
control.channel3_on = data & 0x04;
control.channel2_on = data & 0x02;
control.channel1_on = data & 0x01;
return;
}
if(addr >= 0xff30 && addr <= 0xff3f) {
channel3.pattern[addr & 15] = data;
return;
}
}
#endif
-102
View File
@@ -1,102 +0,0 @@
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
struct Channel1 { //tone and sweep
//$ff10 NR10
unsigned sweep_time;
bool sweep_direction;
unsigned sweep_shift;
//$ff11 NR11
unsigned wave_pattern_duty;
unsigned sound_length;
//$ff12 NR12
unsigned initial_envelope_volume;
bool envelope_direction;
unsigned envelope_sweep;
//$ff13,$ff14 NR13,NR14
unsigned frequency;
bool initialize;
bool consecutive_selection;
} channel1;
struct Channel2 { //tone
//$ff16 NR21
unsigned wave_pattern_duty;
unsigned sound_length;
//$ff17 NR22
unsigned initial_envelope_volume;
bool envelope_direction;
unsigned envelope_sweep;
//$ff18,$ff19 NR23,NR24
unsigned frequency;
bool initialize;
bool consecutive_selection;
} channel2;
struct Channel3 { //wave output
//$ff1a NR30
bool off;
//$ff1b NR31
unsigned sound_length;
//$ff1c NR32
unsigned output_level;
//$ff1d,$ff1e NR33,NR34
unsigned frequency;
bool initialize;
bool consecutive_selection;
//$ff30-ff3f
uint8 pattern[16];
} channel3;
struct Channel4 { //noise
//$ff20 NR41
unsigned sound_length;
//$ff21 NR42
unsigned initial_envelope_volume;
bool envelope_direction;
unsigned envelope_sweep;
//$ff22 NR43
unsigned shift_clock_frequency;
bool counter_step_width;
unsigned dividing_ratio;
//$ff23 NR44
bool initialize;
bool consecutive_selection;
} channel4;
struct Control {
//$ff24 NR50
bool output_vin_to_so2;
unsigned so2_output_level;
bool output_vin_to_so1;
unsigned so1_output_level;
//$ff25 NR51
bool output_channel4_to_so2;
bool output_channel3_to_so2;
bool output_channel2_to_so2;
bool output_channel1_to_so2;
bool output_channel4_to_so1;
bool output_channel3_to_so1;
bool output_channel2_to_so1;
bool output_channel1_to_so1;
//$ff26 NR52
bool sound_on;
bool channel4_on;
bool channel3_on;
bool channel2_on;
bool channel1_on;
} control;
-6
View File
@@ -1,6 +0,0 @@
#ifdef APU_CPP
void APU::serialize(serializer &s) {
}
#endif
-148
View File
@@ -1,148 +0,0 @@
#include <gameboy/gameboy.hpp>
#include <nall/crc32.hpp>
#define CARTRIDGE_CPP
namespace GameBoy {
#include "mbc0/mbc0.cpp"
#include "mbc1/mbc1.cpp"
#include "mbc2/mbc2.cpp"
#include "mbc3/mbc3.cpp"
#include "mbc5/mbc5.cpp"
#include "mmm01/mmm01.cpp"
#include "huc1/huc1.cpp"
#include "huc3/huc3.cpp"
#include "serialization.cpp"
Cartridge cartridge;
void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) {
if(size == 0) size = 32768;
romdata = allocate<uint8>(romsize = size, 0xff);
if(data) memcpy(romdata, data, size);
//uint32_t crc = crc32_calculate(data, size);
//print("CRC32 = ", hex<4>(crc), "\n");
info.mapper = Mapper::Unknown;
info.ram = false;
info.battery = false;
info.rtc = false;
info.rumble = false;
info.romsize = 0;
info.ramsize = 0;
xml_element document = xml_parse(xml);
foreach(head, document.element) {
if(head.name == "cartridge") {
foreach(attr, head.attribute) {
if(attr.name == "mapper") {
if(attr.content == "none") info.mapper = Mapper::MBC0;
if(attr.content == "MBC1") info.mapper = Mapper::MBC1;
if(attr.content == "MBC2") info.mapper = Mapper::MBC2;
if(attr.content == "MBC3") info.mapper = Mapper::MBC3;
if(attr.content == "MBC5") info.mapper = Mapper::MBC5;
if(attr.content == "MMM01") info.mapper = Mapper::MMM01;
if(attr.content == "HuC1") info.mapper = Mapper::HuC1;
if(attr.content == "HuC3") info.mapper = Mapper::HuC3;
}
if(attr.name == "rtc") info.rtc = (attr.content == "true" ? true : false);
if(attr.name == "rumble") info.rumble = (attr.content == "true" ? true : false);
}
foreach(elem, head.element) {
if(elem.name == "rom") {
foreach(attr, elem.attribute) {
if(attr.name == "size") info.romsize = hex(attr.content);
}
}
if(elem.name == "ram") {
info.ram = true;
foreach(attr, elem.attribute) {
if(attr.name == "size") info.ramsize = hex(attr.content);
if(attr.name == "battery") info.battery = (attr.content == "true" ? true : false);
}
}
}
}
}
ramdata = new uint8_t[ramsize = info.ramsize]();
loaded = true;
}
void Cartridge::unload() {
if(loaded == false) return;
if(romdata) { delete[] romdata; romdata = 0; }
if(ramdata) { delete[] ramdata; ramdata = 0; }
loaded = false;
}
uint8 Cartridge::rom_read(unsigned addr) {
if(addr >= romsize) addr %= romsize;
return romdata[addr];
}
void Cartridge::rom_write(unsigned addr, uint8 data) {
if(addr >= romsize) addr %= romsize;
romdata[addr] = data;
}
uint8 Cartridge::ram_read(unsigned addr) {
if(ramsize == 0) return 0x00;
if(addr >= ramsize) addr %= ramsize;
return ramdata[addr];
}
void Cartridge::ram_write(unsigned addr, uint8 data) {
if(ramsize == 0) return;
if(addr >= ramsize) addr %= ramsize;
ramdata[addr] = data;
}
void Cartridge::power() {
mbc0.power();
mbc1.power();
mbc2.power();
mbc3.power();
mbc5.power();
mmm01.power();
huc1.power();
huc3.power();
map();
}
void Cartridge::map() {
MMIO *mapper = 0;
switch(info.mapper) { default:
case Mapper::MBC0: mapper = &mbc0; break;
case Mapper::MBC1: mapper = &mbc1; break;
case Mapper::MBC2: mapper = &mbc2; break;
case Mapper::MBC3: mapper = &mbc3; break;
case Mapper::MBC5: mapper = &mbc5; break;
case Mapper::MMM01: mapper = &mmm01; break;
case Mapper::HuC1: mapper = &huc1; break;
case Mapper::HuC3: mapper = &huc3; break;
}
if(mapper) {
for(unsigned n = 0x0000; n <= 0x7fff; n++) bus.mmio[n] = mapper;
for(unsigned n = 0xa000; n <= 0xbfff; n++) bus.mmio[n] = mapper;
}
}
Cartridge::Cartridge() {
loaded = false;
romdata = 0;
ramdata = 0;
}
Cartridge::~Cartridge() {
unload();
}
}
-60
View File
@@ -1,60 +0,0 @@
struct Cartridge : property<Cartridge> {
#include "mbc0/mbc0.hpp"
#include "mbc1/mbc1.hpp"
#include "mbc2/mbc2.hpp"
#include "mbc3/mbc3.hpp"
#include "mbc5/mbc5.hpp"
#include "mmm01/mmm01.hpp"
#include "huc1/huc1.hpp"
#include "huc3/huc3.hpp"
enum Mapper : unsigned {
MBC0,
MBC1,
MBC2,
MBC3,
MBC5,
MMM01,
HuC1,
HuC3,
Unknown,
};
struct Information {
string xml;
Mapper mapper;
bool ram;
bool battery;
bool rtc;
bool rumble;
unsigned romsize;
unsigned ramsize;
} info;
readonly<bool> loaded;
uint8_t *romdata;
unsigned romsize;
uint8_t *ramdata;
unsigned ramsize;
void load(const string &xml, const uint8_t *data, unsigned size);
void unload();
uint8 rom_read(unsigned addr);
void rom_write(unsigned addr, uint8 data);
uint8 ram_read(unsigned addr);
void ram_write(unsigned addr, uint8 data);
void power();
void map();
void serialize(serializer&);
Cartridge();
~Cartridge();
};
extern Cartridge cartridge;
-53
View File
@@ -1,53 +0,0 @@
#ifdef CARTRIDGE_CPP
uint8 Cartridge::HuC1::mmio_read(uint16 addr) {
if(within<0x0000, 0x3fff>(addr)) {
return cartridge.rom_read(addr);
}
if(within<0x4000, 0x7fff>(addr)) {
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
return 0x00;
}
return 0x00;
}
void Cartridge::HuC1::mmio_write(uint16 addr, uint8 data) {
if(within<0x0000, 0x1fff>(addr)) {
ram_enable = (data & 0x0f) == 0x0a;
return;
}
if(within<0x2000, 0x3fff>(addr)) {
rom_select = data;
return;
}
if(within<0x4000, 0x5fff>(addr)) {
ram_select = data;
return;
}
if(within<0x6000, 0x7fff>(addr)) {
//unknown purpose
return;
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
return;
}
}
void Cartridge::HuC1::power() {
ram_enable = false;
rom_select = 0x01;
ram_select = 0x00;
}
#endif
-9
View File
@@ -1,9 +0,0 @@
struct HuC1 : MMIO {
bool ram_enable; //0000-1fff
uint8 rom_select; //2000-3fff
uint8 ram_select; //4000-5fff
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
void power();
} huc1;
-53
View File
@@ -1,53 +0,0 @@
#ifdef CARTRIDGE_CPP
uint8 Cartridge::HuC3::mmio_read(uint16 addr) {
if(within<0x0000, 0x3fff>(addr)) {
return cartridge.rom_read(addr);
}
if(within<0x4000, 0x7fff>(addr)) {
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
return 0x00;
}
return 0x00;
}
void Cartridge::HuC3::mmio_write(uint16 addr, uint8 data) {
if(within<0x0000, 0x1fff>(addr)) {
ram_enable = (data & 0x0f) == 0x0a;
return;
}
if(within<0x2000, 0x3fff>(addr)) {
rom_select = data;
return;
}
if(within<0x4000, 0x5fff>(addr)) {
ram_select = data;
return;
}
if(within<0x6000, 0x7fff>(addr)) {
//unknown purpose
return;
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
return;
}
}
void Cartridge::HuC3::power() {
ram_enable = false;
rom_select = 0x01;
ram_select = 0x00;
}
#endif
-9
View File
@@ -1,9 +0,0 @@
struct HuC3 : MMIO {
bool ram_enable; //0000-1fff
uint8 rom_select; //2000-3fff
uint8 ram_select; //4000-5fff
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
void power();
} huc3;
-25
View File
@@ -1,25 +0,0 @@
#ifdef CARTRIDGE_CPP
uint8 Cartridge::MBC0::mmio_read(uint16 addr) {
if(within<0x0000, 0x7fff>(addr)) {
return cartridge.rom_read(addr);
}
if(within<0xa000, 0xbfff>(addr)) {
return cartridge.ram_read(addr & 0x1fff);
}
return 0x00;
}
void Cartridge::MBC0::mmio_write(uint16 addr, uint8 data) {
if(within<0xa000, 0xbfff>(addr)) {
cartridge.ram_write(addr & 0x1fff, data);
return;
}
}
void Cartridge::MBC0::power() {
}
#endif
-5
View File
@@ -1,5 +0,0 @@
struct MBC0 : MMIO {
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
void power();
} mbc0;
-70
View File
@@ -1,70 +0,0 @@
#ifdef CARTRIDGE_CPP
uint8 Cartridge::MBC1::mmio_read(uint16 addr) {
if(within<0x0000, 0x3fff>(addr)) {
return cartridge.rom_read(addr);
}
if(within<0x4000, 0x7fff>(addr)) {
if(mode_select == 0) {
return cartridge.rom_read((ram_select << 19) | (rom_select << 14) | (addr & 0x3fff));
} else {
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
}
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) {
if(mode_select == 0) {
return cartridge.ram_read(addr & 0x1fff);
} else {
return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
}
}
return 0x00;
}
return 0x00;
}
void Cartridge::MBC1::mmio_write(uint16 addr, uint8 data) {
if(within<0x0000, 0x1fff>(addr)) {
ram_enable = (data & 0x0f) == 0x0a;
return;
}
if(within<0x2000, 0x3fff>(addr)) {
rom_select = (data & 0x1f) + ((data & 0x1f) == 0);
return;
}
if(within<0x4000, 0x5fff>(addr)) {
ram_select = data & 0x03;
return;
}
if(within<0x6000, 0x7fff>(addr)) {
mode_select = data & 0x01;
return;
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) {
if(mode_select == 0) {
cartridge.ram_write(addr & 0x1fff, data);
} else {
cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
}
}
return;
}
}
void Cartridge::MBC1::power() {
ram_enable = false;
rom_select = 0x01;
ram_select = 0x00;
mode_select = 0;
}
#endif
-10
View File
@@ -1,10 +0,0 @@
struct MBC1 : MMIO {
bool ram_enable; //0000-1fff
uint8 rom_select; //2000-3fff
uint8 ram_select; //4000-5fff
bool mode_select; //6000-7fff
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
void power();
} mbc1;
-42
View File
@@ -1,42 +0,0 @@
#ifdef CARTRIDGE_CPP
uint8 Cartridge::MBC2::mmio_read(uint16 addr) {
if(within<0x0000, 0x3fff>(addr)) {
return cartridge.rom_read(addr);
}
if(within<0x4000, 0x7fff>(addr)) {
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
}
if(within<0xa000, 0xa1ff>(addr)) {
if(ram_enable) return cartridge.ram_read(addr & 0x1ff);
return 0x00;
}
return 0x00;
}
void Cartridge::MBC2::mmio_write(uint16 addr, uint8 data) {
if(within<0x0000, 0x1fff>(addr)) {
if(!(addr & 0x0100)) ram_enable = (data & 0x0f) == 0x0a;
return;
}
if(within<0x2000, 0x3fff>(addr)) {
if( (addr & 0x0100)) rom_select = (data & 0x0f) + ((data & 0x0f) == 0);
return;
}
if(within<0xa000, 0xa1ff>(addr)) {
if(ram_enable) cartridge.ram_write(addr & 0x1ff, data & 0x0f);
return;
}
}
void Cartridge::MBC2::power() {
ram_enable = false;
rom_select = 0x01;
}
#endif
-8
View File
@@ -1,8 +0,0 @@
struct MBC2 : MMIO {
bool ram_enable; //0000-1fff
uint8 rom_select; //2000-3fff
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
void power();
} mbc2;
-120
View File
@@ -1,120 +0,0 @@
#ifdef CARTRIDGE_CPP
void Cartridge::MBC3::second() {
if(rtc_halt == false) {
if(++rtc_second >= 60) {
rtc_second = 0;
if(++rtc_minute >= 60) {
rtc_minute = 0;
if(++rtc_hour >= 24) {
rtc_hour = 0;
if(++rtc_day >= 512) {
rtc_day = 0;
rtc_day_carry = true;
}
}
}
}
}
}
uint8 Cartridge::MBC3::mmio_read(uint16 addr) {
if(within<0x0000, 0x3fff>(addr)) {
return cartridge.rom_read(addr);
}
if(within<0x4000, 0x7fff>(addr)) {
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) {
if(ram_select >= 0x00 && ram_select <= 0x03) {
return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
}
if(ram_select == 0x08) return rtc_latch_second;
if(ram_select == 0x09) return rtc_latch_minute;
if(ram_select == 0x0a) return rtc_latch_hour;
if(ram_select == 0x0b) return rtc_latch_day;
if(ram_select == 0x0c) return (rtc_latch_day_carry << 7) | (rtc_latch_day >> 8);
}
return 0x00;
}
return 0x00;
}
void Cartridge::MBC3::mmio_write(uint16 addr, uint8 data) {
if(within<0x0000, 0x1fff>(addr)) {
ram_enable = (data & 0x0f) == 0x0a;
return;
}
if(within<0x2000, 0x3fff>(addr)) {
rom_select = (data & 0x7f) + ((data & 0x7f) == 0);
return;
}
if(within<0x4000, 0x5fff>(addr)) {
ram_select = data;
return;
}
if(within<0x6000, 0x7fff>(addr)) {
if(rtc_latch == 0 && data == 1) {
rtc_latch_second = rtc_second;
rtc_latch_minute = rtc_minute;
rtc_latch_hour = rtc_hour;
rtc_latch_day = rtc_day;
rtc_latch_day_carry = rtc_day_carry;
}
rtc_latch = data;
return;
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) {
if(ram_select >= 0x00 && ram_select <= 0x03) {
cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
} else if(ram_select == 0x08) {
if(data >= 60) data = 0;
rtc_second = data;
} else if(ram_select == 0x09) {
if(data >= 60) data = 0;
rtc_minute = data;
} else if(ram_select == 0x0a) {
if(data >= 24) data = 0;
rtc_hour = data;
} else if(ram_select == 0x0b) {
rtc_day = (rtc_day & 0x0100) | data;
} else if(ram_select == 0x0c) {
rtc_day = ((data & 1) << 8) | (rtc_day & 0xff);
rtc_halt = data & 0x40;
rtc_day_carry = data & 0x80;
}
}
return;
}
}
void Cartridge::MBC3::power() {
ram_enable = false;
rom_select = 0x01;
ram_select = 0x00;
rtc_latch = 0;
rtc_halt = true;
rtc_second = 0;
rtc_minute = 0;
rtc_hour = 0;
rtc_day = 0;
rtc_day_carry = false;
rtc_latch_second = 0;
rtc_latch_minute = 0;
rtc_latch_hour = 0;
rtc_latch_day = 0;
rtc_latch_day_carry = false;
}
#endif
-24
View File
@@ -1,24 +0,0 @@
struct MBC3 : MMIO {
bool ram_enable; //0000-1fff
uint8 rom_select; //2000-3fff
uint8 ram_select; //4000-5fff
bool rtc_latch; //6000-7fff
bool rtc_halt;
unsigned rtc_second;
unsigned rtc_minute;
unsigned rtc_hour;
unsigned rtc_day;
bool rtc_day_carry;
unsigned rtc_latch_second;
unsigned rtc_latch_minute;
unsigned rtc_latch_hour;
unsigned rtc_latch_day;
unsigned rtc_latch_day_carry;
void second();
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
void power();
} mbc3;
-53
View File
@@ -1,53 +0,0 @@
#ifdef CARTRIDGE_CPP
uint8 Cartridge::MBC5::mmio_read(uint16 addr) {
if(within<0x0000, 0x3fff>(addr)) {
return cartridge.rom_read(addr);
}
if(within<0x4000, 0x7fff>(addr)) {
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
return 0x00;
}
return 0x00;
}
void Cartridge::MBC5::mmio_write(uint16 addr, uint8 data) {
if(within<0x0000, 0x1fff>(addr)) {
ram_enable = (data & 0x0f) == 0x0a;
return;
}
if(within<0x2000, 0x2fff>(addr)) {
rom_select = (rom_select & 0x0100) | data;
return;
}
if(within<0x3000, 0x3fff>(addr)) {
rom_select = ((data & 1) << 8) | (rom_select & 0x00ff);
return;
}
if(within<0x4000, 0x5fff>(addr)) {
ram_select = data & 0x0f;
return;
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
return;
}
}
void Cartridge::MBC5::power() {
ram_enable = false;
rom_select = 0x001;
ram_select = 0x00;
}
#endif
-9
View File
@@ -1,9 +0,0 @@
struct MBC5 : MMIO {
bool ram_enable; //0000-1fff
uint16 rom_select; //2000-2fff + 3000-3fff
uint8 ram_select; //4000-5fff
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
void power();
} mbc5;
-65
View File
@@ -1,65 +0,0 @@
#ifdef CARTRIDGE_CPP
uint8 Cartridge::MMM01::mmio_read(uint16 addr) {
if(within<0x0000, 0x7fff>(addr)) {
if(rom_mode == 0) return cartridge.rom_read(addr);
}
if(within<0x0000, 0x3fff>(addr)) {
return cartridge.rom_read(0x8000 + (rom_base << 14) + (addr & 0x3fff));
}
if(within<0x4000, 0x7fff>(addr)) {
return cartridge.rom_read(0x8000 + (rom_base << 14) + (rom_select << 14) + (addr & 0x3fff));
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) return cartridge.ram_read((ram_select << 13) + (addr & 0x1fff));
return 0x00;
}
return 0x00;
}
void Cartridge::MMM01::mmio_write(uint16 addr, uint8 data) {
if(within<0x0000, 0x1fff>(addr)) {
if(rom_mode == 0) {
rom_mode = 1;
} else {
ram_enable = (data & 0x0f) == 0x0a;
}
}
if(within<0x2000, 0x3fff>(addr)) {
if(rom_mode == 0) {
rom_base = data & 0x3f;
} else {
rom_select = data;
}
}
if(within<0x4000, 0x5fff>(addr)) {
if(rom_mode == 1) {
ram_select = data;
}
}
if(within<0x6000, 0x7fff>(addr)) {
//unknown purpose
}
if(within<0xa000, 0xbfff>(addr)) {
if(ram_enable) cartridge.ram_write((ram_select << 13) + (addr & 0x1fff), data);
}
}
void Cartridge::MMM01::power() {
rom_mode = 0;
rom_base = 0x00;
ram_enable = false;
rom_select = 0x01;
ram_select = 0x00;
}
#endif
-12
View File
@@ -1,12 +0,0 @@
struct MMM01 : MMIO {
bool rom_mode;
uint8 rom_base;
bool ram_enable;
uint8 rom_select;
uint8 ram_select;
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
void power();
} mmm01;
-52
View File
@@ -1,52 +0,0 @@
#ifdef CARTRIDGE_CPP
void Cartridge::serialize(serializer &s) {
if(info.battery) s.array(ramdata, ramsize);
s.integer(mbc1.ram_enable);
s.integer(mbc1.rom_select);
s.integer(mbc1.ram_select);
s.integer(mbc1.mode_select);
s.integer(mbc2.ram_enable);
s.integer(mbc2.rom_select);
s.integer(mbc3.ram_enable);
s.integer(mbc3.rom_select);
s.integer(mbc3.ram_select);
s.integer(mbc3.rtc_latch);
s.integer(mbc3.rtc_halt);
s.integer(mbc3.rtc_second);
s.integer(mbc3.rtc_minute);
s.integer(mbc3.rtc_hour);
s.integer(mbc3.rtc_day);
s.integer(mbc3.rtc_day_carry);
s.integer(mbc3.rtc_latch_second);
s.integer(mbc3.rtc_latch_minute);
s.integer(mbc3.rtc_latch_hour);
s.integer(mbc3.rtc_latch_day);
s.integer(mbc3.rtc_latch_day_carry);
s.integer(mbc5.ram_enable);
s.integer(mbc5.rom_select);
s.integer(mbc5.ram_select);
s.integer(mmm01.rom_mode);
s.integer(mmm01.rom_base);
s.integer(mmm01.ram_enable);
s.integer(mmm01.rom_select);
s.integer(mmm01.ram_select);
s.integer(huc1.ram_enable);
s.integer(huc1.rom_select);
s.integer(huc1.ram_select);
s.integer(huc3.ram_enable);
s.integer(huc3.rom_select);
s.integer(huc3.ram_select);
}
#endif
-674
View File
@@ -1,674 +0,0 @@
#ifdef CPU_CPP
#include "table.cpp"
#include "disassembler.cpp"
void CPU::op_xx() {
}
void CPU::op_cb() {
uint8 opcode = op_read(r[PC]++);
(this->*opcode_table_cb[opcode])();
}
//8-bit load commands
template<unsigned x, unsigned y> void CPU::op_ld_r_r() {
r[x] = r[y];
}
template<unsigned x> void CPU::op_ld_r_n() {
r[x] = op_read(r[PC]++);
}
template<unsigned x> void CPU::op_ld_r_hl() {
r[x] = op_read(r[HL]);
}
template<unsigned x> void CPU::op_ld_hl_r() {
op_write(r[HL], r[x]);
}
void CPU::op_ld_hl_n() {
op_write(r[HL], op_read(r[PC]++));
}
template<unsigned x> void CPU::op_ld_a_rr() {
r[A] = op_read(r[x]);
}
void CPU::op_ld_a_nn() {
uint8 lo = op_read(r[PC]++);
uint8 hi = op_read(r[PC]++);
r[A] = op_read((hi << 8) | (lo << 0));
}
template<unsigned x> void CPU::op_ld_rr_a() {
op_write(r[x], r[A]);
}
void CPU::op_ld_nn_a() {
uint8 lo = op_read(r[PC]++);
uint8 hi = op_read(r[PC]++);
op_write((hi << 8) | (lo << 0), r[A]);
}
void CPU::op_ld_a_ffn() {
r[A] = op_read(0xff00 + op_read(r[PC]++));
}
void CPU::op_ld_ffn_a() {
op_write(0xff00 + op_read(r[PC]++), r[A]);
}
void CPU::op_ld_a_ffc() {
r[A] = op_read(0xff00 + r[C]);
}
void CPU::op_ld_ffc_a() {
op_write(0xff00 + r[C], r[A]);
}
void CPU::op_ldi_hl_a() {
op_write(r[HL], r[A]);
r[HL]++;
}
void CPU::op_ldi_a_hl() {
r[A] = op_read(r[HL]);
r[HL]++;
}
void CPU::op_ldd_hl_a() {
op_write(r[HL], r[A]);
r[HL]--;
}
void CPU::op_ldd_a_hl() {
r[A] = op_read(r[HL]);
r[HL]--;
}
//16-bit load commands
template<unsigned x> void CPU::op_ld_rr_nn() {
r[x] = op_read(r[PC]++) << 0;
r[x] |= op_read(r[PC]++) << 8;
}
void CPU::op_ld_nn_sp() {
uint16 addr = op_read(r[PC]++) << 0;
addr |= op_read(r[PC]++) << 8;
op_write(addr + 0, r[SP] >> 0);
op_write(addr + 1, r[SP] >> 8);
}
void CPU::op_ld_sp_hl() {
r[SP] = r[HL];
op_io();
}
template<unsigned x> void CPU::op_push_rr() {
op_write(--r[SP], r[x] >> 8);
op_write(--r[SP], r[x] >> 0);
op_io();
}
template<unsigned x> void CPU::op_pop_rr() {
r[x] = op_read(r[SP]++) << 0;
r[x] |= op_read(r[SP]++) << 8;
}
//8-bit arithmetic commands
void CPU::opi_add_a(uint8 x) {
uint16 rh = r[A] + x;
uint16 rl = (r[A] & 0x0f) + (x & 0x0f);
r[A] = rh;
r.f.z = (uint8)rh == 0;
r.f.n = 0;
r.f.h = rl > 0x0f;
r.f.c = rh > 0xff;
}
template<unsigned x> void CPU::op_add_a_r() { opi_add_a(r[x]); }
void CPU::op_add_a_n() { opi_add_a(op_read(r[PC]++)); }
void CPU::op_add_a_hl() { opi_add_a(op_read(r[HL])); }
void CPU::opi_adc_a(uint8 x) {
uint16 rh = r[A] + x + r.f.c;
uint16 rl = (r[A] & 0x0f) + (x & 0x0f) + r.f.c;
r[A] = rh;
r.f.z = (uint8)rh == 0;
r.f.n = 0;
r.f.h = rl > 0x0f;
r.f.c = rh > 0xff;
}
template<unsigned x> void CPU::op_adc_a_r() { opi_adc_a(r[x]); }
void CPU::op_adc_a_n() { opi_adc_a(op_read(r[PC]++)); }
void CPU::op_adc_a_hl() { opi_adc_a(op_read(r[HL])); }
void CPU::opi_sub_a(uint8 x) {
uint16 rh = r[A] - x;
uint16 rl = (r[A] & 0x0f) - (x & 0x0f);
r[A] = rh;
r.f.z = (uint8)rh == 0;
r.f.n = 1;
r.f.h = rl > 0x0f;
r.f.c = rh > 0xff;
}
template<unsigned x> void CPU::op_sub_a_r() { opi_sub_a(r[x]); }
void CPU::op_sub_a_n() { opi_sub_a(op_read(r[PC]++)); }
void CPU::op_sub_a_hl() { opi_sub_a(op_read(r[HL])); }
void CPU::opi_sbc_a(uint8 x) {
uint16 rh = r[A] - x - r.f.c;
uint16 rl = (r[A] & 0x0f) - (x & 0x0f) - r.f.c;
r[A] = rh;
r.f.z = (uint8)rh == 0;
r.f.n = 1;
r.f.h = rl > 0x0f;
r.f.c = rh > 0xff;
}
template<unsigned x> void CPU::op_sbc_a_r() { opi_sbc_a(r[x]); }
void CPU::op_sbc_a_n() { opi_sbc_a(op_read(r[PC]++)); }
void CPU::op_sbc_a_hl() { opi_sbc_a(op_read(r[HL])); }
void CPU::opi_and_a(uint8 x) {
r[A] &= x;
r.f.z = r[A] == 0;
r.f.n = 0;
r.f.h = 1;
r.f.c = 0;
}
template<unsigned x> void CPU::op_and_a_r() { opi_and_a(r[x]); }
void CPU::op_and_a_n() { opi_and_a(op_read(r[PC]++)); }
void CPU::op_and_a_hl() { opi_and_a(op_read(r[HL])); }
void CPU::opi_xor_a(uint8 x) {
r[A] ^= x;
r.f.z = r[A] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = 0;
}
template<unsigned x> void CPU::op_xor_a_r() { opi_xor_a(r[x]); }
void CPU::op_xor_a_n() { opi_xor_a(op_read(r[PC]++)); }
void CPU::op_xor_a_hl() { opi_xor_a(op_read(r[HL])); }
void CPU::opi_or_a(uint8 x) {
r[A] |= x;
r.f.z = r[A] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = 0;
}
template<unsigned x> void CPU::op_or_a_r() { opi_or_a(r[x]); }
void CPU::op_or_a_n() { opi_or_a(op_read(r[PC]++)); }
void CPU::op_or_a_hl() { opi_or_a(op_read(r[HL])); }
void CPU::opi_cp_a(uint8 x) {
uint16 rh = r[A] - x;
uint16 rl = (r[A] & 0x0f) - (x & 0x0f);
r.f.z = (uint8)rh == 0;
r.f.n = 1;
r.f.h = rl > 0x0f;
r.f.c = rh > 0xff;
}
template<unsigned x> void CPU::op_cp_a_r() { opi_cp_a(r[x]); }
void CPU::op_cp_a_n() { opi_cp_a(op_read(r[PC]++)); }
void CPU::op_cp_a_hl() { opi_cp_a(op_read(r[HL])); }
template<unsigned x> void CPU::op_inc_r() {
r[x]++;
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = (r[x] & 0x0f) == 0x00;
}
void CPU::op_inc_hl() {
uint8 n = op_read(r[HL]);
op_write(r[HL], ++n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = (n & 0x0f) == 0x00;
}
template<unsigned x> void CPU::op_dec_r() {
r[x]--;
r.f.z = r[x] == 0;
r.f.n = 1;
r.f.h = (r[x] & 0x0f) == 0x0f;
}
void CPU::op_dec_hl() {
uint8 n = op_read(r[HL]);
op_write(r[HL], --n);
r.f.z = n == 0;
r.f.n = 1;
r.f.h = (n & 0x0f) == 0x0f;
}
void CPU::op_daa() {
uint16 a = r[A];
if(r.f.n == 0) {
if(r.f.h || (a & 0x0f) > 0x09) a += 0x06;
if(r.f.c || (a ) > 0x9f) a += 0x60;
} else {
if(r.f.h) {
a -= 0x06;
if(r.f.c == 0) a &= 0xff;
}
if(r.f.c) a -= 0x60;
}
r[A] = a;
r.f.z = r[A] == 0;
r.f.h = 0;
r.f.c |= a & 0x100;
}
void CPU::op_cpl() {
r[A] ^= 0xff;
r.f.n = 1;
r.f.h = 1;
}
//16-bit arithmetic commands
template<unsigned x> void CPU::op_add_hl_rr() {
op_io();
uint32 rb = (r[HL] + r[x]);
uint32 rn = (r[HL] & 0xfff) + (r[x] & 0xfff);
r[HL] = rb;
r.f.n = 0;
r.f.h = rn > 0x0fff;
r.f.c = rb > 0xffff;
}
template<unsigned x> void CPU::op_inc_rr() {
op_io();
r[x]++;
}
template<unsigned x> void CPU::op_dec_rr() {
op_io();
r[x]--;
}
void CPU::op_add_sp_n() {
op_io();
op_io();
signed n = (int8)op_read(r[PC]++);
r.f.z = 0;
r.f.n = 0;
r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f;
r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff;
r[SP] += n;
}
void CPU::op_ld_hl_sp_n() {
op_io();
signed n = (int8)op_read(r[PC]++);
r.f.z = 0;
r.f.n = 0;
r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f;
r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff;
r[HL] = r[SP] + n;
}
//rotate/shift commands
void CPU::op_rlca() {
r[A] = (r[A] << 1) | (r[A] >> 7);
r.f.z = 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = r[A] & 0x01;
}
void CPU::op_rla() {
bool c = r[A] & 0x80;
r[A] = (r[A] << 1) | (r.f.c << 0);
r.f.z = 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
void CPU::op_rrca() {
r[A] = (r[A] >> 1) | (r[A] << 7);
r.f.z = 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = r[A] & 0x80;
}
void CPU::op_rra() {
bool c = r[A] & 0x01;
r[A] = (r[A] >> 1) | (r.f.c << 7);
r.f.z = 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
template<unsigned x> void CPU::op_rlc_r() {
r[x] = (r[x] << 1) | (r[x] >> 7);
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = r[x] & 0x01;
}
void CPU::op_rlc_hl() {
uint8 n = op_read(r[HL]);
n = (n << 1) | (n >> 7);
op_write(r[HL], n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = n & 0x01;
}
template<unsigned x> void CPU::op_rl_r() {
bool c = r[x] & 0x80;
r[x] = (r[x] << 1) | (r.f.c << 0);
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
void CPU::op_rl_hl() {
uint8 n = op_read(r[HL]);
bool c = n & 0x80;
n = (n << 1) | (r.f.c << 0);
op_write(r[HL], n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
template<unsigned x> void CPU::op_rrc_r() {
r[x] = (r[x] >> 1) | (r[x] << 7);
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = r[x] & 0x80;
}
void CPU::op_rrc_hl() {
uint8 n = op_read(r[HL]);
n = (n >> 1) | (n << 7);
op_write(r[HL], n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = n & 0x80;
}
template<unsigned x> void CPU::op_rr_r() {
bool c = r[x] & 0x01;
r[x] = (r[x] >> 1) | (r.f.c << 7);
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
void CPU::op_rr_hl() {
uint8 n = op_read(r[HL]);
bool c = n & 0x01;
n = (n >> 1) | (r.f.c << 7);
op_write(r[HL], n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
template<unsigned x> void CPU::op_sla_r() {
bool c = r[x] & 0x80;
r[x] <<= 1;
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
void CPU::op_sla_hl() {
uint8 n = op_read(r[HL]);
bool c = n & 0x80;
n <<= 1;
op_write(r[HL], n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
template<unsigned x> void CPU::op_swap_r() {
r[x] = (r[x] << 4) | (r[x] >> 4);
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = 0;
}
void CPU::op_swap_hl() {
uint8 n = op_read(r[HL]);
n = (n << 4) | (n >> 4);
op_write(r[HL], n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = 0;
}
template<unsigned x> void CPU::op_sra_r() {
bool c = r[x] & 0x01;
r[x] = (int8)r[x] >> 1;
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
void CPU::op_sra_hl() {
uint8 n = op_read(r[HL]);
bool c = n & 0x01;
n = (int8)n >> 1;
op_write(r[HL], n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
template<unsigned x> void CPU::op_srl_r() {
bool c = r[x] & 0x01;
r[x] >>= 1;
r.f.z = r[x] == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
void CPU::op_srl_hl() {
uint8 n = op_read(r[HL]);
bool c = n & 0x01;
n >>= 1;
op_write(r[HL], n);
r.f.z = n == 0;
r.f.n = 0;
r.f.h = 0;
r.f.c = c;
}
//single-bit commands
template<unsigned b, unsigned x> void CPU::op_bit_n_r() {
r.f.z = (r[x] & (1 << b)) == 0;
r.f.n = 0;
r.f.h = 1;
}
template<unsigned b> void CPU::op_bit_n_hl() {
uint8 n = op_read(r[HL]);
r.f.z = (n & (1 << b)) == 0;
r.f.n = 0;
r.f.h = 1;
}
template<unsigned b, unsigned x> void CPU::op_set_n_r() {
r[x] |= 1 << b;
}
template<unsigned b> void CPU::op_set_n_hl() {
uint8 n = op_read(r[HL]);
n |= 1 << b;
op_write(r[HL], n);
}
template<unsigned b, unsigned x> void CPU::op_res_n_r() {
r[x] &= ~(1 << b);
}
template<unsigned b> void CPU::op_res_n_hl() {
uint8 n = op_read(r[HL]);
n &= ~(1 << b);
op_write(r[HL], n);
}
//control commands
void CPU::op_ccf() {
r.f.n = 0;
r.f.h = 0;
r.f.c = !r.f.c;
}
void CPU::op_scf() {
r.f.n = 0;
r.f.h = 0;
r.f.c = 1;
}
void CPU::op_nop() {
}
void CPU::op_halt() {
status.halt = true;
while(status.halt == true) op_io();
}
void CPU::op_stop() {
status.stop = true;
while(status.stop == true) op_io();
}
void CPU::op_di() {
status.ime = 0;
}
void CPU::op_ei() {
status.ime = 1;
}
//jump commands
void CPU::op_jp_nn() {
uint8 lo = op_read(r[PC]++);
uint8 hi = op_read(r[PC]++);
r[PC] = (hi << 8) | (lo << 0);
op_io();
}
void CPU::op_jp_hl() {
r[PC] = r[HL];
}
template<unsigned x, bool y> void CPU::op_jp_f_nn() {
uint8 lo = op_read(r[PC]++);
uint8 hi = op_read(r[PC]++);
if(r.f[x] == y) {
r[PC] = (hi << 8) | (lo << 0);
op_io();
}
}
void CPU::op_jr_n() {
int8 n = op_read(r[PC]++);
r[PC] += n;
op_io();
}
template<unsigned x, bool y> void CPU::op_jr_f_n() {
int8 n = op_read(r[PC]++);
if(r.f[x] == y) {
r[PC] += n;
op_io();
}
}
void CPU::op_call_nn() {
uint8 lo = op_read(r[PC]++);
uint8 hi = op_read(r[PC]++);
op_write(--r[SP], r[PC] >> 8);
op_write(--r[SP], r[PC] >> 0);
r[PC] = (hi << 8) | (lo << 0);
op_io();
}
template<unsigned x, bool y> void CPU::op_call_f_nn() {
uint8 lo = op_read(r[PC]++);
uint8 hi = op_read(r[PC]++);
if(r.f[x] == y) {
op_write(--r[SP], r[PC] >> 8);
op_write(--r[SP], r[PC] >> 0);
r[PC] = (hi << 8) | (lo << 0);
op_io();
}
}
void CPU::op_ret() {
uint8 lo = op_read(r[SP]++);
uint8 hi = op_read(r[SP]++);
r[PC] = (hi << 8) | (lo << 0);
op_io();
}
template<unsigned x, bool y> void CPU::op_ret_f() {
op_io();
if(r.f[x] == y) {
uint8 lo = op_read(r[SP]++);
uint8 hi = op_read(r[SP]++);
r[PC] = (hi << 8) | (lo << 0);
op_io();
}
}
void CPU::op_reti() {
uint8 lo = op_read(r[SP]++);
uint8 hi = op_read(r[SP]++);
r[PC] = (hi << 8) | (lo << 0);
op_io();
status.ime = 1;
}
template<unsigned n> void CPU::op_rst_n() {
op_write(--r[SP], r[PC] >> 8);
op_write(--r[SP], r[PC] >> 0);
r[PC] = n;
op_io();
}
#endif
-145
View File
@@ -1,145 +0,0 @@
#include "registers.hpp"
void (CPU::*opcode_table[256])();
void (CPU::*opcode_table_cb[256])();
void initialize_opcode_table();
void op_xx();
void op_cb();
//8-bit load commands
template<unsigned x, unsigned y> void op_ld_r_r();
template<unsigned x> void op_ld_r_n();
template<unsigned x> void op_ld_r_hl();
template<unsigned x> void op_ld_hl_r();
void op_ld_hl_n();
template<unsigned x> void op_ld_a_rr();
void op_ld_a_nn();
template<unsigned x> void op_ld_rr_a();
void op_ld_nn_a();
void op_ld_a_ffn();
void op_ld_ffn_a();
void op_ld_a_ffc();
void op_ld_ffc_a();
void op_ldi_hl_a();
void op_ldi_a_hl();
void op_ldd_hl_a();
void op_ldd_a_hl();
//16-bit load commands
template<unsigned x> void op_ld_rr_nn();
void op_ld_nn_sp();
void op_ld_sp_hl();
template<unsigned x> void op_push_rr();
template<unsigned x> void op_pop_rr();
//8-bit arithmetic commands
void opi_add_a(uint8 x);
template<unsigned x> void op_add_a_r();
void op_add_a_n();
void op_add_a_hl();
void opi_adc_a(uint8 x);
template<unsigned x> void op_adc_a_r();
void op_adc_a_n();
void op_adc_a_hl();
void opi_sub_a(uint8 x);
template<unsigned x> void op_sub_a_r();
void op_sub_a_n();
void op_sub_a_hl();
void opi_sbc_a(uint8 x);
template<unsigned x> void op_sbc_a_r();
void op_sbc_a_n();
void op_sbc_a_hl();
void opi_and_a(uint8 x);
template<unsigned x> void op_and_a_r();
void op_and_a_n();
void op_and_a_hl();
void opi_xor_a(uint8 x);
template<unsigned x> void op_xor_a_r();
void op_xor_a_n();
void op_xor_a_hl();
void opi_or_a(uint8 x);
template<unsigned x> void op_or_a_r();
void op_or_a_n();
void op_or_a_hl();
void opi_cp_a(uint8 x);
template<unsigned x> void op_cp_a_r();
void op_cp_a_n();
void op_cp_a_hl();
template<unsigned x> void op_inc_r();
void op_inc_hl();
template<unsigned x> void op_dec_r();
void op_dec_hl();
void op_daa();
void op_cpl();
//16-bit arithmetic commands
template<unsigned x> void op_add_hl_rr();
template<unsigned x> void op_inc_rr();
template<unsigned x> void op_dec_rr();
void op_add_sp_n();
void op_ld_hl_sp_n();
//rotate/shift commands
void op_rlca();
void op_rla();
void op_rrca();
void op_rra();
template<unsigned x> void op_rlc_r();
void op_rlc_hl();
template<unsigned x> void op_rl_r();
void op_rl_hl();
template<unsigned x> void op_rrc_r();
void op_rrc_hl();
template<unsigned x> void op_rr_r();
void op_rr_hl();
template<unsigned x> void op_sla_r();
void op_sla_hl();
template<unsigned x> void op_swap_r();
void op_swap_hl();
template<unsigned x> void op_sra_r();
void op_sra_hl();
template<unsigned x> void op_srl_r();
void op_srl_hl();
//single-bit commands
template<unsigned b, unsigned x> void op_bit_n_r();
template<unsigned b> void op_bit_n_hl();
template<unsigned b, unsigned x> void op_set_n_r();
template<unsigned b> void op_set_n_hl();
template<unsigned b, unsigned x> void op_res_n_r();
template<unsigned b> void op_res_n_hl();
//control commands
void op_ccf();
void op_scf();
void op_nop();
void op_halt();
void op_stop();
void op_di();
void op_ei();
//jump commands
void op_jp_nn();
void op_jp_hl();
template<unsigned x, bool y> void op_jp_f_nn();
void op_jr_n();
template<unsigned x, bool y> void op_jr_f_n();
void op_call_nn();
template<unsigned x, bool y> void op_call_f_nn();
void op_ret();
template<unsigned x, bool y> void op_ret_f();
void op_reti();
template<unsigned n> void op_rst_n();
//disassembler.cpp
string disassemble(uint16 pc);
string disassemble_opcode(uint16 pc);
string disassemble_opcode_cb(uint16 pc);
-560
View File
@@ -1,560 +0,0 @@
#ifdef CPU_CPP
string CPU::disassemble(uint16 pc) {
char output[80];
memset(output, ' ', sizeof output);
output[79] = 0;
string opcode = disassemble_opcode(pc);
string registers = {
" AF:", hex<4>(r[AF]),
" BC:", hex<4>(r[BC]),
" DE:", hex<4>(r[DE]),
" HL:", hex<4>(r[HL]),
" SP:", hex<4>(r[SP])
};
memcpy(output + 0, hex<4>(pc), 4);
memcpy(output + 6, opcode, opcode.length());
memcpy(output + 23, registers, registers.length());
output[63] = 0;
return output;
}
string CPU::disassemble_opcode(uint16 pc) {
uint8 opcode = bus.read(pc);
uint8 p0 = bus.read(pc + 1);
uint8 p1 = bus.read(pc + 2);
uint8 p2 = bus.read(pc + 3);
switch(opcode) {
case 0x00: return { "nop" };
case 0x01: return { "ld bc,$", hex<2>(p1), hex<2>(p0) };
case 0x02: return { "ld (bc),a" };
case 0x03: return { "inc bc" };
case 0x04: return { "inc b" };
case 0x05: return { "dec b" };
case 0x06: return { "ld b,$", hex<2>(p0) };
case 0x07: return { "rlc a" };
case 0x08: return { "ld ($", hex<2>(p1), hex<2>(p0), "),sp" };
case 0x09: return { "add hl,bc" };
case 0x0a: return { "ld a,(bc)" };
case 0x0b: return { "dec bc" };
case 0x0c: return { "inc c" };
case 0x0d: return { "dec c" };
case 0x0e: return { "ld c,$", hex<2>(p0) };
case 0x0f: return { "rrc a" };
case 0x10: return { "stop" };
case 0x11: return { "ld de,$", hex<2>(p1), hex<2>(p0) };
case 0x12: return { "ld (de),a" };
case 0x13: return { "inc de" };
case 0x14: return { "inc d" };
case 0x15: return { "dec d" };
case 0x16: return { "ld d,$", hex<2>(p0) };
case 0x17: return { "rl a" };
case 0x18: return { "jr $", hex<4>(r[PC] + 2 + (int8)p0) };
case 0x19: return { "add hl,de" };
case 0x1a: return { "ld a,(de)" };
case 0x1b: return { "dec de" };
case 0x1c: return { "inc e" };
case 0x1d: return { "dec e" };
case 0x1e: return { "ld e,$", hex<2>(p0) };
case 0x1f: return { "rr a" };
case 0x20: return { "jr nz,$", hex<4>(r[PC] + 2 + (int8)p0) };
case 0x21: return { "ld hl,$", hex<2>(p1), hex<2>(p0) };
case 0x22: return { "ldi (hl),a" };
case 0x23: return { "inc hl" };
case 0x24: return { "inc h" };
case 0x25: return { "dec h" };
case 0x26: return { "ld h,$", hex<2>(p0) };
case 0x27: return { "daa" };
case 0x28: return { "jr z,$", hex<4>(r[PC] + 2 + (int8)p0) };
case 0x29: return { "add hl,hl" };
case 0x2a: return { "ldi a,(hl)" };
case 0x2b: return { "dec hl" };
case 0x2c: return { "inc l" };
case 0x2d: return { "dec l" };
case 0x2e: return { "ld l,$", hex<2>(p0) };
case 0x2f: return { "cpl" };
case 0x30: return { "jr nc,$", hex<4>(r[PC] + 2 + (int8)p0) };
case 0x31: return { "ld sp,$", hex<2>(p1), hex<2>(p0) };
case 0x32: return { "ldd (hl),a" };
case 0x33: return { "inc sp" };
case 0x34: return { "inc (hl)" };
case 0x35: return { "dec (hl)" };
case 0x36: return { "ld (hl),$", hex<2>(p0) };
case 0x37: return { "scf" };
case 0x38: return { "jr c,$", hex<4>(r[PC] + 2 + (int8)p0) };
case 0x39: return { "add hl,sp" };
case 0x3a: return { "ldd a,(hl)" };
case 0x3b: return { "dec sp" };
case 0x3c: return { "inc a" };
case 0x3d: return { "dec a" };
case 0x3e: return { "ld a,$", hex<2>(p0) };
case 0x3f: return { "ccf" };
case 0x40: return { "ld b,b" };
case 0x41: return { "ld b,c" };
case 0x42: return { "ld b,d" };
case 0x43: return { "ld b,e" };
case 0x44: return { "ld b,h" };
case 0x45: return { "ld b,l" };
case 0x46: return { "ld b,(hl)" };
case 0x47: return { "ld b,a" };
case 0x48: return { "ld c,b" };
case 0x49: return { "ld c,c" };
case 0x4a: return { "ld c,d" };
case 0x4b: return { "ld c,e" };
case 0x4c: return { "ld c,h" };
case 0x4d: return { "ld c,l" };
case 0x4e: return { "ld c,(hl)" };
case 0x4f: return { "ld c,a" };
case 0x50: return { "ld d,b" };
case 0x51: return { "ld d,c" };
case 0x52: return { "ld d,d" };
case 0x53: return { "ld d,e" };
case 0x54: return { "ld d,h" };
case 0x55: return { "ld d,l" };
case 0x56: return { "ld d,(hl)" };
case 0x57: return { "ld d,a" };
case 0x58: return { "ld e,b" };
case 0x59: return { "ld e,c" };
case 0x5a: return { "ld e,d" };
case 0x5b: return { "ld e,e" };
case 0x5c: return { "ld e,h" };
case 0x5d: return { "ld e,l" };
case 0x5e: return { "ld e,(hl)" };
case 0x5f: return { "ld e,a" };
case 0x60: return { "ld h,b" };
case 0x61: return { "ld h,c" };
case 0x62: return { "ld h,d" };
case 0x63: return { "ld h,e" };
case 0x64: return { "ld h,h" };
case 0x65: return { "ld h,l" };
case 0x66: return { "ld h,(hl)" };
case 0x67: return { "ld h,a" };
case 0x68: return { "ld l,b" };
case 0x69: return { "ld l,c" };
case 0x6a: return { "ld l,d" };
case 0x6b: return { "ld l,e" };
case 0x6c: return { "ld l,h" };
case 0x6d: return { "ld l,l" };
case 0x6e: return { "ld l,(hl)" };
case 0x6f: return { "ld l,a" };
case 0x70: return { "ld (hl),b" };
case 0x71: return { "ld (hl),c" };
case 0x72: return { "ld (hl),d" };
case 0x73: return { "ld (hl),e" };
case 0x74: return { "ld (hl),h" };
case 0x75: return { "ld (hl),l" };
case 0x76: return { "halt" };
case 0x77: return { "ld (hl),a" };
case 0x78: return { "ld a,b" };
case 0x79: return { "ld a,c" };
case 0x7a: return { "ld a,d" };
case 0x7b: return { "ld a,e" };
case 0x7c: return { "ld a,h" };
case 0x7d: return { "ld a,l" };
case 0x7e: return { "ld a,(hl)" };
case 0x7f: return { "ld a,a" };
case 0x80: return { "add a,b" };
case 0x81: return { "add a,c" };
case 0x82: return { "add a,d" };
case 0x83: return { "add a,e" };
case 0x84: return { "add a,h" };
case 0x85: return { "add a,l" };
case 0x86: return { "add a,(hl)" };
case 0x87: return { "add a,a" };
case 0x88: return { "adc a,b" };
case 0x89: return { "adc a,c" };
case 0x8a: return { "adc a,d" };
case 0x8b: return { "adc a,e" };
case 0x8c: return { "adc a,h" };
case 0x8d: return { "adc a,l" };
case 0x8e: return { "adc a,(hl)" };
case 0x8f: return { "adc a,a" };
case 0x90: return { "sub a,b" };
case 0x91: return { "sub a,c" };
case 0x92: return { "sub a,d" };
case 0x93: return { "sub a,e" };
case 0x94: return { "sub a,h" };
case 0x95: return { "sub a,l" };
case 0x96: return { "sub a,(hl)" };
case 0x97: return { "sub a,a" };
case 0x98: return { "sbc a,b" };
case 0x99: return { "sbc a,c" };
case 0x9a: return { "sbc a,d" };
case 0x9b: return { "sbc a,e" };
case 0x9c: return { "sbc a,h" };
case 0x9d: return { "sbc a,l" };
case 0x9e: return { "sbc a,(hl)" };
case 0x9f: return { "sbc a,a" };
case 0xa0: return { "and a,b" };
case 0xa1: return { "and a,c" };
case 0xa2: return { "and a,d" };
case 0xa3: return { "and a,e" };
case 0xa4: return { "and a,h" };
case 0xa5: return { "and a,l" };
case 0xa6: return { "and a,(hl)" };
case 0xa7: return { "and a,a" };
case 0xa8: return { "xor a,b" };
case 0xa9: return { "xor a,c" };
case 0xaa: return { "xor a,d" };
case 0xab: return { "xor a,e" };
case 0xac: return { "xor a,h" };
case 0xad: return { "xor a,l" };
case 0xae: return { "xor a,(hl)" };
case 0xaf: return { "xor a,a" };
case 0xb0: return { "or a,b" };
case 0xb1: return { "or a,c" };
case 0xb2: return { "or a,d" };
case 0xb3: return { "or a,e" };
case 0xb4: return { "or a,h" };
case 0xb5: return { "or a,l" };
case 0xb6: return { "or a,(hl)" };
case 0xb7: return { "or a,a" };
case 0xb8: return { "cp a,b" };
case 0xb9: return { "cp a,c" };
case 0xba: return { "cp a,d" };
case 0xbb: return { "cp a,e" };
case 0xbc: return { "cp a,h" };
case 0xbd: return { "cp a,l" };
case 0xbe: return { "cp a,(hl)" };
case 0xbf: return { "cp a,a" };
case 0xc0: return { "ret nz" };
case 0xc1: return { "pop bc" };
case 0xc2: return { "jp nz,$", hex<2>(p1), hex<2>(p0) };
case 0xc3: return { "jp $", hex<2>(p1), hex<2>(p0) };
case 0xc4: return { "call nz,$", hex<2>(p1), hex<2>(p0) };
case 0xc5: return { "push bc" };
case 0xc6: return { "add a,$", hex<2>(p0) };
case 0xc7: return { "rst $0000" };
case 0xc8: return { "ret z" };
case 0xc9: return { "ret" };
case 0xca: return { "jp z,$", hex<2>(p1), hex<2>(p0) };
case 0xcb: return disassemble_opcode_cb(pc + 1);
case 0xcc: return { "call z,$", hex<2>(p1), hex<2>(p0) };
case 0xcd: return { "call $", hex<2>(p1), hex<2>(p0) };
case 0xce: return { "adc a,$", hex<2>(p0) };
case 0xcf: return { "rst $0008" };
case 0xd0: return { "ret nc" };
case 0xd1: return { "pop de" };
case 0xd2: return { "jp nc,$", hex<2>(p1), hex<2>(p0) };
case 0xd3: return { "xx" };
case 0xd4: return { "call nc,$", hex<2>(p1), hex<2>(p0) };
case 0xd5: return { "push de" };
case 0xd6: return { "sub a,$", hex<2>(p0) };
case 0xd7: return { "rst $0010" };
case 0xd8: return { "ret c" };
case 0xd9: return { "reti" };
case 0xda: return { "jp c,$", hex<2>(p1), hex<2>(p0) };
case 0xdb: return { "xx" };
case 0xdc: return { "call c,$", hex<2>(p1), hex<2>(p0) };
case 0xdd: return { "xx" };
case 0xde: return { "sbc a,$", hex<2>(p0) };
case 0xdf: return { "rst $0018" };
case 0xe0: return { "ld ($ff", hex<2>(p0), "),a" };
case 0xe1: return { "pop hl" };
case 0xe2: return { "ld ($ff00+c),a" };
case 0xe3: return { "xx" };
case 0xe4: return { "xx" };
case 0xe5: return { "push hl" };
case 0xe6: return { "and a,$", hex<2>(p0) };
case 0xe7: return { "rst $0020" };
case 0xe8: return { "add sp,$", hex<4>((int8)p0) };
case 0xe9: return { "jp hl" };
case 0xea: return { "ld ($", hex<2>(p1), hex<2>(p0), "),a" };
case 0xeb: return { "xx" };
case 0xec: return { "xx" };
case 0xed: return { "xx" };
case 0xee: return { "xor a,$", hex<2>(p0) };
case 0xef: return { "rst $0028" };
case 0xf0: return { "ld a,($ff", hex<2>(p0), ")" };
case 0xf1: return { "pop af" };
case 0xf2: return { "ld a,($ff00+c)" };
case 0xf3: return { "di" };
case 0xf4: return { "xx" };
case 0xf5: return { "push af" };
case 0xf6: return { "or a,$", hex<2>(p0) };
case 0xf7: return { "rst $0030" };
case 0xf8: return { "ld hl,sp+$", hex<4>((int8)p0) };
case 0xf9: return { "ld sp,hl" };
case 0xfa: return { "ld a,($", hex<2>(p1), hex<2>(p0), ")" };
case 0xfb: return { "ei" };
case 0xfc: return { "xx" };
case 0xfd: return { "xx" };
case 0xfe: return { "cp a,$", hex<2>(p0) };
case 0xff: return { "rst $0038" };
}
return "";
}
string CPU::disassemble_opcode_cb(uint16 pc) {
uint8 opcode = bus.read(pc);
uint8 p0 = bus.read(pc + 1);
uint8 p1 = bus.read(pc + 2);
uint8 p2 = bus.read(pc + 3);
switch(opcode) {
case 0x00: return { "rlc b" };
case 0x01: return { "rlc c" };
case 0x02: return { "rlc d" };
case 0x03: return { "rlc e" };
case 0x04: return { "rlc h" };
case 0x05: return { "rlc l" };
case 0x06: return { "rlc (hl)" };
case 0x07: return { "rlc a" };
case 0x08: return { "rrc b" };
case 0x09: return { "rrc c" };
case 0x0a: return { "rrc d" };
case 0x0b: return { "rrc e" };
case 0x0c: return { "rrc h" };
case 0x0d: return { "rrc l" };
case 0x0e: return { "rrc (hl)" };
case 0x0f: return { "rrc a" };
case 0x10: return { "rl b" };
case 0x11: return { "rl c" };
case 0x12: return { "rl d" };
case 0x13: return { "rl e" };
case 0x14: return { "rl h" };
case 0x15: return { "rl l" };
case 0x16: return { "rl (hl)" };
case 0x17: return { "rl a" };
case 0x18: return { "rr b" };
case 0x19: return { "rr c" };
case 0x1a: return { "rr d" };
case 0x1b: return { "rr e" };
case 0x1c: return { "rr h" };
case 0x1d: return { "rr l" };
case 0x1e: return { "rr (hl)" };
case 0x1f: return { "rr a" };
case 0x20: return { "sla b" };
case 0x21: return { "sla c" };
case 0x22: return { "sla d" };
case 0x23: return { "sla e" };
case 0x24: return { "sla h" };
case 0x25: return { "sla l" };
case 0x26: return { "sla (hl)" };
case 0x27: return { "sla a" };
case 0x28: return { "sra b" };
case 0x29: return { "sra c" };
case 0x2a: return { "sra d" };
case 0x2b: return { "sra e" };
case 0x2c: return { "sra h" };
case 0x2d: return { "sra l" };
case 0x2e: return { "sra (hl)" };
case 0x2f: return { "sra a" };
case 0x30: return { "swap b" };
case 0x31: return { "swap c" };
case 0x32: return { "swap d" };
case 0x33: return { "swap e" };
case 0x34: return { "swap h" };
case 0x35: return { "swap l" };
case 0x36: return { "swap (hl)" };
case 0x37: return { "swap a" };
case 0x38: return { "srl b" };
case 0x39: return { "srl c" };
case 0x3a: return { "srl d" };
case 0x3b: return { "srl e" };
case 0x3c: return { "srl h" };
case 0x3d: return { "srl l" };
case 0x3e: return { "srl (hl)" };
case 0x3f: return { "srl a" };
case 0x40: return { "bit 0,b" };
case 0x41: return { "bit 0,c" };
case 0x42: return { "bit 0,d" };
case 0x43: return { "bit 0,e" };
case 0x44: return { "bit 0,h" };
case 0x45: return { "bit 0,l" };
case 0x46: return { "bit 0,(hl)" };
case 0x47: return { "bit 0,a" };
case 0x48: return { "bit 1,b" };
case 0x49: return { "bit 1,c" };
case 0x4a: return { "bit 1,d" };
case 0x4b: return { "bit 1,e" };
case 0x4c: return { "bit 1,h" };
case 0x4d: return { "bit 1,l" };
case 0x4e: return { "bit 1,(hl)" };
case 0x4f: return { "bit 1,a" };
case 0x50: return { "bit 2,b" };
case 0x51: return { "bit 2,c" };
case 0x52: return { "bit 2,d" };
case 0x53: return { "bit 2,e" };
case 0x54: return { "bit 2,h" };
case 0x55: return { "bit 2,l" };
case 0x56: return { "bit 2,(hl)" };
case 0x57: return { "bit 2,a" };
case 0x58: return { "bit 3,b" };
case 0x59: return { "bit 3,c" };
case 0x5a: return { "bit 3,d" };
case 0x5b: return { "bit 3,e" };
case 0x5c: return { "bit 3,h" };
case 0x5d: return { "bit 3,l" };
case 0x5e: return { "bit 3,(hl)" };
case 0x5f: return { "bit 3,a" };
case 0x60: return { "bit 4,b" };
case 0x61: return { "bit 4,c" };
case 0x62: return { "bit 4,d" };
case 0x63: return { "bit 4,e" };
case 0x64: return { "bit 4,h" };
case 0x65: return { "bit 4,l" };
case 0x66: return { "bit 4,(hl)" };
case 0x67: return { "bit 4,a" };
case 0x68: return { "bit 5,b" };
case 0x69: return { "bit 5,c" };
case 0x6a: return { "bit 5,d" };
case 0x6b: return { "bit 5,e" };
case 0x6c: return { "bit 5,h" };
case 0x6d: return { "bit 5,l" };
case 0x6e: return { "bit 5,(hl)" };
case 0x6f: return { "bit 5,a" };
case 0x70: return { "bit 6,b" };
case 0x71: return { "bit 6,c" };
case 0x72: return { "bit 6,d" };
case 0x73: return { "bit 6,e" };
case 0x74: return { "bit 6,h" };
case 0x75: return { "bit 6,l" };
case 0x76: return { "bit 6,(hl)" };
case 0x77: return { "bit 6,a" };
case 0x78: return { "bit 7,b" };
case 0x79: return { "bit 7,c" };
case 0x7a: return { "bit 7,d" };
case 0x7b: return { "bit 7,e" };
case 0x7c: return { "bit 7,h" };
case 0x7d: return { "bit 7,l" };
case 0x7e: return { "bit 7,(hl)" };
case 0x7f: return { "bit 7,a" };
case 0x80: return { "res 0,b" };
case 0x81: return { "res 0,c" };
case 0x82: return { "res 0,d" };
case 0x83: return { "res 0,e" };
case 0x84: return { "res 0,h" };
case 0x85: return { "res 0,l" };
case 0x86: return { "res 0,(hl)" };
case 0x87: return { "res 0,a" };
case 0x88: return { "res 1,b" };
case 0x89: return { "res 1,c" };
case 0x8a: return { "res 1,d" };
case 0x8b: return { "res 1,e" };
case 0x8c: return { "res 1,h" };
case 0x8d: return { "res 1,l" };
case 0x8e: return { "res 1,(hl)" };
case 0x8f: return { "res 1,a" };
case 0x90: return { "res 2,b" };
case 0x91: return { "res 2,c" };
case 0x92: return { "res 2,d" };
case 0x93: return { "res 2,e" };
case 0x94: return { "res 2,h" };
case 0x95: return { "res 2,l" };
case 0x96: return { "res 2,(hl)" };
case 0x97: return { "res 2,a" };
case 0x98: return { "res 3,b" };
case 0x99: return { "res 3,c" };
case 0x9a: return { "res 3,d" };
case 0x9b: return { "res 3,e" };
case 0x9c: return { "res 3,h" };
case 0x9d: return { "res 3,l" };
case 0x9e: return { "res 3,(hl)" };
case 0x9f: return { "res 3,a" };
case 0xa0: return { "res 4,b" };
case 0xa1: return { "res 4,c" };
case 0xa2: return { "res 4,d" };
case 0xa3: return { "res 4,e" };
case 0xa4: return { "res 4,h" };
case 0xa5: return { "res 4,l" };
case 0xa6: return { "res 4,(hl)" };
case 0xa7: return { "res 4,a" };
case 0xa8: return { "res 5,b" };
case 0xa9: return { "res 5,c" };
case 0xaa: return { "res 5,d" };
case 0xab: return { "res 5,e" };
case 0xac: return { "res 5,h" };
case 0xad: return { "res 5,l" };
case 0xae: return { "res 5,(hl)" };
case 0xaf: return { "res 5,a" };
case 0xb0: return { "res 6,b" };
case 0xb1: return { "res 6,c" };
case 0xb2: return { "res 6,d" };
case 0xb3: return { "res 6,e" };
case 0xb4: return { "res 6,h" };
case 0xb5: return { "res 6,l" };
case 0xb6: return { "res 6,(hl)" };
case 0xb7: return { "res 6,a" };
case 0xb8: return { "res 7,b" };
case 0xb9: return { "res 7,c" };
case 0xba: return { "res 7,d" };
case 0xbb: return { "res 7,e" };
case 0xbc: return { "res 7,h" };
case 0xbd: return { "res 7,l" };
case 0xbe: return { "res 7,(hl)" };
case 0xbf: return { "res 7,a" };
case 0xc0: return { "set 0,b" };
case 0xc1: return { "set 0,c" };
case 0xc2: return { "set 0,d" };
case 0xc3: return { "set 0,e" };
case 0xc4: return { "set 0,h" };
case 0xc5: return { "set 0,l" };
case 0xc6: return { "set 0,(hl)" };
case 0xc7: return { "set 0,a" };
case 0xc8: return { "set 1,b" };
case 0xc9: return { "set 1,c" };
case 0xca: return { "set 1,d" };
case 0xcb: return { "set 1,e" };
case 0xcc: return { "set 1,h" };
case 0xcd: return { "set 1,l" };
case 0xce: return { "set 1,(hl)" };
case 0xcf: return { "set 1,a" };
case 0xd0: return { "set 2,b" };
case 0xd1: return { "set 2,c" };
case 0xd2: return { "set 2,d" };
case 0xd3: return { "set 2,e" };
case 0xd4: return { "set 2,h" };
case 0xd5: return { "set 2,l" };
case 0xd6: return { "set 2,(hl)" };
case 0xd7: return { "set 2,a" };
case 0xd8: return { "set 3,b" };
case 0xd9: return { "set 3,c" };
case 0xda: return { "set 3,d" };
case 0xdb: return { "set 3,e" };
case 0xdc: return { "set 3,h" };
case 0xdd: return { "set 3,l" };
case 0xde: return { "set 3,(hl)" };
case 0xdf: return { "set 3,a" };
case 0xe0: return { "set 4,b" };
case 0xe1: return { "set 4,c" };
case 0xe2: return { "set 4,d" };
case 0xe3: return { "set 4,e" };
case 0xe4: return { "set 4,h" };
case 0xe5: return { "set 4,l" };
case 0xe6: return { "set 4,(hl)" };
case 0xe7: return { "set 4,a" };
case 0xe8: return { "set 5,b" };
case 0xe9: return { "set 5,c" };
case 0xea: return { "set 5,d" };
case 0xeb: return { "set 5,e" };
case 0xec: return { "set 5,h" };
case 0xed: return { "set 5,l" };
case 0xee: return { "set 5,(hl)" };
case 0xef: return { "set 5,a" };
case 0xf0: return { "set 6,b" };
case 0xf1: return { "set 6,c" };
case 0xf2: return { "set 6,d" };
case 0xf3: return { "set 6,e" };
case 0xf4: return { "set 6,h" };
case 0xf5: return { "set 6,l" };
case 0xf6: return { "set 6,(hl)" };
case 0xf7: return { "set 6,a" };
case 0xf8: return { "set 7,b" };
case 0xf9: return { "set 7,c" };
case 0xfa: return { "set 7,d" };
case 0xfb: return { "set 7,e" };
case 0xfc: return { "set 7,h" };
case 0xfd: return { "set 7,l" };
case 0xfe: return { "set 7,(hl)" };
case 0xff: return { "set 7,a" };
}
return "";
}
#endif
-101
View File
@@ -1,101 +0,0 @@
enum {
A, F, AF,
B, C, BC,
D, E, DE,
H, L, HL,
SP, PC,
};
enum {
ZF, NF, HF, CF,
};
//register base class
//the idea here is to have all registers derive from a single base class.
//this allows construction of opcodes that can take any register as input or output,
//despite the fact that behind-the-scenes, special handling is done for eg: F, AF, HL, etc.
//registers can also be chained together: eg af = 0x0000 writes both a and f.
struct Register {
virtual operator unsigned() const = 0;
virtual unsigned operator=(unsigned x) = 0;
Register& operator=(const Register &x) { operator=((unsigned)x); return *this; }
unsigned operator++(int) { unsigned r = *this; operator=(*this + 1); return r; }
unsigned operator--(int) { unsigned r = *this; operator=(*this - 1); return r; }
unsigned operator++() { return operator=(*this + 1); }
unsigned operator--() { return operator=(*this - 1); }
unsigned operator |=(unsigned x) { return operator=(*this | x); }
unsigned operator ^=(unsigned x) { return operator=(*this ^ x); }
unsigned operator &=(unsigned x) { return operator=(*this & x); }
unsigned operator<<=(unsigned x) { return operator=(*this << x); }
unsigned operator>>=(unsigned x) { return operator=(*this >> x); }
unsigned operator +=(unsigned x) { return operator=(*this + x); }
unsigned operator -=(unsigned x) { return operator=(*this - x); }
unsigned operator *=(unsigned x) { return operator=(*this * x); }
unsigned operator /=(unsigned x) { return operator=(*this / x); }
unsigned operator %=(unsigned x) { return operator=(*this % x); }
};
struct Register8 : Register {
uint8 data;
operator unsigned() const { return data; }
unsigned operator=(unsigned x) { return data = x; }
};
struct RegisterF : Register {
bool z, n, h, c;
operator unsigned() const { return (z << 7) | (n << 6) | (h << 5) | (c << 4); }
unsigned operator=(unsigned x) { z = x & 0x80; n = x & 0x40; h = x & 0x20; c = x & 0x10; return *this; }
bool& operator[](unsigned r) {
static bool* table[] = { &z, &n, &h, &c };
return *table[r];
}
};
struct Register16 : Register {
uint16 data;
operator unsigned() const { return data; }
unsigned operator=(unsigned x) { return data = x; }
};
struct RegisterAF : Register {
Register8 &hi;
RegisterF &lo;
operator unsigned() const { return (hi << 8) | (lo << 0); }
unsigned operator=(unsigned x) { hi = x >> 8; lo = x >> 0; return *this; }
RegisterAF(Register8 &hi, RegisterF &lo) : hi(hi), lo(lo) {}
};
struct RegisterW : Register {
Register8 &hi, &lo;
operator unsigned() const { return (hi << 8) | (lo << 0); }
unsigned operator=(unsigned x) { hi = x >> 8; lo = x >> 0; return *this; }
RegisterW(Register8 &hi, Register8 &lo) : hi(hi), lo(lo) {}
};
struct Registers {
Register8 a;
RegisterF f;
RegisterAF af;
Register8 b;
Register8 c;
RegisterW bc;
Register8 d;
Register8 e;
RegisterW de;
Register8 h;
Register8 l;
RegisterW hl;
Register16 sp;
Register16 pc;
Register& operator[](unsigned r) {
static Register* table[] = { &a, &f, &af, &b, &c, &bc, &d, &e, &de, &h, &l, &hl, &sp, &pc };
return *table[r];
}
Registers() : af(a, f), bc(b, c), de(d, e), hl(h, l) {}
} r;
-519
View File
@@ -1,519 +0,0 @@
#ifdef CPU_CPP
void CPU::initialize_opcode_table() {
opcode_table[0x00] = &CPU::op_nop;
opcode_table[0x01] = &CPU::op_ld_rr_nn<BC>;
opcode_table[0x02] = &CPU::op_ld_rr_a<BC>;
opcode_table[0x03] = &CPU::op_inc_rr<BC>;
opcode_table[0x04] = &CPU::op_inc_r<B>;
opcode_table[0x05] = &CPU::op_dec_r<B>;
opcode_table[0x06] = &CPU::op_ld_r_n<B>;
opcode_table[0x07] = &CPU::op_rlca;
opcode_table[0x08] = &CPU::op_ld_nn_sp;
opcode_table[0x09] = &CPU::op_add_hl_rr<BC>;
opcode_table[0x0a] = &CPU::op_ld_a_rr<BC>;
opcode_table[0x0b] = &CPU::op_dec_rr<BC>;
opcode_table[0x0c] = &CPU::op_inc_r<C>;
opcode_table[0x0d] = &CPU::op_dec_r<C>;
opcode_table[0x0e] = &CPU::op_ld_r_n<C>;
opcode_table[0x0f] = &CPU::op_rrca;
opcode_table[0x10] = &CPU::op_stop;
opcode_table[0x11] = &CPU::op_ld_rr_nn<DE>;
opcode_table[0x12] = &CPU::op_ld_rr_a<DE>;
opcode_table[0x13] = &CPU::op_inc_rr<DE>;
opcode_table[0x14] = &CPU::op_inc_r<D>;
opcode_table[0x15] = &CPU::op_dec_r<D>;
opcode_table[0x16] = &CPU::op_ld_r_n<D>;
opcode_table[0x17] = &CPU::op_rla;
opcode_table[0x18] = &CPU::op_jr_n;
opcode_table[0x19] = &CPU::op_add_hl_rr<DE>;
opcode_table[0x1a] = &CPU::op_ld_a_rr<DE>;
opcode_table[0x1b] = &CPU::op_dec_rr<DE>;
opcode_table[0x1c] = &CPU::op_inc_r<E>;
opcode_table[0x1d] = &CPU::op_dec_r<E>;
opcode_table[0x1e] = &CPU::op_ld_r_n<E>;
opcode_table[0x1f] = &CPU::op_rra;
opcode_table[0x20] = &CPU::op_jr_f_n<ZF, 0>;
opcode_table[0x21] = &CPU::op_ld_rr_nn<HL>;
opcode_table[0x22] = &CPU::op_ldi_hl_a;
opcode_table[0x23] = &CPU::op_inc_rr<HL>;
opcode_table[0x24] = &CPU::op_inc_r<H>;
opcode_table[0x25] = &CPU::op_dec_r<H>;
opcode_table[0x26] = &CPU::op_ld_r_n<H>;
opcode_table[0x27] = &CPU::op_daa;
opcode_table[0x28] = &CPU::op_jr_f_n<ZF, 1>;
opcode_table[0x29] = &CPU::op_add_hl_rr<HL>;
opcode_table[0x2a] = &CPU::op_ldi_a_hl;
opcode_table[0x2b] = &CPU::op_dec_rr<HL>;
opcode_table[0x2c] = &CPU::op_inc_r<L>;
opcode_table[0x2d] = &CPU::op_dec_r<L>;
opcode_table[0x2e] = &CPU::op_ld_r_n<L>;
opcode_table[0x2f] = &CPU::op_cpl;
opcode_table[0x30] = &CPU::op_jr_f_n<CF, 0>;
opcode_table[0x31] = &CPU::op_ld_rr_nn<SP>;
opcode_table[0x32] = &CPU::op_ldd_hl_a;
opcode_table[0x33] = &CPU::op_inc_rr<SP>;
opcode_table[0x34] = &CPU::op_inc_hl;
opcode_table[0x35] = &CPU::op_dec_hl;
opcode_table[0x36] = &CPU::op_ld_hl_n;
opcode_table[0x37] = &CPU::op_scf;
opcode_table[0x38] = &CPU::op_jr_f_n<CF, 1>;
opcode_table[0x39] = &CPU::op_add_hl_rr<SP>;
opcode_table[0x3a] = &CPU::op_ldd_a_hl;
opcode_table[0x3b] = &CPU::op_dec_rr<SP>;
opcode_table[0x3c] = &CPU::op_inc_r<A>;
opcode_table[0x3d] = &CPU::op_dec_r<A>;
opcode_table[0x3e] = &CPU::op_ld_r_n<A>;
opcode_table[0x3f] = &CPU::op_ccf;
opcode_table[0x40] = &CPU::op_ld_r_r<B, B>;
opcode_table[0x41] = &CPU::op_ld_r_r<B, C>;
opcode_table[0x42] = &CPU::op_ld_r_r<B, D>;
opcode_table[0x43] = &CPU::op_ld_r_r<B, E>;
opcode_table[0x44] = &CPU::op_ld_r_r<B, H>;
opcode_table[0x45] = &CPU::op_ld_r_r<B, L>;
opcode_table[0x46] = &CPU::op_ld_r_hl<B>;
opcode_table[0x47] = &CPU::op_ld_r_r<B, A>;
opcode_table[0x48] = &CPU::op_ld_r_r<C, B>;
opcode_table[0x49] = &CPU::op_ld_r_r<C, C>;
opcode_table[0x4a] = &CPU::op_ld_r_r<C, D>;
opcode_table[0x4b] = &CPU::op_ld_r_r<C, E>;
opcode_table[0x4c] = &CPU::op_ld_r_r<C, H>;
opcode_table[0x4d] = &CPU::op_ld_r_r<C, L>;
opcode_table[0x4e] = &CPU::op_ld_r_hl<C>;
opcode_table[0x4f] = &CPU::op_ld_r_r<C, A>;
opcode_table[0x50] = &CPU::op_ld_r_r<D, B>;
opcode_table[0x51] = &CPU::op_ld_r_r<D, C>;
opcode_table[0x52] = &CPU::op_ld_r_r<D, D>;
opcode_table[0x53] = &CPU::op_ld_r_r<D, E>;
opcode_table[0x54] = &CPU::op_ld_r_r<D, H>;
opcode_table[0x55] = &CPU::op_ld_r_r<D, L>;
opcode_table[0x56] = &CPU::op_ld_r_hl<D>;
opcode_table[0x57] = &CPU::op_ld_r_r<D, A>;
opcode_table[0x58] = &CPU::op_ld_r_r<E, B>;
opcode_table[0x59] = &CPU::op_ld_r_r<E, C>;
opcode_table[0x5a] = &CPU::op_ld_r_r<E, D>;
opcode_table[0x5b] = &CPU::op_ld_r_r<E, E>;
opcode_table[0x5c] = &CPU::op_ld_r_r<E, H>;
opcode_table[0x5d] = &CPU::op_ld_r_r<E, L>;
opcode_table[0x5e] = &CPU::op_ld_r_hl<E>;
opcode_table[0x5f] = &CPU::op_ld_r_r<E, A>;
opcode_table[0x60] = &CPU::op_ld_r_r<H, B>;
opcode_table[0x61] = &CPU::op_ld_r_r<H, C>;
opcode_table[0x62] = &CPU::op_ld_r_r<H, D>;
opcode_table[0x63] = &CPU::op_ld_r_r<H, E>;
opcode_table[0x64] = &CPU::op_ld_r_r<H, H>;
opcode_table[0x65] = &CPU::op_ld_r_r<H, L>;
opcode_table[0x66] = &CPU::op_ld_r_hl<H>;
opcode_table[0x67] = &CPU::op_ld_r_r<H, A>;
opcode_table[0x68] = &CPU::op_ld_r_r<L, B>;
opcode_table[0x69] = &CPU::op_ld_r_r<L, C>;
opcode_table[0x6a] = &CPU::op_ld_r_r<L, D>;
opcode_table[0x6b] = &CPU::op_ld_r_r<L, E>;
opcode_table[0x6c] = &CPU::op_ld_r_r<L, H>;
opcode_table[0x6d] = &CPU::op_ld_r_r<L, L>;
opcode_table[0x6e] = &CPU::op_ld_r_hl<L>;
opcode_table[0x6f] = &CPU::op_ld_r_r<L, A>;
opcode_table[0x70] = &CPU::op_ld_hl_r<B>;
opcode_table[0x71] = &CPU::op_ld_hl_r<C>;
opcode_table[0x72] = &CPU::op_ld_hl_r<D>;
opcode_table[0x73] = &CPU::op_ld_hl_r<E>;
opcode_table[0x74] = &CPU::op_ld_hl_r<H>;
opcode_table[0x75] = &CPU::op_ld_hl_r<L>;
opcode_table[0x76] = &CPU::op_halt;
opcode_table[0x77] = &CPU::op_ld_hl_r<A>;
opcode_table[0x78] = &CPU::op_ld_r_r<A, B>;
opcode_table[0x79] = &CPU::op_ld_r_r<A, C>;
opcode_table[0x7a] = &CPU::op_ld_r_r<A, D>;
opcode_table[0x7b] = &CPU::op_ld_r_r<A, E>;
opcode_table[0x7c] = &CPU::op_ld_r_r<A, H>;
opcode_table[0x7d] = &CPU::op_ld_r_r<A, L>;
opcode_table[0x7e] = &CPU::op_ld_r_hl<A>;
opcode_table[0x7f] = &CPU::op_ld_r_r<A, A>;
opcode_table[0x80] = &CPU::op_add_a_r<B>;
opcode_table[0x81] = &CPU::op_add_a_r<C>;
opcode_table[0x82] = &CPU::op_add_a_r<D>;
opcode_table[0x83] = &CPU::op_add_a_r<E>;
opcode_table[0x84] = &CPU::op_add_a_r<H>;
opcode_table[0x85] = &CPU::op_add_a_r<L>;
opcode_table[0x86] = &CPU::op_add_a_hl;
opcode_table[0x87] = &CPU::op_add_a_r<A>;
opcode_table[0x88] = &CPU::op_adc_a_r<B>;
opcode_table[0x89] = &CPU::op_adc_a_r<C>;
opcode_table[0x8a] = &CPU::op_adc_a_r<D>;
opcode_table[0x8b] = &CPU::op_adc_a_r<E>;
opcode_table[0x8c] = &CPU::op_adc_a_r<H>;
opcode_table[0x8d] = &CPU::op_adc_a_r<L>;
opcode_table[0x8e] = &CPU::op_adc_a_hl;
opcode_table[0x8f] = &CPU::op_adc_a_r<A>;
opcode_table[0x90] = &CPU::op_sub_a_r<B>;
opcode_table[0x91] = &CPU::op_sub_a_r<C>;
opcode_table[0x92] = &CPU::op_sub_a_r<D>;
opcode_table[0x93] = &CPU::op_sub_a_r<E>;
opcode_table[0x94] = &CPU::op_sub_a_r<H>;
opcode_table[0x95] = &CPU::op_sub_a_r<L>;
opcode_table[0x96] = &CPU::op_sub_a_hl;
opcode_table[0x97] = &CPU::op_sub_a_r<A>;
opcode_table[0x98] = &CPU::op_sbc_a_r<B>;
opcode_table[0x99] = &CPU::op_sbc_a_r<C>;
opcode_table[0x9a] = &CPU::op_sbc_a_r<D>;
opcode_table[0x9b] = &CPU::op_sbc_a_r<E>;
opcode_table[0x9c] = &CPU::op_sbc_a_r<H>;
opcode_table[0x9d] = &CPU::op_sbc_a_r<L>;
opcode_table[0x9e] = &CPU::op_sbc_a_hl;
opcode_table[0x9f] = &CPU::op_sbc_a_r<A>;
opcode_table[0xa0] = &CPU::op_and_a_r<B>;
opcode_table[0xa1] = &CPU::op_and_a_r<C>;
opcode_table[0xa2] = &CPU::op_and_a_r<D>;
opcode_table[0xa3] = &CPU::op_and_a_r<E>;
opcode_table[0xa4] = &CPU::op_and_a_r<H>;
opcode_table[0xa5] = &CPU::op_and_a_r<L>;
opcode_table[0xa6] = &CPU::op_and_a_hl;
opcode_table[0xa7] = &CPU::op_and_a_r<A>;
opcode_table[0xa8] = &CPU::op_xor_a_r<B>;
opcode_table[0xa9] = &CPU::op_xor_a_r<C>;
opcode_table[0xaa] = &CPU::op_xor_a_r<D>;
opcode_table[0xab] = &CPU::op_xor_a_r<E>;
opcode_table[0xac] = &CPU::op_xor_a_r<H>;
opcode_table[0xad] = &CPU::op_xor_a_r<L>;
opcode_table[0xae] = &CPU::op_xor_a_hl;
opcode_table[0xaf] = &CPU::op_xor_a_r<A>;
opcode_table[0xb0] = &CPU::op_or_a_r<B>;
opcode_table[0xb1] = &CPU::op_or_a_r<C>;
opcode_table[0xb2] = &CPU::op_or_a_r<D>;
opcode_table[0xb3] = &CPU::op_or_a_r<E>;
opcode_table[0xb4] = &CPU::op_or_a_r<H>;
opcode_table[0xb5] = &CPU::op_or_a_r<L>;
opcode_table[0xb6] = &CPU::op_or_a_hl;
opcode_table[0xb7] = &CPU::op_or_a_r<A>;
opcode_table[0xb8] = &CPU::op_cp_a_r<B>;
opcode_table[0xb9] = &CPU::op_cp_a_r<C>;
opcode_table[0xba] = &CPU::op_cp_a_r<D>;
opcode_table[0xbb] = &CPU::op_cp_a_r<E>;
opcode_table[0xbc] = &CPU::op_cp_a_r<H>;
opcode_table[0xbd] = &CPU::op_cp_a_r<L>;
opcode_table[0xbe] = &CPU::op_cp_a_hl;
opcode_table[0xbf] = &CPU::op_cp_a_r<A>;
opcode_table[0xc0] = &CPU::op_ret_f<ZF, 0>;
opcode_table[0xc1] = &CPU::op_pop_rr<BC>;
opcode_table[0xc2] = &CPU::op_jp_f_nn<ZF, 0>;
opcode_table[0xc3] = &CPU::op_jp_nn;
opcode_table[0xc4] = &CPU::op_call_f_nn<ZF, 0>;
opcode_table[0xc5] = &CPU::op_push_rr<BC>;
opcode_table[0xc6] = &CPU::op_add_a_n;
opcode_table[0xc7] = &CPU::op_rst_n<0x00>;
opcode_table[0xc8] = &CPU::op_ret_f<ZF, 1>;
opcode_table[0xc9] = &CPU::op_ret;
opcode_table[0xca] = &CPU::op_jp_f_nn<ZF, 1>;
opcode_table[0xcb] = &CPU::op_cb;
opcode_table[0xcc] = &CPU::op_call_f_nn<ZF, 1>;
opcode_table[0xcd] = &CPU::op_call_nn;
opcode_table[0xce] = &CPU::op_adc_a_n;
opcode_table[0xcf] = &CPU::op_rst_n<0x08>;
opcode_table[0xd0] = &CPU::op_ret_f<CF, 0>;
opcode_table[0xd1] = &CPU::op_pop_rr<DE>;
opcode_table[0xd2] = &CPU::op_jp_f_nn<CF, 0>;
opcode_table[0xd3] = &CPU::op_xx;
opcode_table[0xd4] = &CPU::op_call_f_nn<CF, 0>;
opcode_table[0xd5] = &CPU::op_push_rr<DE>;
opcode_table[0xd6] = &CPU::op_sub_a_n;
opcode_table[0xd7] = &CPU::op_rst_n<0x10>;
opcode_table[0xd8] = &CPU::op_ret_f<CF, 1>;
opcode_table[0xd9] = &CPU::op_reti;
opcode_table[0xda] = &CPU::op_jp_f_nn<CF, 1>;
opcode_table[0xdb] = &CPU::op_xx;
opcode_table[0xdc] = &CPU::op_call_f_nn<CF, 1>;
opcode_table[0xdd] = &CPU::op_xx;
opcode_table[0xde] = &CPU::op_sbc_a_n;
opcode_table[0xdf] = &CPU::op_rst_n<0x18>;
opcode_table[0xe0] = &CPU::op_ld_ffn_a;
opcode_table[0xe1] = &CPU::op_pop_rr<HL>;
opcode_table[0xe2] = &CPU::op_ld_ffc_a;
opcode_table[0xe3] = &CPU::op_xx;
opcode_table[0xe4] = &CPU::op_xx;
opcode_table[0xe5] = &CPU::op_push_rr<HL>;
opcode_table[0xe6] = &CPU::op_and_a_n;
opcode_table[0xe7] = &CPU::op_rst_n<0x20>;
opcode_table[0xe8] = &CPU::op_add_sp_n;
opcode_table[0xe9] = &CPU::op_jp_hl;
opcode_table[0xea] = &CPU::op_ld_nn_a;
opcode_table[0xeb] = &CPU::op_xx;
opcode_table[0xec] = &CPU::op_xx;
opcode_table[0xed] = &CPU::op_xx;
opcode_table[0xee] = &CPU::op_xor_a_n;
opcode_table[0xef] = &CPU::op_rst_n<0x28>;
opcode_table[0xf0] = &CPU::op_ld_a_ffn;
opcode_table[0xf1] = &CPU::op_pop_rr<AF>;
opcode_table[0xf2] = &CPU::op_ld_a_ffc;
opcode_table[0xf3] = &CPU::op_di;
opcode_table[0xf4] = &CPU::op_xx;
opcode_table[0xf5] = &CPU::op_push_rr<AF>;
opcode_table[0xf6] = &CPU::op_or_a_n;
opcode_table[0xf7] = &CPU::op_rst_n<0x30>;
opcode_table[0xf8] = &CPU::op_ld_hl_sp_n;
opcode_table[0xf9] = &CPU::op_ld_sp_hl;
opcode_table[0xfa] = &CPU::op_ld_a_nn;
opcode_table[0xfb] = &CPU::op_ei;
opcode_table[0xfc] = &CPU::op_xx;
opcode_table[0xfd] = &CPU::op_xx;
opcode_table[0xfe] = &CPU::op_cp_a_n;
opcode_table[0xff] = &CPU::op_rst_n<0x38>;
opcode_table_cb[0x00] = &CPU::op_rlc_r<B>;
opcode_table_cb[0x01] = &CPU::op_rlc_r<C>;
opcode_table_cb[0x02] = &CPU::op_rlc_r<D>;
opcode_table_cb[0x03] = &CPU::op_rlc_r<E>;
opcode_table_cb[0x04] = &CPU::op_rlc_r<H>;
opcode_table_cb[0x05] = &CPU::op_rlc_r<L>;
opcode_table_cb[0x06] = &CPU::op_rlc_hl;
opcode_table_cb[0x07] = &CPU::op_rlc_r<A>;
opcode_table_cb[0x08] = &CPU::op_rrc_r<B>;
opcode_table_cb[0x09] = &CPU::op_rrc_r<C>;
opcode_table_cb[0x0a] = &CPU::op_rrc_r<D>;
opcode_table_cb[0x0b] = &CPU::op_rrc_r<E>;
opcode_table_cb[0x0c] = &CPU::op_rrc_r<H>;
opcode_table_cb[0x0d] = &CPU::op_rrc_r<L>;
opcode_table_cb[0x0e] = &CPU::op_rrc_hl;
opcode_table_cb[0x0f] = &CPU::op_rrc_r<A>;
opcode_table_cb[0x10] = &CPU::op_rl_r<B>;
opcode_table_cb[0x11] = &CPU::op_rl_r<C>;
opcode_table_cb[0x12] = &CPU::op_rl_r<D>;
opcode_table_cb[0x13] = &CPU::op_rl_r<E>;
opcode_table_cb[0x14] = &CPU::op_rl_r<H>;
opcode_table_cb[0x15] = &CPU::op_rl_r<L>;
opcode_table_cb[0x16] = &CPU::op_rl_hl;
opcode_table_cb[0x17] = &CPU::op_rl_r<A>;
opcode_table_cb[0x18] = &CPU::op_rr_r<B>;
opcode_table_cb[0x19] = &CPU::op_rr_r<C>;
opcode_table_cb[0x1a] = &CPU::op_rr_r<D>;
opcode_table_cb[0x1b] = &CPU::op_rr_r<E>;
opcode_table_cb[0x1c] = &CPU::op_rr_r<H>;
opcode_table_cb[0x1d] = &CPU::op_rr_r<L>;
opcode_table_cb[0x1e] = &CPU::op_rr_hl;
opcode_table_cb[0x1f] = &CPU::op_rr_r<A>;
opcode_table_cb[0x20] = &CPU::op_sla_r<B>;
opcode_table_cb[0x21] = &CPU::op_sla_r<C>;
opcode_table_cb[0x22] = &CPU::op_sla_r<D>;
opcode_table_cb[0x23] = &CPU::op_sla_r<E>;
opcode_table_cb[0x24] = &CPU::op_sla_r<H>;
opcode_table_cb[0x25] = &CPU::op_sla_r<L>;
opcode_table_cb[0x26] = &CPU::op_sla_hl;
opcode_table_cb[0x27] = &CPU::op_sla_r<A>;
opcode_table_cb[0x28] = &CPU::op_sra_r<B>;
opcode_table_cb[0x29] = &CPU::op_sra_r<C>;
opcode_table_cb[0x2a] = &CPU::op_sra_r<D>;
opcode_table_cb[0x2b] = &CPU::op_sra_r<E>;
opcode_table_cb[0x2c] = &CPU::op_sra_r<H>;
opcode_table_cb[0x2d] = &CPU::op_sra_r<L>;
opcode_table_cb[0x2e] = &CPU::op_sra_hl;
opcode_table_cb[0x2f] = &CPU::op_sra_r<A>;
opcode_table_cb[0x30] = &CPU::op_swap_r<B>;
opcode_table_cb[0x31] = &CPU::op_swap_r<C>;
opcode_table_cb[0x32] = &CPU::op_swap_r<D>;
opcode_table_cb[0x33] = &CPU::op_swap_r<E>;
opcode_table_cb[0x34] = &CPU::op_swap_r<H>;
opcode_table_cb[0x35] = &CPU::op_swap_r<L>;
opcode_table_cb[0x36] = &CPU::op_swap_hl;
opcode_table_cb[0x37] = &CPU::op_swap_r<A>;
opcode_table_cb[0x38] = &CPU::op_srl_r<B>;
opcode_table_cb[0x39] = &CPU::op_srl_r<C>;
opcode_table_cb[0x3a] = &CPU::op_srl_r<D>;
opcode_table_cb[0x3b] = &CPU::op_srl_r<E>;
opcode_table_cb[0x3c] = &CPU::op_srl_r<H>;
opcode_table_cb[0x3d] = &CPU::op_srl_r<L>;
opcode_table_cb[0x3e] = &CPU::op_srl_hl;
opcode_table_cb[0x3f] = &CPU::op_srl_r<A>;
opcode_table_cb[0x40] = &CPU::op_bit_n_r<0, B>;
opcode_table_cb[0x41] = &CPU::op_bit_n_r<0, C>;
opcode_table_cb[0x42] = &CPU::op_bit_n_r<0, D>;
opcode_table_cb[0x43] = &CPU::op_bit_n_r<0, E>;
opcode_table_cb[0x44] = &CPU::op_bit_n_r<0, H>;
opcode_table_cb[0x45] = &CPU::op_bit_n_r<0, L>;
opcode_table_cb[0x46] = &CPU::op_bit_n_hl<0>;
opcode_table_cb[0x47] = &CPU::op_bit_n_r<0, A>;
opcode_table_cb[0x48] = &CPU::op_bit_n_r<1, B>;
opcode_table_cb[0x49] = &CPU::op_bit_n_r<1, C>;
opcode_table_cb[0x4a] = &CPU::op_bit_n_r<1, D>;
opcode_table_cb[0x4b] = &CPU::op_bit_n_r<1, E>;
opcode_table_cb[0x4c] = &CPU::op_bit_n_r<1, H>;
opcode_table_cb[0x4d] = &CPU::op_bit_n_r<1, L>;
opcode_table_cb[0x4e] = &CPU::op_bit_n_hl<1>;
opcode_table_cb[0x4f] = &CPU::op_bit_n_r<1, A>;
opcode_table_cb[0x50] = &CPU::op_bit_n_r<2, B>;
opcode_table_cb[0x51] = &CPU::op_bit_n_r<2, C>;
opcode_table_cb[0x52] = &CPU::op_bit_n_r<2, D>;
opcode_table_cb[0x53] = &CPU::op_bit_n_r<2, E>;
opcode_table_cb[0x54] = &CPU::op_bit_n_r<2, H>;
opcode_table_cb[0x55] = &CPU::op_bit_n_r<2, L>;
opcode_table_cb[0x56] = &CPU::op_bit_n_hl<2>;
opcode_table_cb[0x57] = &CPU::op_bit_n_r<2, A>;
opcode_table_cb[0x58] = &CPU::op_bit_n_r<3, B>;
opcode_table_cb[0x59] = &CPU::op_bit_n_r<3, C>;
opcode_table_cb[0x5a] = &CPU::op_bit_n_r<3, D>;
opcode_table_cb[0x5b] = &CPU::op_bit_n_r<3, E>;
opcode_table_cb[0x5c] = &CPU::op_bit_n_r<3, H>;
opcode_table_cb[0x5d] = &CPU::op_bit_n_r<3, L>;
opcode_table_cb[0x5e] = &CPU::op_bit_n_hl<3>;
opcode_table_cb[0x5f] = &CPU::op_bit_n_r<3, A>;
opcode_table_cb[0x60] = &CPU::op_bit_n_r<4, B>;
opcode_table_cb[0x61] = &CPU::op_bit_n_r<4, C>;
opcode_table_cb[0x62] = &CPU::op_bit_n_r<4, D>;
opcode_table_cb[0x63] = &CPU::op_bit_n_r<4, E>;
opcode_table_cb[0x64] = &CPU::op_bit_n_r<4, H>;
opcode_table_cb[0x65] = &CPU::op_bit_n_r<4, L>;
opcode_table_cb[0x66] = &CPU::op_bit_n_hl<4>;
opcode_table_cb[0x67] = &CPU::op_bit_n_r<4, A>;
opcode_table_cb[0x68] = &CPU::op_bit_n_r<5, B>;
opcode_table_cb[0x69] = &CPU::op_bit_n_r<5, C>;
opcode_table_cb[0x6a] = &CPU::op_bit_n_r<5, D>;
opcode_table_cb[0x6b] = &CPU::op_bit_n_r<5, E>;
opcode_table_cb[0x6c] = &CPU::op_bit_n_r<5, H>;
opcode_table_cb[0x6d] = &CPU::op_bit_n_r<5, L>;
opcode_table_cb[0x6e] = &CPU::op_bit_n_hl<5>;
opcode_table_cb[0x6f] = &CPU::op_bit_n_r<5, A>;
opcode_table_cb[0x70] = &CPU::op_bit_n_r<6, B>;
opcode_table_cb[0x71] = &CPU::op_bit_n_r<6, C>;
opcode_table_cb[0x72] = &CPU::op_bit_n_r<6, D>;
opcode_table_cb[0x73] = &CPU::op_bit_n_r<6, E>;
opcode_table_cb[0x74] = &CPU::op_bit_n_r<6, H>;
opcode_table_cb[0x75] = &CPU::op_bit_n_r<6, L>;
opcode_table_cb[0x76] = &CPU::op_bit_n_hl<6>;
opcode_table_cb[0x77] = &CPU::op_bit_n_r<6, A>;
opcode_table_cb[0x78] = &CPU::op_bit_n_r<7, B>;
opcode_table_cb[0x79] = &CPU::op_bit_n_r<7, C>;
opcode_table_cb[0x7a] = &CPU::op_bit_n_r<7, D>;
opcode_table_cb[0x7b] = &CPU::op_bit_n_r<7, E>;
opcode_table_cb[0x7c] = &CPU::op_bit_n_r<7, H>;
opcode_table_cb[0x7d] = &CPU::op_bit_n_r<7, L>;
opcode_table_cb[0x7e] = &CPU::op_bit_n_hl<7>;
opcode_table_cb[0x7f] = &CPU::op_bit_n_r<7, A>;
opcode_table_cb[0x80] = &CPU::op_res_n_r<0, B>;
opcode_table_cb[0x81] = &CPU::op_res_n_r<0, C>;
opcode_table_cb[0x82] = &CPU::op_res_n_r<0, D>;
opcode_table_cb[0x83] = &CPU::op_res_n_r<0, E>;
opcode_table_cb[0x84] = &CPU::op_res_n_r<0, H>;
opcode_table_cb[0x85] = &CPU::op_res_n_r<0, L>;
opcode_table_cb[0x86] = &CPU::op_res_n_hl<0>;
opcode_table_cb[0x87] = &CPU::op_res_n_r<0, A>;
opcode_table_cb[0x88] = &CPU::op_res_n_r<1, B>;
opcode_table_cb[0x89] = &CPU::op_res_n_r<1, C>;
opcode_table_cb[0x8a] = &CPU::op_res_n_r<1, D>;
opcode_table_cb[0x8b] = &CPU::op_res_n_r<1, E>;
opcode_table_cb[0x8c] = &CPU::op_res_n_r<1, H>;
opcode_table_cb[0x8d] = &CPU::op_res_n_r<1, L>;
opcode_table_cb[0x8e] = &CPU::op_res_n_hl<1>;
opcode_table_cb[0x8f] = &CPU::op_res_n_r<1, A>;
opcode_table_cb[0x90] = &CPU::op_res_n_r<2, B>;
opcode_table_cb[0x91] = &CPU::op_res_n_r<2, C>;
opcode_table_cb[0x92] = &CPU::op_res_n_r<2, D>;
opcode_table_cb[0x93] = &CPU::op_res_n_r<2, E>;
opcode_table_cb[0x94] = &CPU::op_res_n_r<2, H>;
opcode_table_cb[0x95] = &CPU::op_res_n_r<2, L>;
opcode_table_cb[0x96] = &CPU::op_res_n_hl<2>;
opcode_table_cb[0x97] = &CPU::op_res_n_r<2, A>;
opcode_table_cb[0x98] = &CPU::op_res_n_r<3, B>;
opcode_table_cb[0x99] = &CPU::op_res_n_r<3, C>;
opcode_table_cb[0x9a] = &CPU::op_res_n_r<3, D>;
opcode_table_cb[0x9b] = &CPU::op_res_n_r<3, E>;
opcode_table_cb[0x9c] = &CPU::op_res_n_r<3, H>;
opcode_table_cb[0x9d] = &CPU::op_res_n_r<3, L>;
opcode_table_cb[0x9e] = &CPU::op_res_n_hl<3>;
opcode_table_cb[0x9f] = &CPU::op_res_n_r<3, A>;
opcode_table_cb[0xa0] = &CPU::op_res_n_r<4, B>;
opcode_table_cb[0xa1] = &CPU::op_res_n_r<4, C>;
opcode_table_cb[0xa2] = &CPU::op_res_n_r<4, D>;
opcode_table_cb[0xa3] = &CPU::op_res_n_r<4, E>;
opcode_table_cb[0xa4] = &CPU::op_res_n_r<4, H>;
opcode_table_cb[0xa5] = &CPU::op_res_n_r<4, L>;
opcode_table_cb[0xa6] = &CPU::op_res_n_hl<4>;
opcode_table_cb[0xa7] = &CPU::op_res_n_r<4, A>;
opcode_table_cb[0xa8] = &CPU::op_res_n_r<5, B>;
opcode_table_cb[0xa9] = &CPU::op_res_n_r<5, C>;
opcode_table_cb[0xaa] = &CPU::op_res_n_r<5, D>;
opcode_table_cb[0xab] = &CPU::op_res_n_r<5, E>;
opcode_table_cb[0xac] = &CPU::op_res_n_r<5, H>;
opcode_table_cb[0xad] = &CPU::op_res_n_r<5, L>;
opcode_table_cb[0xae] = &CPU::op_res_n_hl<5>;
opcode_table_cb[0xaf] = &CPU::op_res_n_r<5, A>;
opcode_table_cb[0xb0] = &CPU::op_res_n_r<6, B>;
opcode_table_cb[0xb1] = &CPU::op_res_n_r<6, C>;
opcode_table_cb[0xb2] = &CPU::op_res_n_r<6, D>;
opcode_table_cb[0xb3] = &CPU::op_res_n_r<6, E>;
opcode_table_cb[0xb4] = &CPU::op_res_n_r<6, H>;
opcode_table_cb[0xb5] = &CPU::op_res_n_r<6, L>;
opcode_table_cb[0xb6] = &CPU::op_res_n_hl<6>;
opcode_table_cb[0xb7] = &CPU::op_res_n_r<6, A>;
opcode_table_cb[0xb8] = &CPU::op_res_n_r<7, B>;
opcode_table_cb[0xb9] = &CPU::op_res_n_r<7, C>;
opcode_table_cb[0xba] = &CPU::op_res_n_r<7, D>;
opcode_table_cb[0xbb] = &CPU::op_res_n_r<7, E>;
opcode_table_cb[0xbc] = &CPU::op_res_n_r<7, H>;
opcode_table_cb[0xbd] = &CPU::op_res_n_r<7, L>;
opcode_table_cb[0xbe] = &CPU::op_res_n_hl<7>;
opcode_table_cb[0xbf] = &CPU::op_res_n_r<7, A>;
opcode_table_cb[0xc0] = &CPU::op_set_n_r<0, B>;
opcode_table_cb[0xc1] = &CPU::op_set_n_r<0, C>;
opcode_table_cb[0xc2] = &CPU::op_set_n_r<0, D>;
opcode_table_cb[0xc3] = &CPU::op_set_n_r<0, E>;
opcode_table_cb[0xc4] = &CPU::op_set_n_r<0, H>;
opcode_table_cb[0xc5] = &CPU::op_set_n_r<0, L>;
opcode_table_cb[0xc6] = &CPU::op_set_n_hl<0>;
opcode_table_cb[0xc7] = &CPU::op_set_n_r<0, A>;
opcode_table_cb[0xc8] = &CPU::op_set_n_r<1, B>;
opcode_table_cb[0xc9] = &CPU::op_set_n_r<1, C>;
opcode_table_cb[0xca] = &CPU::op_set_n_r<1, D>;
opcode_table_cb[0xcb] = &CPU::op_set_n_r<1, E>;
opcode_table_cb[0xcc] = &CPU::op_set_n_r<1, H>;
opcode_table_cb[0xcd] = &CPU::op_set_n_r<1, L>;
opcode_table_cb[0xce] = &CPU::op_set_n_hl<1>;
opcode_table_cb[0xcf] = &CPU::op_set_n_r<1, A>;
opcode_table_cb[0xd0] = &CPU::op_set_n_r<2, B>;
opcode_table_cb[0xd1] = &CPU::op_set_n_r<2, C>;
opcode_table_cb[0xd2] = &CPU::op_set_n_r<2, D>;
opcode_table_cb[0xd3] = &CPU::op_set_n_r<2, E>;
opcode_table_cb[0xd4] = &CPU::op_set_n_r<2, H>;
opcode_table_cb[0xd5] = &CPU::op_set_n_r<2, L>;
opcode_table_cb[0xd6] = &CPU::op_set_n_hl<2>;
opcode_table_cb[0xd7] = &CPU::op_set_n_r<2, A>;
opcode_table_cb[0xd8] = &CPU::op_set_n_r<3, B>;
opcode_table_cb[0xd9] = &CPU::op_set_n_r<3, C>;
opcode_table_cb[0xda] = &CPU::op_set_n_r<3, D>;
opcode_table_cb[0xdb] = &CPU::op_set_n_r<3, E>;
opcode_table_cb[0xdc] = &CPU::op_set_n_r<3, H>;
opcode_table_cb[0xdd] = &CPU::op_set_n_r<3, L>;
opcode_table_cb[0xde] = &CPU::op_set_n_hl<3>;
opcode_table_cb[0xdf] = &CPU::op_set_n_r<3, A>;
opcode_table_cb[0xe0] = &CPU::op_set_n_r<4, B>;
opcode_table_cb[0xe1] = &CPU::op_set_n_r<4, C>;
opcode_table_cb[0xe2] = &CPU::op_set_n_r<4, D>;
opcode_table_cb[0xe3] = &CPU::op_set_n_r<4, E>;
opcode_table_cb[0xe4] = &CPU::op_set_n_r<4, H>;
opcode_table_cb[0xe5] = &CPU::op_set_n_r<4, L>;
opcode_table_cb[0xe6] = &CPU::op_set_n_hl<4>;
opcode_table_cb[0xe7] = &CPU::op_set_n_r<4, A>;
opcode_table_cb[0xe8] = &CPU::op_set_n_r<5, B>;
opcode_table_cb[0xe9] = &CPU::op_set_n_r<5, C>;
opcode_table_cb[0xea] = &CPU::op_set_n_r<5, D>;
opcode_table_cb[0xeb] = &CPU::op_set_n_r<5, E>;
opcode_table_cb[0xec] = &CPU::op_set_n_r<5, H>;
opcode_table_cb[0xed] = &CPU::op_set_n_r<5, L>;
opcode_table_cb[0xee] = &CPU::op_set_n_hl<5>;
opcode_table_cb[0xef] = &CPU::op_set_n_r<5, A>;
opcode_table_cb[0xf0] = &CPU::op_set_n_r<6, B>;
opcode_table_cb[0xf1] = &CPU::op_set_n_r<6, C>;
opcode_table_cb[0xf2] = &CPU::op_set_n_r<6, D>;
opcode_table_cb[0xf3] = &CPU::op_set_n_r<6, E>;
opcode_table_cb[0xf4] = &CPU::op_set_n_r<6, H>;
opcode_table_cb[0xf5] = &CPU::op_set_n_r<6, L>;
opcode_table_cb[0xf6] = &CPU::op_set_n_hl<6>;
opcode_table_cb[0xf7] = &CPU::op_set_n_r<6, A>;
opcode_table_cb[0xf8] = &CPU::op_set_n_r<7, B>;
opcode_table_cb[0xf9] = &CPU::op_set_n_r<7, C>;
opcode_table_cb[0xfa] = &CPU::op_set_n_r<7, D>;
opcode_table_cb[0xfb] = &CPU::op_set_n_r<7, E>;
opcode_table_cb[0xfc] = &CPU::op_set_n_r<7, H>;
opcode_table_cb[0xfd] = &CPU::op_set_n_r<7, L>;
opcode_table_cb[0xfe] = &CPU::op_set_n_hl<7>;
opcode_table_cb[0xff] = &CPU::op_set_n_r<7, A>;
}
#endif
-162
View File
@@ -1,162 +0,0 @@
#include <gameboy/gameboy.hpp>
#define CPU_CPP
namespace GameBoy {
#include "core/core.cpp"
#include "mmio/mmio.cpp"
#include "timing/timing.cpp"
#include "serialization.cpp"
CPU cpu;
void CPU::Main() {
cpu.main();
}
void CPU::main() {
while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::CPU) {
scheduler.sync = Scheduler::SynchronizeMode::All;
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
}
if(trace) print(disassemble(r[PC]), "\n");
interrupt_test();
uint8 opcode = op_read(r[PC]++);
(this->*opcode_table[opcode])();
}
}
void CPU::interrupt_raise(CPU::Interrupt id) {
if(id == Interrupt::Vblank) {
status.interrupt_request_vblank = 1;
if(status.interrupt_enable_vblank) status.halt = false;
}
if(id == Interrupt::Stat) {
status.interrupt_request_stat = 1;
if(status.interrupt_enable_stat) status.halt = false;
}
if(id == Interrupt::Timer) {
status.interrupt_request_timer = 1;
if(status.interrupt_enable_timer) status.halt = false;
}
if(id == Interrupt::Serial) {
status.interrupt_request_serial = 1;
if(status.interrupt_enable_serial) status.halt = false;
}
if(id == Interrupt::Joypad) {
status.interrupt_request_joypad = 1;
if(status.interrupt_enable_joypad) status.halt = status.stop = false;
}
}
void CPU::interrupt_test() {
if(status.ime) {
if(status.interrupt_request_vblank && status.interrupt_enable_vblank) {
status.interrupt_request_vblank = 0;
return interrupt_exec(0x0040);
}
if(status.interrupt_request_stat && status.interrupt_enable_stat) {
status.interrupt_request_stat = 0;
return interrupt_exec(0x0048);
}
if(status.interrupt_request_timer && status.interrupt_enable_timer) {
status.interrupt_request_timer = 0;
return interrupt_exec(0x0050);
}
if(status.interrupt_request_serial && status.interrupt_enable_serial) {
status.interrupt_request_serial = 0;
return interrupt_exec(0x0058);
}
if(status.interrupt_request_joypad && status.interrupt_enable_joypad) {
status.interrupt_request_joypad = 0;
return interrupt_exec(0x0060);
}
}
}
void CPU::interrupt_exec(uint16 pc) {
status.ime = 0;
op_write(--r[SP], r[PC] >> 8);
op_write(--r[SP], r[PC] >> 0);
r[PC] = pc;
op_io();
op_io();
op_io();
}
void CPU::power() {
create(Main, 4 * 1024 * 1024);
for(unsigned n = 0xc000; n <= 0xdfff; n++) bus.mmio[n] = this; //WRAM
for(unsigned n = 0xe000; n <= 0xfdff; n++) bus.mmio[n] = this; //WRAM (mirror)
for(unsigned n = 0xff00; n <= 0xff0f; n++) bus.mmio[n] = this; //MMIO
for(unsigned n = 0xff80; n <= 0xffff; n++) bus.mmio[n] = this; //HRAM+IE
for(unsigned n = 0; n < 8192; n++) wram[n] = 0x00;
for(unsigned n = 0; n < 128; n++) hram[n] = 0x00;
r[PC] = 0x0000;
r[SP] = 0x0000;
r[AF] = 0x0000;
r[BC] = 0x0000;
r[DE] = 0x0000;
r[HL] = 0x0000;
status.clock = 0;
status.halt = false;
status.stop = false;
status.ime = 0;
status.timer0 = 0;
status.timer1 = 0;
status.timer2 = 0;
status.timer3 = 0;
status.timer4 = 0;
status.p15 = 0;
status.p14 = 0;
status.joyp = 0;
status.mlt_req = 0;
status.serial_data = 0;
status.serial_bits = 0;
status.serial_transfer = 0;
status.serial_clock = 0;
status.div = 0;
status.tima = 0;
status.tma = 0;
status.timer_enable = 0;
status.timer_clock = 0;
status.interrupt_request_joypad = 0;
status.interrupt_request_serial = 0;
status.interrupt_request_timer = 0;
status.interrupt_request_stat = 0;
status.interrupt_request_vblank = 0;
status.interrupt_enable_joypad = 0;
status.interrupt_enable_serial = 0;
status.interrupt_enable_timer = 0;
status.interrupt_enable_stat = 0;
status.interrupt_enable_vblank = 0;
}
CPU::CPU() : trace(false) {
initialize_opcode_table();
}
}
-84
View File
@@ -1,84 +0,0 @@
struct CPU : Processor, MMIO {
#include "core/core.hpp"
#include "mmio/mmio.hpp"
#include "timing/timing.hpp"
bool trace;
enum class Interrupt : unsigned {
Vblank,
Stat,
Timer,
Serial,
Joypad,
};
struct Status {
unsigned clock;
bool halt;
bool stop;
bool ime;
unsigned timer0;
unsigned timer1;
unsigned timer2;
unsigned timer3;
unsigned timer4;
//$ff00 JOYP
bool p15;
bool p14;
uint8 joyp;
uint8 mlt_req;
//$ff01 SB
uint8 serial_data;
unsigned serial_bits;
//$ff02 SC
bool serial_transfer;
bool serial_clock;
//$ff04 DIV
uint8 div;
//$ff05 TIMA
uint8 tima;
//$ff06 TMA
uint8 tma;
//$ff07 TAC
bool timer_enable;
unsigned timer_clock;
//$ff0f IF
bool interrupt_request_joypad;
bool interrupt_request_serial;
bool interrupt_request_timer;
bool interrupt_request_stat;
bool interrupt_request_vblank;
//$ffff IE
bool interrupt_enable_joypad;
bool interrupt_enable_serial;
bool interrupt_enable_timer;
bool interrupt_enable_stat;
bool interrupt_enable_vblank;
} status;
uint8 wram[8192];
uint8 hram[128];
static void Main();
void main();
void interrupt_raise(Interrupt id);
void interrupt_test();
void interrupt_exec(uint16 pc);
void power();
void serialize(serializer&);
CPU();
};
extern CPU cpu;
-144
View File
@@ -1,144 +0,0 @@
#ifdef CPU_CPP
void CPU::mmio_joyp_poll() {
unsigned button = 0, dpad = 0;
button |= system.interface->input_poll((unsigned)Input::Start) << 3;
button |= system.interface->input_poll((unsigned)Input::Select) << 2;
button |= system.interface->input_poll((unsigned)Input::B) << 1;
button |= system.interface->input_poll((unsigned)Input::A) << 0;
dpad |= system.interface->input_poll((unsigned)Input::Down) << 3;
dpad |= system.interface->input_poll((unsigned)Input::Up) << 2;
dpad |= system.interface->input_poll((unsigned)Input::Left) << 1;
dpad |= system.interface->input_poll((unsigned)Input::Right) << 0;
status.joyp = 0x0f;
if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mlt_req;
if(status.p15 == 0) status.joyp &= button ^ 0x0f;
if(status.p14 == 0) status.joyp &= dpad ^ 0x0f;
if(status.joyp != 0x0f) interrupt_raise(Interrupt::Joypad);
}
uint8 CPU::mmio_read(uint16 addr) {
if(addr >= 0xc000 && addr <= 0xdfff) return wram[addr & 0x1fff];
if(addr >= 0xe000 && addr <= 0xfdff) return wram[addr & 0x1fff];
if(addr >= 0xff80 && addr <= 0xfffe) return hram[addr & 0x7f];
if(addr == 0xff00) { //JOYP
return (status.p15 << 5)
| (status.p14 << 4)
| (status.joyp << 0);
}
if(addr == 0xff01) { //SB
return 0xff;
}
if(addr == 0xff02) { //SC
return (status.serial_transfer << 7)
| (status.serial_clock << 0);
}
if(addr == 0xff04) { //DIV
return status.div;
}
if(addr == 0xff05) { //TIMA
return status.tima;
}
if(addr == 0xff06) { //TMA
return status.tma;
}
if(addr == 0xff07) { //TAC
return (status.timer_enable << 2)
| (status.timer_clock << 0);
}
if(addr == 0xff0f) { //IF
return (status.interrupt_request_joypad << 4)
| (status.interrupt_request_serial << 3)
| (status.interrupt_request_timer << 2)
| (status.interrupt_request_stat << 1)
| (status.interrupt_request_vblank << 0);
}
if(addr == 0xffff) { //IE
return (status.interrupt_enable_joypad << 4)
| (status.interrupt_enable_serial << 3)
| (status.interrupt_enable_timer << 2)
| (status.interrupt_enable_stat << 1)
| (status.interrupt_enable_vblank << 0);
}
return 0x00;
}
void CPU::mmio_write(uint16 addr, uint8 data) {
if(addr >= 0xc000 && addr <= 0xdfff) { wram[addr & 0x1fff] = data; return; }
if(addr >= 0xe000 && addr <= 0xfdff) { wram[addr & 0x1fff] = data; return; }
if(addr >= 0xff80 && addr <= 0xfffe) { hram[addr & 0x7f] = data; return; }
if(addr == 0xff00) { //JOYP
status.p15 = data & 0x20;
status.p14 = data & 0x10;
system.interface->joyp_write(status.p15, status.p14);
mmio_joyp_poll();
return;
}
if(addr == 0xff01) { //SB
status.serial_data = data;
return;
}
if(addr == 0xff02) { //SC
status.serial_transfer = data & 0x80;
status.serial_clock = data & 0x01;
if(status.serial_transfer) status.serial_bits = 8;
return;
}
if(addr == 0xff04) { //DIV
status.div = 0;
return;
}
if(addr == 0xff05) { //TIMA
status.tima = data;
return;
}
if(addr == 0xff06) { //TMA
status.tma = data;
return;
}
if(addr == 0xff07) { //TAC
status.timer_enable = data & 0x04;
status.timer_clock = data & 0x03;
return;
}
if(addr == 0xff0f) { //IF
status.interrupt_request_joypad = data & 0x10;
status.interrupt_request_serial = data & 0x08;
status.interrupt_request_timer = data & 0x04;
status.interrupt_request_stat = data & 0x02;
status.interrupt_request_vblank = data & 0x01;
return;
}
if(addr == 0xffff) { //IE
status.interrupt_enable_joypad = data & 0x10;
status.interrupt_enable_serial = data & 0x08;
status.interrupt_enable_timer = data & 0x04;
status.interrupt_enable_stat = data & 0x02;
status.interrupt_enable_vblank = data & 0x01;
return;
}
}
#endif
-3
View File
@@ -1,3 +0,0 @@
void mmio_joyp_poll();
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
-62
View File
@@ -1,62 +0,0 @@
#ifdef CPU_CPP
void CPU::serialize(serializer &s) {
s.array(wram);
s.array(hram);
s.integer(r.a.data);
s.integer(r.f.z);
s.integer(r.f.n);
s.integer(r.f.h);
s.integer(r.f.c);
s.integer(r.b.data);
s.integer(r.c.data);
s.integer(r.d.data);
s.integer(r.e.data);
s.integer(r.h.data);
s.integer(r.l.data);
s.integer(r.sp.data);
s.integer(r.pc.data);
s.integer(status.clock);
s.integer(status.halt);
s.integer(status.stop);
s.integer(status.ime);
s.integer(status.timer0);
s.integer(status.timer1);
s.integer(status.timer2);
s.integer(status.timer3);
s.integer(status.timer4);
s.integer(status.p15);
s.integer(status.p14);
s.integer(status.joyp);
s.integer(status.mlt_req);
s.integer(status.serial_data);
s.integer(status.serial_bits);
s.integer(status.serial_transfer);
s.integer(status.serial_clock);
s.integer(status.div);
s.integer(status.tima);
s.integer(status.tma);
s.integer(status.timer_enable);
s.integer(status.timer_clock);
s.integer(status.interrupt_request_joypad);
s.integer(status.interrupt_request_serial);
s.integer(status.interrupt_request_timer);
s.integer(status.interrupt_request_stat);
s.integer(status.interrupt_request_vblank);
s.integer(status.interrupt_enable_joypad);
s.integer(status.interrupt_enable_serial);
s.integer(status.interrupt_enable_timer);
s.integer(status.interrupt_enable_stat);
s.integer(status.interrupt_enable_vblank);
}
#endif
-18
View File
@@ -1,18 +0,0 @@
#ifdef CPU_CPP
void CPU::op_io() {
add_clocks(4);
}
uint8 CPU::op_read(uint16 addr) {
uint8 r = bus.read(addr);
add_clocks(4);
return r;
}
void CPU::op_write(uint16 addr, uint8 data) {
bus.write(addr, data);
add_clocks(4);
}
#endif
-93
View File
@@ -1,93 +0,0 @@
//4194304hz (4 * 1024 * 1024)
//70224 clocks/frame
// 456 clocks/scanline
// 154 scanlines/frame
//4194304 / 4096 = 1024
//4194304 / 262144 = 16
//4194304 / 65536 = 64
//4394304 / 16384 = 256
#ifdef CPU_CPP
#include "opcode.cpp"
void CPU::add_clocks(unsigned clocks) {
system.clocks_executed += clocks;
scheduler.exit(Scheduler::ExitReason::StepEvent);
status.clock += clocks;
if(status.clock >= 4 * 1024 * 1024) {
status.clock -= 4 * 1024 * 1024;
cartridge.mbc3.second();
}
status.timer0 += clocks;
if(status.timer0 >= 16) timer_stage0();
cpu.clock += clocks;
if(cpu.clock >= 0) co_switch(scheduler.active_thread = lcd.thread);
}
void CPU::timer_stage0() { //262144hz
if(status.timer_enable && status.timer_clock == 1) {
if(++status.tima == 0) {
status.tima = status.tma;
interrupt_raise(Interrupt::Timer);
}
}
status.timer0 -= 16;
if(++status.timer1 >= 4) timer_stage1();
}
void CPU::timer_stage1() { // 65536hz
if(status.timer_enable && status.timer_clock == 2) {
if(++status.tima == 0) {
status.tima = status.tma;
interrupt_raise(Interrupt::Timer);
}
}
status.timer1 -= 4;
if(++status.timer2 >= 4) timer_stage2();
}
void CPU::timer_stage2() { // 16384hz
if(status.timer_enable && status.timer_clock == 3) {
if(++status.tima == 0) {
status.tima = status.tma;
interrupt_raise(Interrupt::Timer);
}
}
status.div++;
status.timer2 -= 4;
if(++status.timer3 >= 2) timer_stage3();
}
void CPU::timer_stage3() { // 8192hz
if(status.serial_transfer && status.serial_clock) {
if(--status.serial_bits == 0) {
status.serial_transfer = 0;
interrupt_raise(Interrupt::Serial);
}
}
status.timer3 -= 2;
if(++status.timer4 >= 2) timer_stage4();
}
void CPU::timer_stage4() { // 4096hz
if(status.timer_enable && status.timer_clock == 0) {
if(++status.tima == 0) {
status.tima = status.tma;
interrupt_raise(Interrupt::Timer);
}
}
status.timer4 -= 2;
}
#endif
-11
View File
@@ -1,11 +0,0 @@
void add_clocks(unsigned clocks);
void timer_stage0();
void timer_stage1();
void timer_stage2();
void timer_stage3();
void timer_stage4();
//opcode.cpp
void op_io();
uint8 op_read(uint16 addr);
void op_write(uint16 addr, uint8 data);
-62
View File
@@ -1,62 +0,0 @@
//bgameboy
//author: byuu
//project started: 2010-12-27
namespace GameBoy {
namespace Info {
static const char Name[] = "bgameboy";
static const char Version[] = "000.13";
static unsigned SerializerVersion = 1;
}
}
#include <libco/libco.h>
#include <nall/foreach.hpp>
#include <nall/platform.hpp>
#include <nall/property.hpp>
#include <nall/serializer.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
using namespace nall;
namespace GameBoy {
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
template<uint16 lo, uint16 hi>
alwaysinline bool within(uint16 addr) {
static const uint16 mask = ~(hi ^ lo);
return (addr & mask) == lo;
}
struct Processor {
cothread_t thread;
unsigned frequency;
int64 clock;
inline void create(void (*entrypoint_)(), unsigned frequency_) {
if(thread) co_delete(thread);
thread = co_create(65536 * sizeof(void*), entrypoint_);
frequency = frequency_;
clock = 0;
}
inline Processor() : thread(0) {}
};
#include <gameboy/memory/memory.hpp>
#include <gameboy/system/system.hpp>
#include <gameboy/scheduler/scheduler.hpp>
#include <gameboy/cartridge/cartridge.hpp>
#include <gameboy/cpu/cpu.hpp>
#include <gameboy/apu/apu.hpp>
#include <gameboy/lcd/lcd.hpp>
};
-11
View File
@@ -1,11 +0,0 @@
class Interface {
public:
virtual void joyp_write(bool p15, bool p14) {}
virtual void video_refresh(const uint8_t *data) {}
virtual void audio_sample(signed left, signed right) {}
virtual void input_poll() {}
virtual bool input_poll(unsigned id) {}
virtual void message(const string &text) { print(text, "\n"); }
};
-238
View File
@@ -1,238 +0,0 @@
#include <gameboy/gameboy.hpp>
#define LCD_CPP
namespace GameBoy {
#include "mmio/mmio.cpp"
#include "serialization.cpp"
LCD lcd;
void LCD::Main() {
lcd.main();
}
void LCD::main() {
while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
}
add_clocks(4);
if(status.lx == 0) {
if(status.interrupt_oam) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
if(status.lx == 252) {
if(status.interrupt_hblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
}
}
void LCD::add_clocks(unsigned clocks) {
status.lx += clocks;
if(status.lx >= 456) scanline();
cpu.clock -= clocks;
if(cpu.clock <= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) {
co_switch(scheduler.active_thread = cpu.thread);
}
}
void LCD::scanline() {
status.lx -= 456;
if(++status.ly == 154) frame();
if(status.interrupt_lyc == true) {
if(status.ly == status.lyc) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
if(status.ly < 144) render();
if(status.ly == 144) {
cpu.interrupt_raise(CPU::Interrupt::Vblank);
if(status.interrupt_vblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
}
void LCD::frame() {
system.interface->video_refresh(screen);
system.interface->input_poll();
cpu.mmio_joyp_poll();
status.ly = 0;
scheduler.exit(Scheduler::ExitReason::FrameEvent);
}
void LCD::render() {
for(unsigned n = 0; n < 160; n++) line[n] = 0x00;
if(status.display_enable == true) {
if(status.bg_enable == true) render_bg();
if(status.window_display_enable == true) render_window();
if(status.obj_enable == true) render_obj();
}
uint8_t *output = screen + status.ly * 160;
for(unsigned n = 0; n < 160; n++) output[n] = (3 - line[n]) * 0x55;
}
uint16 LCD::read_tile(bool select, unsigned x, unsigned y) {
unsigned tmaddr = 0x1800 + (select << 10), tdaddr;
tmaddr += (((y >> 3) << 5) + (x >> 3)) & 0x03ff;
if(status.bg_tiledata_select == 0) {
tdaddr = 0x1000 + ((int8)vram[tmaddr] << 4);
} else {
tdaddr = 0x0000 + (vram[tmaddr] << 4);
}
tdaddr += (y & 7) << 1;
return (vram[tdaddr + 0] << 0) | (vram[tdaddr + 1] << 8);
}
void LCD::render_bg() {
unsigned iy = (status.ly + status.scy) & 255;
unsigned ix = status.scx, tx = ix & 7;
unsigned data = read_tile(status.bg_tilemap_select, ix, iy);
for(unsigned ox = 0; ox < 160; ox++) {
uint8 palette = ((data & (0x0080 >> tx)) ? 1 : 0)
| ((data & (0x8000 >> tx)) ? 2 : 0);
line[ox] = status.bgp[palette];
ix = (ix + 1) & 255;
tx = (tx + 1) & 7;
if(tx == 0) data = read_tile(status.bg_tilemap_select, ix, iy);
}
}
void LCD::render_window() {
if(status.ly - status.wy >= 144U) return;
unsigned iy = status.ly - status.wy;
unsigned ix = (status.wx - 7) & 255, tx = ix & 7;
unsigned data = read_tile(status.window_tilemap_select, ix, iy);
for(unsigned ox = 0; ox < 160; ox++) {
uint8 palette = ((data & (0x0080 >> tx)) ? 1 : 0)
| ((data & (0x8000 >> tx)) ? 2 : 0);
if(ox - (status.wx - 7) < 160U) line[ox] = status.bgp[palette];
ix = (ix + 1) & 255;
tx = (tx + 1) & 7;
if(tx == 0) data = read_tile(status.window_tilemap_select, ix, iy);
}
}
void LCD::render_obj() {
unsigned obj_size = (status.obj_size == 0 ? 8 : 16);
unsigned sprite[10], sprites = 0;
//find first ten sprites on this scanline
for(unsigned s = 0; s < 40; s++) {
unsigned sy = oam[(s << 2) + 0] - 16;
unsigned sx = oam[(s << 2) + 1] - 8;
sy = status.ly - sy;
if(sy >= obj_size) continue;
sprite[sprites++] = s;
if(sprites == 10) break;
}
//sort by X-coordinate, when equal, lower address comes first
for(unsigned x = 0; x < sprites; x++) {
for(unsigned y = x + 1; y < sprites; y++) {
signed sx = oam[(sprite[x] << 2) + 1] - 8;
signed sy = oam[(sprite[y] << 2) + 1] - 8;
if(sy < sx) {
sprite[x] ^= sprite[y];
sprite[y] ^= sprite[x];
sprite[x] ^= sprite[y];
}
}
}
//render backwards, so that first sprite has highest priority
for(signed s = sprites - 1; s >= 0; s--) {
unsigned n = sprite[s] << 2;
unsigned sy = oam[n + 0] - 16;
unsigned sx = oam[n + 1] - 8;
unsigned tile = oam[n + 2];
unsigned attribute = oam[n + 3];
sy = status.ly - sy;
if(sy >= obj_size) continue;
if(attribute & 0x40) sy ^= (obj_size - 1);
unsigned tdaddr = (tile << 4) + (sy << 1);
uint8 d0 = vram[tdaddr + 0];
uint8 d1 = vram[tdaddr + 1];
unsigned xflip = attribute & 0x20 ? 7 : 0;
for(unsigned tx = 0; tx < 8; tx++) {
uint8 palette = ((d0 & (0x80 >> tx)) ? 1 : 0)
| ((d1 & (0x80 >> tx)) ? 2 : 0);
if(palette == 0) continue;
palette = status.obp[(bool)(attribute & 0x10)][palette];
unsigned ox = sx + (tx ^ xflip);
if(ox <= 159) {
if(attribute & 0x80) {
if(line[ox] > 0) continue;
}
line[ox] = palette;
}
}
}
}
void LCD::power() {
create(Main, 4 * 1024 * 1024);
for(unsigned n = 0x8000; n <= 0x9fff; n++) bus.mmio[n] = this; //VRAM
for(unsigned n = 0xff40; n <= 0xff4b; n++) bus.mmio[n] = this; //MMIO
for(unsigned n = 0xfe00; n <= 0xfe9f; n++) bus.mmio[n] = this; //OAM
for(unsigned n = 0; n < 8192; n++) vram[n] = 0x00;
for(unsigned n = 0; n < 160; n++) oam [n] = 0x00;
for(unsigned n = 0; n < 160 * 144; n++) screen[n] = 0x00;
status.lx = 0;
status.display_enable = 0;
status.window_tilemap_select = 0;
status.window_display_enable = 0;
status.bg_tiledata_select = 0;
status.bg_tilemap_select = 0;
status.obj_size = 0;
status.obj_enable = 0;
status.bg_enable = 0;
status.interrupt_lyc = 0;
status.interrupt_oam = 0;
status.interrupt_vblank = 0;
status.interrupt_hblank = 0;
status.scy = 0;
status.scx = 0;
status.ly = 0;
status.lyc = 0;
for(unsigned n = 0; n < 4; n++) {
status.bgp[n] = n;
status.obp[0][n] = n;
status.obp[1][n] = n;
}
status.wy = 0;
status.wx = 0;
}
LCD::LCD() {
}
}
-71
View File
@@ -1,71 +0,0 @@
struct LCD : Processor, MMIO {
#include "mmio/mmio.hpp"
struct Status {
unsigned lx;
//$ff40 LCDC
bool display_enable;
bool window_tilemap_select;
bool window_display_enable;
bool bg_tiledata_select;
bool bg_tilemap_select;
bool obj_size;
bool obj_enable;
bool bg_enable;
//$ff41 STAT
bool interrupt_lyc;
bool interrupt_oam;
bool interrupt_vblank;
bool interrupt_hblank;
//$ff42 SCY
uint8 scy;
//$ff43 SCX
uint8 scx;
//$ff44 LY
uint8 ly;
//$ff45 LYC
uint8 lyc;
//$ff47 BGP
uint8 bgp[4];
//$ff48 OBP0
//$ff49 OBP1
uint8 obp[2][4];
//$ff4a WY
uint8 wy;
//$ff4b WX
uint8 wx;
} status;
uint8 screen[160 * 144];
uint8 vram[8192];
uint8 oam[160];
uint8 line[160];
static void Main();
void main();
void add_clocks(unsigned clocks);
void scanline();
void frame();
void render();
uint16 read_tile(bool select, unsigned x, unsigned y);
void render_bg();
void render_window();
void render_obj();
void power();
void serialize(serializer&);
LCD();
};
extern LCD lcd;
-165
View File
@@ -1,165 +0,0 @@
#ifdef LCD_CPP
uint8 LCD::mmio_read(uint16 addr) {
if(addr >= 0x8000 && addr <= 0x9fff) return vram[addr & 0x1fff];
if(addr >= 0xfe00 && addr <= 0xfe9f) return oam[addr & 0xff];
if(addr == 0xff40) { //LCDC
return (status.display_enable << 7)
| (status.window_tilemap_select << 6)
| (status.window_display_enable << 5)
| (status.bg_tiledata_select << 4)
| (status.bg_tilemap_select << 3)
| (status.obj_size << 2)
| (status.obj_enable << 1)
| (status.bg_enable << 0);
}
if(addr == 0xff41) { //STAT
unsigned mode;
if(status.ly >= 144) mode = 1; //Vblank
else if(status.lx < 80) mode = 2; //OAM
else if(status.lx < 252) mode = 3; //LCD
else mode = 0; //Hblank
return (status.interrupt_lyc << 6)
| (status.interrupt_oam << 5)
| (status.interrupt_vblank << 4)
| (status.interrupt_hblank << 3)
| ((status.ly == status.lyc) << 2)
| (mode << 0);
}
if(addr == 0xff42) { //SCY
return status.scy;
}
if(addr == 0xff43) { //SCX
return status.scx;
}
if(addr == 0xff44) { //LY
return status.ly;
}
if(addr == 0xff45) { //LYC
return status.lyc;
}
if(addr == 0xff47) { //BGP
return (status.bgp[3] << 6)
| (status.bgp[2] << 4)
| (status.bgp[1] << 2)
| (status.bgp[0] << 0);
}
if(addr == 0xff48) { //OBP0
return (status.obp[0][3] << 6)
| (status.obp[0][2] << 4)
| (status.obp[0][1] << 2)
| (status.obp[0][0] << 0);
}
if(addr == 0xff49) { //OBP1
return (status.obp[1][3] << 6)
| (status.obp[1][2] << 4)
| (status.obp[1][1] << 2)
| (status.obp[1][0] << 0);
}
if(addr == 0xff4a) { //WY
return status.wy;
}
if(addr == 0xff4b) { //WX
return status.wx;
}
return 0x00;
}
void LCD::mmio_write(uint16 addr, uint8 data) {
if(addr >= 0x8000 && addr <= 0x9fff) { vram[addr & 0x1fff] = data; return; }
if(addr >= 0xfe00 && addr <= 0xfe9f) { oam[addr & 0xff] = data; return; }
if(addr == 0xff40) { //LCDC
status.display_enable = data & 0x80;
status.window_tilemap_select = data & 0x40;
status.window_display_enable = data & 0x20;
status.bg_tiledata_select = data & 0x10;
status.bg_tilemap_select = data & 0x08;
status.obj_size = data & 0x04;
status.obj_enable = data & 0x02;
status.bg_enable = data & 0x01;
return;
}
if(addr == 0xff41) { //STAT
status.interrupt_lyc = data & 0x40;
status.interrupt_oam = data & 0x20;
status.interrupt_vblank = data & 0x10;
status.interrupt_hblank = data & 0x08;
return;
}
if(addr == 0xff42) { //SCY
status.scy = data;
return;
}
if(addr == 0xff43) { //SCX
status.scx = data;
return;
}
if(addr == 0xff44) { //LY
status.ly = 0;
return;
}
if(addr == 0xff45) { //LYC
status.lyc = data;
return;
}
if(addr == 0xff46) { //DMA
for(unsigned n = 0x00; n <= 0x9f; n++) bus.write(0xfe00 + n, bus.read((data << 8) + n));
return;
}
if(addr == 0xff47) { //BGP
status.bgp[3] = (data >> 6) & 3;
status.bgp[2] = (data >> 4) & 3;
status.bgp[1] = (data >> 2) & 3;
status.bgp[0] = (data >> 0) & 3;
return;
}
if(addr == 0xff48) { //OBP0
status.obp[0][3] = (data >> 6) & 3;
status.obp[0][2] = (data >> 4) & 3;
status.obp[0][1] = (data >> 2) & 3;
status.obp[0][0] = (data >> 0) & 3;
return;
}
if(addr == 0xff49) { //OBP1
status.obp[1][3] = (data >> 6) & 3;
status.obp[1][2] = (data >> 4) & 3;
status.obp[1][1] = (data >> 2) & 3;
status.obp[1][0] = (data >> 0) & 3;
return;
}
if(addr == 0xff4a) { //WY
status.wy = data;
return;
}
if(addr == 0xff4b) { //WX
status.wx = data;
return;
}
}
#endif
-2
View File
@@ -1,2 +0,0 @@
uint8 mmio_read(uint16 addr);
void mmio_write(uint16 addr, uint8 data);
-38
View File
@@ -1,38 +0,0 @@
#ifdef LCD_CPP
void LCD::serialize(serializer &s) {
s.integer(status.lx);
s.integer(status.display_enable);
s.integer(status.window_tilemap_select);
s.integer(status.window_display_enable);
s.integer(status.bg_tiledata_select);
s.integer(status.bg_tilemap_select);
s.integer(status.obj_size);
s.integer(status.obj_enable);
s.integer(status.bg_enable);
s.integer(status.interrupt_lyc);
s.integer(status.interrupt_oam);
s.integer(status.interrupt_vblank);
s.integer(status.interrupt_hblank);
s.integer(status.scy);
s.integer(status.scx);
s.integer(status.ly);
s.integer(status.lyc);
s.array(status.bgp);
s.array(status.obp[0]);
s.array(status.obp[1]);
s.integer(status.wy);
s.integer(status.wx);
s.array(screen);
s.array(vram);
s.array(oam);
s.array(line);
}
#endif
-56
View File
@@ -1,56 +0,0 @@
#include <gameboy/gameboy.hpp>
#define MEMORY_CPP
namespace GameBoy {
Unmapped unmapped;
Bus bus;
uint8_t& Memory::operator[](unsigned addr) {
return data[addr];
}
void Memory::allocate(unsigned size_) {
free();
size = size_;
data = new uint8_t[size]();
}
void Memory::copy(const uint8_t *data_, unsigned size_) {
free();
size = size_;
data = new uint8_t[size];
memcpy(data, data_, size);
}
void Memory::free() {
if(data) {
delete[] data;
data = 0;
}
}
Memory::Memory() {
data = 0;
size = 0;
}
Memory::~Memory() {
free();
}
//
uint8 Bus::read(uint16 addr) {
return mmio[addr]->mmio_read(addr);
}
void Bus::write(uint16 addr, uint8 data) {
mmio[addr]->mmio_write(addr, data);
}
void Bus::power() {
for(unsigned n = 0; n < 65536; n++) mmio[n] = &unmapped;
}
}
-32
View File
@@ -1,32 +0,0 @@
struct Memory {
uint8_t *data;
unsigned size;
uint8_t& operator[](unsigned addr);
void allocate(unsigned size);
void copy(const uint8_t *data, unsigned size);
void free();
Memory();
~Memory();
};
struct MMIO {
virtual uint8 mmio_read(uint16 addr) = 0;
virtual void mmio_write(uint16 addr, uint8 data) = 0;
};
struct Unmapped : MMIO {
uint8 mmio_read(uint16) { return 0x00; }
void mmio_write(uint16, uint8) {}
};
struct Bus {
MMIO *mmio[65536];
uint8 read(uint16 addr);
void write(uint16 addr, uint8 data);
void power();
};
extern Unmapped unmapped;
extern Bus bus;
-35
View File
@@ -1,35 +0,0 @@
#include <gameboy/gameboy.hpp>
#define SCHEDULER_CPP
namespace GameBoy {
Scheduler scheduler;
void Scheduler::enter() {
host_thread = co_active();
co_switch(active_thread);
}
void Scheduler::exit(ExitReason reason) {
exit_reason = reason;
active_thread = co_active();
co_switch(host_thread);
}
void Scheduler::swapto(Processor &p) {
active_thread = p.thread;
co_switch(active_thread);
}
void Scheduler::init() {
host_thread = co_active();
active_thread = cpu.thread;
}
Scheduler::Scheduler() {
exit_reason = ExitReason::UnknownEvent;
host_thread = 0;
active_thread = 0;
}
}
-17
View File
@@ -1,17 +0,0 @@
struct Scheduler : property<Scheduler> {
enum class SynchronizeMode : unsigned { None, CPU, All } sync;
enum class ExitReason : unsigned { UnknownEvent, StepEvent, FrameEvent, SynchronizeEvent };
readonly<ExitReason> exit_reason;
cothread_t host_thread;
cothread_t active_thread;
void enter();
void exit(ExitReason);
void swapto(Processor&);
void init();
Scheduler();
};
extern Scheduler scheduler;
-23
View File
@@ -1,23 +0,0 @@
#ifdef SYSTEM_CPP
//MD5SUM = 32fbbd84168d3482956eb3c5051637f5
const uint8_t System::BootROM::dmg[256] = {
0x31,0xfe,0xff,0xaf,0x21,0xff,0x9f,0x32,0xcb,0x7c,0x20,0xfb,0x21,0x26,0xff,0x0e,
0x11,0x3e,0x80,0x32,0xe2,0x0c,0x3e,0xf3,0xe2,0x32,0x3e,0x77,0x77,0x3e,0xfc,0xe0,
0x47,0x11,0x04,0x01,0x21,0x10,0x80,0x1a,0xcd,0x95,0x00,0xcd,0x96,0x00,0x13,0x7b,
0xfe,0x34,0x20,0xf3,0x11,0xd8,0x00,0x06,0x08,0x1a,0x13,0x22,0x23,0x05,0x20,0xf9,
0x3e,0x19,0xea,0x10,0x99,0x21,0x2f,0x99,0x0e,0x0c,0x3d,0x28,0x08,0x32,0x0d,0x20,
0xf9,0x2e,0x0f,0x18,0xf3,0x67,0x3e,0x64,0x57,0xe0,0x42,0x3e,0x91,0xe0,0x40,0x04,
0x1e,0x02,0x0e,0x0c,0xf0,0x44,0xfe,0x90,0x20,0xfa,0x0d,0x20,0xf7,0x1d,0x20,0xf2,
0x0e,0x13,0x24,0x7c,0x1e,0x83,0xfe,0x62,0x28,0x06,0x1e,0xc1,0xfe,0x64,0x20,0x06,
0x7b,0xe2,0x0c,0x3e,0x87,0xe2,0xf0,0x42,0x90,0xe0,0x42,0x15,0x20,0xd2,0x05,0x20,
0x4f,0x16,0x20,0x18,0xcb,0x4f,0x06,0x04,0xc5,0xcb,0x11,0x17,0xc1,0xcb,0x11,0x17,
0x05,0x20,0xf5,0x22,0x23,0x22,0x23,0xc9,0xce,0xed,0x66,0x66,0xcc,0x0d,0x00,0x0b,
0x03,0x73,0x00,0x83,0x00,0x0c,0x00,0x0d,0x00,0x08,0x11,0x1f,0x88,0x89,0x00,0x0e,
0xdc,0xcc,0x6e,0xe6,0xdd,0xdd,0xd9,0x99,0xbb,0xbb,0x67,0x63,0x6e,0x0e,0xec,0xcc,
0xdd,0xdc,0x99,0x9f,0xbb,0xb9,0x33,0x3e,0x3c,0x42,0xb9,0xa5,0xb9,0xa5,0x42,0x3c,
0x21,0x04,0x01,0x11,0xa8,0x00,0x1a,0x13,0xbe,0x20,0xfe,0x23,0x7d,0xfe,0x34,0x20,
0xf5,0x06,0x19,0x78,0x86,0x23,0x05,0x20,0xfb,0x86,0x20,0xfe,0x3e,0x01,0xe0,0x50,
};
#endif
-23
View File
@@ -1,23 +0,0 @@
#ifdef SYSTEM_CPP
//MD5SUM = d574d4f9c12f305074798f54c091a8b4
const uint8_t System::BootROM::sgb[256] = {
0x31,0xfe,0xff,0x3e,0x30,0xe0,0x00,0xaf,0x21,0xff,0x9f,0x32,0xcb,0x7c,0x20,0xfb,
0x21,0x26,0xff,0x0e,0x11,0x3e,0x80,0x32,0xe2,0x0c,0x3e,0xf3,0xe2,0x32,0x3e,0x77,
0x77,0x3e,0xfc,0xe0,0x47,0x21,0x5f,0xc0,0x0e,0x08,0xaf,0x32,0x0d,0x20,0xfc,0x11,
0x4f,0x01,0x3e,0xfb,0x0e,0x06,0xf5,0x06,0x00,0x1a,0x1b,0x32,0x80,0x47,0x0d,0x20,
0xf8,0x32,0xf1,0x32,0x0e,0x0e,0xd6,0x02,0xfe,0xef,0x20,0xea,0x11,0x04,0x01,0x21,
0x10,0x80,0x1a,0xcd,0xd3,0x00,0xcd,0xd4,0x00,0x13,0x7b,0xfe,0x34,0x20,0xf3,0x11,
0xe6,0x00,0x06,0x08,0x1a,0x13,0x22,0x23,0x05,0x20,0xf9,0x3e,0x19,0xea,0x10,0x99,
0x21,0x2f,0x99,0x0e,0x0c,0x3d,0x28,0x08,0x32,0x0d,0x20,0xf9,0x2e,0x0f,0x18,0xf3,
0x3e,0x91,0xe0,0x40,0x21,0x00,0xc0,0x0e,0x00,0x3e,0x00,0xe2,0x3e,0x30,0xe2,0x06,
0x10,0x1e,0x08,0x2a,0x57,0xcb,0x42,0x3e,0x10,0x20,0x02,0x3e,0x20,0xe2,0x3e,0x30,
0xe2,0xcb,0x1a,0x1d,0x20,0xef,0x05,0x20,0xe8,0x3e,0x20,0xe2,0x3e,0x30,0xe2,0xcd,
0xc2,0x00,0x7d,0xfe,0x60,0x20,0xd2,0x0e,0x13,0x3e,0xc1,0xe2,0x0c,0x3e,0x07,0xe2,
0x18,0x3a,0x16,0x04,0xf0,0x44,0xfe,0x90,0x20,0xfa,0x1e,0x00,0x1d,0x20,0xfd,0x15,
0x20,0xf2,0xc9,0x4f,0x06,0x04,0xc5,0xcb,0x11,0x17,0xc1,0xcb,0x11,0x17,0x05,0x20,
0xf5,0x22,0x23,0x22,0x23,0xc9,0x3c,0x42,0xb9,0xa5,0xb9,0xa5,0x42,0x3c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x01,0xe0,0x50,
};
#endif
-63
View File
@@ -1,63 +0,0 @@
#ifdef SYSTEM_CPP
serializer System::serialize() {
serializer s(serialize_size);
unsigned signature = 0x31545342, version = Info::SerializerVersion, crc32 = 0;
char description[512];
memset(&description, 0, sizeof description);
s.integer(signature);
s.integer(version);
s.integer(crc32);
s.array(description);
serialize_all(s);
return s;
}
bool System::unserialize(serializer &s) {
unsigned signature, version, crc32;
char description[512];
s.integer(signature);
s.integer(version);
s.integer(crc32);
s.array(description);
if(signature != 0x31545342) return false;
if(version != Info::SerializerVersion) return false;
//if(crc32 != 0) return false;
serialize_all(s);
return true;
}
void System::serialize(serializer &s) {
s.integer(clocks_executed);
}
void System::serialize_all(serializer &s) {
cartridge.serialize(s);
system.serialize(s);
cpu.serialize(s);
apu.serialize(s);
lcd.serialize(s);
}
void System::serialize_init() {
serializer s;
unsigned signature = 0, version = 0, crc32 = 0;
char description[512];
s.integer(signature);
s.integer(version);
s.integer(crc32);
s.array(description);
serialize_all(s);
serialize_size = s.size();
}
#endif
-68
View File
@@ -1,68 +0,0 @@
#include <gameboy/gameboy.hpp>
#define SYSTEM_CPP
namespace GameBoy {
#include "bootrom-dmg.cpp"
#include "bootrom-sgb.cpp"
#include "serialization.cpp"
System system;
void System::run() {
scheduler.sync = Scheduler::SynchronizeMode::None;
scheduler.enter();
if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) {
}
}
void System::runtosave() {
scheduler.sync = Scheduler::SynchronizeMode::CPU;
runthreadtosave();
scheduler.active_thread = lcd.thread;
runthreadtosave();
}
void System::runthreadtosave() {
while(true) {
scheduler.enter();
if(scheduler.exit_reason() == Scheduler::ExitReason::SynchronizeEvent) break;
if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) {
}
}
}
uint8 System::mmio_read(uint16 addr) {
if((addr & 0xff00) == 0x0000) {
return BootROM::sgb[addr];
}
return 0x00;
}
void System::mmio_write(uint16 addr, uint8 data) {
if(addr == 0xff50) {
if(data == 0x01) cartridge.map();
}
}
void System::init(Interface *interface_) {
interface = interface_;
}
void System::power() {
bus.power();
cartridge.power();
cpu.power();
apu.power();
lcd.power();
scheduler.init();
for(unsigned n = 0x0000; n <= 0x00ff; n++) bus.mmio[n] = this;
bus.mmio[0xff50] = this;
clocks_executed = 0;
serialize_init();
}
}
Loaded 100 of 902 files, more files were not shown because too many files have changed in this diff. Show more