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
1168 changed files with 19155 additions and 208427 deletions

No files matched your search

Executable → Regular
+43 -95
View File
@@ -1,95 +1,43 @@
include nall/Makefile
snes := snes
profile := accuracy
ui := ui-phoenix
# compiler
c := $(compiler) -std=gnu99
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
flags := -O3 -fomit-frame-pointer -I. -I$(snes)
link :=
objects :=
# 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;
include $(snes)/Makefile
include $(ui)/Makefile
objects := $(patsubst %,obj/%.o,$(objects))
# targets
build: ui_build $(objects)
ifeq ($(platform),osx)
test -d ../bsnes.app || mkdir -p ../bsnes.app/Contents/MacOS
$(strip $(cpp) -o ../bsnes.app/Contents/MacOS/bsnes $(objects) $(link))
else
$(strip $(cpp) -o out/bsnes $(objects) $(link))
endif
install:
ifeq ($(platform),x)
install -D -m 755 out/bsnes $(DESTDIR)$(prefix)/bin/bsnes
install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
test -d ~/.bsnes || mkdir ~/.bsnes
cp data/cheats.xml ~/.bsnes/cheats.xml
chmod 777 ~/.bsnes ~/.bsnes/cheats.xml
endif
uninstall:
ifeq ($(platform),x)
rm $(DESTDIR)$(prefix)/bin/bsnes
rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
endif
clean: ui_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 launcher libco nall obj out phoenix ruby snes ui-phoenix ui-qt 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

-56237
View File
File diff suppressed because it is too large. Load diff
-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="x86"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
</assembly>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

-4
View File
@@ -1,4 +0,0 @@
@windres resource.rc resource.o
@mingw32-g++ -std=gnu++0x -mwindows -s -O3 -fomit-frame-pointer -I.. -o ../out/bsnes launcher.cpp resource.o
@del *.o
@pause
-2
View File
@@ -1,2 +0,0 @@
clear
g++ -std=gnu++0x -s -O3 -fomit-frame-pointer -I.. -o ../out/bsnes launcher.cpp
-54
View File
@@ -1,54 +0,0 @@
#include <nall/config.hpp>
#include <nall/detect.hpp>
#include <nall/file.hpp>
#include <nall/foreach.hpp>
#include <nall/platform.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
using namespace nall;
int main(int argc, char **argv) {
char path[PATH_MAX], *unused;
#if !defined(PLATFORM_WIN)
unused = realpath(argv[0], path);
#else
wchar_t **argw = CommandLineToArgvW(GetCommandLineW(), &argc);
unused = realpath(nall::utf8_t(argw[0]), path);
#endif
string realPath = dir(path);
string basePath = string(dir(path), "bsnes-qt.cfg");
unused = userpath(path);
if(!strend(path, "/") && !strend(path, "\\")) strcat(path, "/");
string userPath = string(path, ".bsnes/bsnes-qt.cfg");
configuration config;
string profile;
config.attach(profile = "", "system.profile");
if(config.load(userPath) == false) config.load(basePath);
if(profile == "") profile = "compatibility";
string binaryName = string("bsnes-", profile);
#if defined(PLATFORM_WIN)
binaryName << ".dll";
#endif
string fileName = string(realPath, binaryName);
#if !defined(PLATFORM_WIN)
char **args = new char*[argc + 1];
args[0] = strdup(binaryName);
for(unsigned i = 1; i < argc; i++) args[i] = strdup(argv[i]);
args[argc] = 0;
execvp(args[0], args);
execv(fileName, args);
print("[bsnes] Error: unable to locate binary file: ", binaryName, "\n");
#else
STARTUPINFOW si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(STARTUPINFOW));
if(!CreateProcessW(nall::utf16_t(fileName), GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
MessageBoxA(0, string("Error: unable to locate binary file: ", binaryName), "bsnes", MB_OK);
}
#endif
return 0;
}
-2
View File
@@ -1,2 +0,0 @@
1 24 "bsnes.Manifest"
IDI_ICON1 ICON DISCARDABLE "bsnes.ico"
-104
View File
@@ -1,104 +0,0 @@
/*
libco.amd64 (2009-10-12)
author: byuu
license: public domain
*/
#define LIBCO_C
#include "libco.h"
#include <assert.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
static thread_local long long co_active_buffer[64];
static thread_local cothread_t co_active_handle = 0;
static void (*co_swap)(cothread_t, cothread_t) = 0;
#ifdef _WIN32
//ABI: Win64
static unsigned char co_swap_function[] = {
0x48, 0x89, 0x22, 0x48, 0x8B, 0x21, 0x58, 0x48, 0x89, 0x6A, 0x08, 0x48, 0x89, 0x72, 0x10, 0x48,
0x89, 0x7A, 0x18, 0x48, 0x89, 0x5A, 0x20, 0x4C, 0x89, 0x62, 0x28, 0x4C, 0x89, 0x6A, 0x30, 0x4C,
0x89, 0x72, 0x38, 0x4C, 0x89, 0x7A, 0x40, 0x48, 0x81, 0xC2, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83,
0xE2, 0xF0, 0x0F, 0x29, 0x32, 0x0F, 0x29, 0x7A, 0x10, 0x44, 0x0F, 0x29, 0x42, 0x20, 0x44, 0x0F,
0x29, 0x4A, 0x30, 0x44, 0x0F, 0x29, 0x52, 0x40, 0x44, 0x0F, 0x29, 0x5A, 0x50, 0x44, 0x0F, 0x29,
0x62, 0x60, 0x44, 0x0F, 0x29, 0x6A, 0x70, 0x44, 0x0F, 0x29, 0xB2, 0x80, 0x00, 0x00, 0x00, 0x44,
0x0F, 0x29, 0xBA, 0x90, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x69, 0x08, 0x48, 0x8B, 0x71, 0x10, 0x48,
0x8B, 0x79, 0x18, 0x48, 0x8B, 0x59, 0x20, 0x4C, 0x8B, 0x61, 0x28, 0x4C, 0x8B, 0x69, 0x30, 0x4C,
0x8B, 0x71, 0x38, 0x4C, 0x8B, 0x79, 0x40, 0x48, 0x81, 0xC1, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83,
0xE1, 0xF0, 0x0F, 0x29, 0x31, 0x0F, 0x29, 0x79, 0x10, 0x44, 0x0F, 0x29, 0x41, 0x20, 0x44, 0x0F,
0x29, 0x49, 0x30, 0x44, 0x0F, 0x29, 0x51, 0x40, 0x44, 0x0F, 0x29, 0x59, 0x50, 0x44, 0x0F, 0x29,
0x61, 0x60, 0x44, 0x0F, 0x29, 0x69, 0x70, 0x44, 0x0F, 0x29, 0xB1, 0x80, 0x00, 0x00, 0x00, 0x44,
0x0F, 0x29, 0xB9, 0x90, 0x00, 0x00, 0x00, 0xFF, 0xE0,
};
#include <windows.h>
void co_init() {
DWORD old_privileges;
VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges);
}
#else
//ABI: SystemV
static unsigned char co_swap_function[] = {
0x48, 0x89, 0x26, 0x48, 0x8B, 0x27, 0x58, 0x48, 0x89, 0x6E, 0x08, 0x48, 0x89, 0x5E, 0x10, 0x4C,
0x89, 0x66, 0x18, 0x4C, 0x89, 0x6E, 0x20, 0x4C, 0x89, 0x76, 0x28, 0x4C, 0x89, 0x7E, 0x30, 0x48,
0x8B, 0x6F, 0x08, 0x48, 0x8B, 0x5F, 0x10, 0x4C, 0x8B, 0x67, 0x18, 0x4C, 0x8B, 0x6F, 0x20, 0x4C,
0x8B, 0x77, 0x28, 0x4C, 0x8B, 0x7F, 0x30, 0xFF, 0xE0,
};
#include <unistd.h>
#include <sys/mman.h>
void co_init() {
unsigned long long addr = (unsigned long long)co_swap_function;
unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE));
unsigned long long size = (addr - base) + sizeof co_swap_function;
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
}
#endif
static void crash() {
assert(0); /* called only if cothread_t entrypoint returns */
}
cothread_t co_active() {
if(!co_active_handle) co_active_handle = &co_active_buffer;
return co_active_handle;
}
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
cothread_t handle;
if(!co_swap) {
co_init();
co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
}
if(!co_active_handle) co_active_handle = &co_active_buffer;
size += 512; /* allocate additional space for storage */
size &= ~15; /* align stack to 16-byte boundary */
if(handle = (cothread_t)malloc(size)) {
long long *p = (long long*)((char*)handle + size); /* seek to top of stack */
*--p = (long long)crash; /* crash if entrypoint returns */
*--p = (long long)entrypoint; /* start of function */
*(long long*)handle = (long long)p; /* stack pointer */
}
return handle;
}
void co_delete(cothread_t handle) {
free(handle);
}
void co_switch(cothread_t handle) {
register cothread_t co_previous_handle = co_active_handle;
co_swap(co_active_handle = handle, co_previous_handle);
}
#ifdef __cplusplus
}
#endif
-51
View File
@@ -1,51 +0,0 @@
/*
libco.win (2008-01-28)
authors: Nach, byuu
license: public domain
*/
#define LIBCO_C
#include "libco.h"
#define WINVER 0x0400
#define _WIN32_WINNT 0x0400
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
static thread_local cothread_t co_active_ = 0;
static void __stdcall co_thunk(void *coentry) {
((void (*)(void))coentry)();
}
cothread_t co_active() {
if(!co_active_) {
ConvertThreadToFiber(0);
co_active_ = GetCurrentFiber();
}
return co_active_;
}
cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) {
if(!co_active_) {
ConvertThreadToFiber(0);
co_active_ = GetCurrentFiber();
}
return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry);
}
void co_delete(cothread_t cothread) {
DeleteFiber(cothread);
}
void co_switch(cothread_t cothread) {
co_active_ = cothread;
SwitchToFiber(cothread);
}
#ifdef __cplusplus
}
#endif
-23
View File
@@ -1,23 +0,0 @@
/*
libco
auto-selection module
license: public domain
*/
#if defined(__GNUC__) && defined(__i386__)
#include "x86.c"
#elif defined(__GNUC__) && defined(__amd64__)
#include "amd64.c"
#elif defined(__GNUC__) && defined(__powerpc__) && defined(__ELF__)
#include "ppc-elf.c"
#elif defined(__GNUC__)
#include "sjlj.c"
#elif defined(_MSC_VER) && defined(_M_IX86)
#include "x86.c"
#elif defined(_MSC_VER) && defined(_M_AMD64)
#include "amd64.c"
#elif defined(_MSC_VER)
#include "fiber.c"
#else
#error "libco: unsupported processor, compiler or operating system"
#endif
-34
View File
@@ -1,34 +0,0 @@
/*
libco
version: 0.15 (2009-10-12)
license: public domain
*/
#ifndef LIBCO_H
#define LIBCO_H
#ifdef LIBCO_C
#ifdef LIBCO_MP
#define thread_local __thread
#else
#define thread_local
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef void* cothread_t;
cothread_t co_active();
cothread_t co_create(unsigned int, void (*)(void));
void co_delete(cothread_t);
void co_switch(cothread_t);
#ifdef __cplusplus
}
#endif
/* ifndef LIBCO_H */
#endif
-325
View File
@@ -1,325 +0,0 @@
/*
* libco.ppc-elf
* author: Kernigh
* license: public domain
*
* PowerPC 32-bit ELF implementation of libco (for compile with GCC),
* ported from PowerPC Mac OS X implementation (ppc.s) by Vas Crabb.
* This ELF version works for OpenBSD, and might also work for FreeBSD,
* NetBSD and Linux.
*
* Note 1: This implementation does not handle the AltiVec/VMX
* registers, because the ELF ABI does not mention them,
* and my OpenBSD system is not using them.
*
* Note 2: If you want position-independent code, then you must
* define __PIC__. gcc -fpic or -fPIC defines __PIC__, but
* gcc -fpie or -fPIE might not. If you want to use -fpie
* or -fPIE, then you might need a manual definition:
* gcc -fpie -D__PIC__=1
* gcc -fPIE -D__PIC__=2
*
* The ELF ABI is "System V Application Binary Interface, PowerPC
* Processor Supplement", which you can get from
* <http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf>
* (PDF file, hosted by Linux Foundation).
*
* ELF and Mac OS X use similar conventions to allocate the registers,
* and to pass arguments and return values through registers. The main
* differences are that ELF has a slightly different stack format, that
* symbols are different (and without an extra underscore at the start),
* and that the assembly syntax is different.
*
* A function may destroy the values of volatile registers, but must
* preserve the values of nonvolatile registers. So the co_switch()
* function only saves the nonvolatile registers.
*
* [nonvolatile registers in ELF]
* %r1, %r14..%r31
* %f14..%f31
* %cr2..%cr4 in cr
*
* [volatile registers in ELF]
* %r0, %r3..%r10
* %f0..%f13
* %cr0, %cr1, %cr5..%cr7 in cr
* ctr, lr, xer
*
* lr (link register) is volatile, but it contains the return address,
* so co_switch must save lr.
*
* %r13 is the small data pointer. This is constant across threads, so
* co_switch() does not touch %r13.
*
* %r2 is a reserved register, so co_switch() does not touch %r2. Some
* systems might borrow an idea from the PowerPC Embedded ABI, and might
* use %r2 as a small read-only data pointer, which is constant across
* threads.
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef void * cothread_t;
/*
* co_active_context is either in a global offset table (if we are
* compiling -fPIC or -fPIE) or has an absolute position.
*/
static void *co_main_stack_pointer;
static cothread_t co_active_context = &co_main_stack_pointer;
extern cothread_t co_active() {
return co_active_context;
}
/*
* Embedded assembly.
*
* We are not using the percent-sign substitution feature,
* so we must write "%r1", not "%%r1".
*
* We always write 'bl malloc@plt', not 'bl malloc'. The '@plt'
* is necessary in position-indepent code and seems to have no
* significant effect in fixed-position code.
*
* We never use the 'lmw' or 'stmw' instructions. The ELF ABI
* mentions that these instructions "are usually slower than
* a sequence of other instructions that have the same effect."
* We instead use sequences of 'lwz' or 'stz' instructions.
*/
__asm__("\n"
"### embedded assembly \n"
".section \".text\" \n"
" .balign 4 \n"
" \n"
/*
* void co_switch(co_thread to %r3)
*
* Allocate our stack frame of 240 bytes:
* Old New Value
* 4(%r1) 244(%r1) return address, used by us
* 0(%r1) 240(%r1) frame pointer
* 232(%r1) %f31
* 224(%r1) %f30
* ...
* 96(%r1) %f14
* 92(%r1) %r31
* 88(%r1) %r30
* ...
* 24(%r1) %r14
* 20(%r1) condition register
* 8(%r1) padding of 12 bytes
* 4(%r1) return address, never used
* 0(%r1) frame pointer
*
* Save our registers in our stack frame.
* Save our stack pointer in 0(%r4).
* Switch to the stack of the other thread.
* Restore registers and return.
*/
" .globl co_switch \n"
" .type co_switch, @function \n"
"co_switch: \n"
" mflr %r0 # %r0 = return address \n"
" mfcr %r9 # %r9 = condition register \n"
" stwu %r1, -240(%r1) # allocate stack frame \n"
" \n"
" stw %r0, 244(%r1) # save return address \n"
" stfd %f31, 232(%r1) # save floating-point regs \n"
" stfd %f30, 224(%r1) \n"
" stfd %f29, 216(%r1) \n"
" stfd %f28, 208(%r1) \n"
" stfd %f27, 200(%r1) \n"
" stfd %f26, 192(%r1) \n"
" stfd %f25, 184(%r1) \n"
" stfd %f24, 176(%r1) \n"
" stfd %f23, 168(%r1) \n"
" stfd %f22, 160(%r1) \n"
" stfd %f21, 152(%r1) \n"
" stfd %f20, 144(%r1) \n"
" stfd %f19, 136(%r1) \n"
" stfd %f18, 128(%r1) \n"
" stfd %f17, 120(%r1) \n"
" stfd %f16, 112(%r1) \n"
" stfd %f16, 104(%r1) \n"
" stfd %f14, 96(%r1) \n"
" stw %r31, 92(%r1) # save general-purpose regs \n"
" stw %r30, 88(%r1) \n"
" stw %r29, 84(%r1) \n"
" stw %r28, 80(%r1) \n"
" stw %r27, 76(%r1) \n"
" stw %r26, 72(%r1) \n"
" stw %r25, 68(%r1) \n"
" stw %r24, 64(%r1) \n"
" stw %r23, 60(%r1) \n"
" stw %r22, 56(%r1) \n"
" stw %r21, 52(%r1) \n"
" stw %r20, 48(%r1) \n"
" stw %r19, 44(%r1) \n"
" stw %r18, 40(%r1) \n"
" stw %r17, 36(%r1) \n"
" stw %r16, 32(%r1) \n"
" stw %r15, 28(%r1) \n"
" stw %r14, 24(%r1) \n"
" stw %r9, 20(%r1) # save condition reg \n"
" \n"
" # save current context, set new context \n"
" # %r4 = co_active_context \n"
" # co_active_context = %r3 \n"
#if __PIC__ == 2
" # position-independent code, large model (-fPIC) \n"
" bl _GLOBAL_OFFSET_TABLE_@local-4 \n"
" mflr %r8 # %r8 = address of got \n"
" addis %r7, %r8, co_active_context@got@ha \n"
" lwz %r6, co_active_context@got@l(%r7) \n"
" lwz %r4, 0(%r6) \n"
" stw %r3, 0(%r6) \n"
#elif __PIC__ == 1
" # position-independent code, small model (-fpic) \n"
" bl _GLOBAL_OFFSET_TABLE_@local-4 \n"
" mflr %r8 # %r8 = address of got \n"
" lwz %r7, co_active_context@got(%r8) \n"
" lwz %r4, 0(%r7) \n"
" stw %r3, 0(%r7) \n"
#else
" # fixed-position code \n"
" lis %r8, co_active_context@ha \n"
" lwz %r4, co_active_context@l(%r8) \n"
" stw %r3, co_active_context@l(%r8) \n"
#endif
" \n"
" # save current stack pointer \n"
" stw %r1, 0(%r4) \n"
" # get new stack pointer \n"
" lwz %r1, 0(%r3) \n"
" \n"
" lwz %r0, 244(%r1) # get return address \n"
" lfd %f31, 232(%r1) # restore floating-point regs \n"
" lfd %f30, 224(%r1) \n"
" lfd %f29, 216(%r1) \n"
" lfd %f28, 208(%r1) \n"
" lfd %f27, 200(%r1) \n"
" lfd %f26, 192(%r1) \n"
" lfd %f25, 184(%r1) \n"
" lfd %f24, 176(%r1) \n"
" lfd %f23, 168(%r1) \n"
" lfd %f22, 160(%r1) \n"
" lfd %f21, 152(%r1) \n"
" lfd %f20, 144(%r1) \n"
" lfd %f19, 136(%r1) \n"
" lfd %f18, 128(%r1) \n"
" lfd %f17, 120(%r1) \n"
" lfd %f16, 112(%r1) \n"
" lfd %f16, 104(%r1) \n"
" lfd %f14, 96(%r1) \n"
" lwz %r31, 92(%r1) # restore general-purpose regs \n"
" lwz %r30, 88(%r1) \n"
" lwz %r29, 84(%r1) \n"
" lwz %r28, 80(%r1) \n"
" lwz %r27, 76(%r1) \n"
" lwz %r26, 72(%r1) \n"
" lwz %r25, 68(%r1) \n"
" lwz %r24, 64(%r1) \n"
" lwz %r23, 60(%r1) \n"
" lwz %r22, 56(%r1) \n"
" lwz %r21, 52(%r1) \n"
" lwz %r20, 48(%r1) \n"
" lwz %r19, 44(%r1) \n"
" lwz %r18, 40(%r1) \n"
" lwz %r17, 36(%r1) \n"
" lwz %r16, 32(%r1) \n"
" lwz %r15, 28(%r1) \n"
" lwz %r14, 24(%r1) \n"
" lwz %r9, 20(%r1) # get condition reg \n"
" \n"
" addi %r1, %r1, 240 # free stack frame \n"
" mtlr %r0 # restore return address \n"
" mtcr %r9 # restore condition register \n"
" blr # return \n"
" .size co_switch, . - co_switch \n"
" \n"
/*
* cothread_t %r3 co_create(unsigned int stack_size %r3,
* void (*coentry %r4)())
*
* Allocate a new stack, such that when you co_switch to that
* stack, then co_switch returns to coentry.
*/
" .globl co_create \n"
" .type co_create, @function \n"
"co_create: \n"
" mflr %r0 # %r0 = return address \n"
" stwu %r1, -16(%r1) # allocate my stack frame \n"
" stw %r0, 20(%r1) # save return address \n"
" stw %r31, 12(%r1) # save %r31 \n"
" stw %r30, 8(%r1) # save %r30 \n"
" \n"
" mr %r30, %r3 # %r30 = stack_size \n"
" mr %r31, %r4 # %r31 = coentry \n"
" \n"
" # Call malloc(stack_size %r3) to allocate stack; \n"
" # malloc() probably uses good alignment. \n"
" # \n"
" bl malloc@plt # returns %r3 = low end \n"
" cmpwi %r3, 0 # if returned NULL, \n"
" beq- 1f # then abort \n"
" \n"
" # we return %r3 = low end of stack \n"
" add %r4, %r3, %r30 # %r4 = high end of stack \n"
" \n"
" # uncomment if malloc() uses wrong alignment \n"
" #rlwinm %r4,%r4,0,0,27 # force 16-byte alignment \n"
" \n"
/*
* Allocate two stack frames:
* 16 bytes for stack frame with return address
* 240 bytes for co_switch stack frame
*
* Old New Value
* -8(%r4) 248(%r5) padding of 8 bytes
* -12(%r4) 244(%r5) return address = coentry
* -16(%r4) 240(%r5) frame pointer = NULL
* 232(%r5) %f31 = 0
* ...
* 20(%r5) condition register = 0
* 0(%r5) frame pointer
*/
" li %r9, (240-20)/4+1 \n"
" addi %r5, %r4, -16 # allocate first stack frame \n"
" li %r0, 0 \n"
" stwu %r5, -240(%r5) # allocate second stack frame \n"
" li %r8, 20 \n"
" mtctr %r9 # loop %r9 times \n"
"2: # loop to store zero to 20(%r5) through 240(%r5) \n"
" stwx %r0, %r5, %r8 \n"
" addi %r8, %r8, 4 # index += 4 \n"
" bdnz+ 2b # ctr -= 1, branch if nonzero \n"
" \n"
" stw %r31, 244(%r5) # return address = coentry \n"
" stw %r5, 0(%r3) # save stack pointer \n"
" \n"
" lwz %r0, 20(%r1) # get return address \n"
" lwz %r31, 12(%r1) # restore %r31 \n"
" lwz %r30, 8(%r1) # restore %r30 \n"
" mtlr %r0 # restore return address \n"
" addi %r1, %r1, 16 # free stack frame \n"
" blr # return \n"
" \n"
"1: b abort@plt # branch 1f to abort \n"
" .size co_create, . - co_create \n"
" \n"
/*
* void co_delete(cothread_t) => void free(void *)
*/
" .globl co_delete \n"
" .type co_delete, @function \n"
"co_delete: \n"
" b free@plt \n"
" \n"
);
#ifdef __cplusplus
}
#endif
-478
View File
@@ -1,478 +0,0 @@
;*****
;libco.ppc (2007-11-29)
;author: Vas Crabb
;license: public domain
;
;cross-platform PowerPC implementation of libco
;special thanks to byuu for writing the original version
;
;[ABI compatibility]
;- gcc; mac os x; ppc
;
;[nonvolatile registers]
;- GPR1, GPR13 - GPR31
;- FPR14 - FPR31
;- V20 - V31
;- VRSAVE, CR2 - CR4
;
;[volatile registers]
;- GPR0, GPR2 - GPR12
;- FPR0 - FPR13
;- V0 - V19
;- LR, CTR, XER, CR0, CR1, CR5 - CR7
;*****
;Declare some target-specific stuff
.section __TEXT,__text,regular,pure_instructions
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.machine ppc
;Constants
.cstring
.align 2
_sysctl_altivec:
.ascii "hw.optional.altivec\0"
;Declare space for variables
.lcomm _co_environ,4,2 ;bit 0 = initialised, bit 1 = have Altivec/VMX
.lcomm _co_primary_buffer,1024,2 ;buffer (will be zeroed by loader)
.data
.align 2
_co_active_context:
.long _co_primary_buffer
.text
.align 2
;Declare exported names
.globl _co_active
.globl _co_create
.globl _co_delete
.globl _co_switch
;*****
;extern "C" cothread_t co_active();
;return = GPR3
;*****
_co_active:
mflr r0 ;GPR0 = return address
bcl 20,31,L_co_active$spb
L_co_active$spb:
mflr r2 ;GPR2 set for position-independance
addis r3,r2,ha16(_co_active_context-L_co_active$spb) ;get value in GPR3
lwz r3,lo16(_co_active_context-L_co_active$spb)(r3)
mtlr r0 ;LR = return address
blr ;return
;*****
;extern "C" cothread_t co_create(unsigned int heapsize, void (*coentry)());
;GPR3 = heapsize
;GPR4 = coentry
;return = GPR3
;*****
_co_create:
mflr r0 ;GPR0 = return address
stmw r30,-8(r1) ;save GPR30 and GPR31
stw r0,8(r1) ;save return address
stwu r1,-(2*4+16+24)(r1) ;allocate 16 bytes for locals/parameters
;create heap space (stack + register storage)
addi r31,r3,1024-24 ;subtract space for linkage
mr r30,r4 ;GPR30 = coentry
addi r3,r3,1024 ;allocate extra memory for contextual info
bl L_malloc$stub ;GPR3 = malloc(heapsize + 1024)
add r4,r3,r31 ;GPR4 points to top-of-stack
rlwinm r5,r4,0,0,27 ;force 16-byte alignment
;store thread entry point + registers, so that first call to co_switch will execute coentry
stw r30,8(r5) ;store entry point
addi r6,0,2+19+18*2+12*4+1 ;clear for CR, old GPR1, 19 GPRs, 18 FPRs, 12 VRs, VRSAVE
addi r0,0,0
addi r7,0,4 ;start at 4(GPR5)
mtctr r6
L_co_create$clear_loop:
stwx r0,r5,r7 ;clear a word
addi r7,r7,-4 ;increment pointer
bdnz L_co_create$clear_loop ;loop
stwu r5,-448(r5) ;store top of stack
;initialize context memory heap and return
stw r5,0(r3) ;*cothread_t = stack heap pointer (GPR1)
lwz r1,0(r1) ;deallocate stack frame
lwz r8,8(r1) ;fetch return address
lmw r30,-8(r1) ;restore GPR30 and GPR31
mtlr r8 ;return address in LR
blr ;return
;*****
;extern "C" void co_delete(cothread_t cothread);
;GPR3 = cothread
;*****
_co_delete:
b L_free$stub ;free(GPR3)
;*****
;extern "C" void co_switch(cothread_t cothread);
;GPR3 = cothread
;*****
;
;Frame looks like:
;
;Old New Value
; 8(r1) 456(r1) Saved LR
; 4(r1) 452(r1) Saved CR
; 0(r1) 448(r1) Old GPR1
; -4(r1) 444(r1) Saved GPR31
; -8(r1) 440(r1) Saved GPR30
;... ... ...
; -72(r1) 376(r1) Saved GPR14
; -76(r1) 372(r1) Saved GPR13
; -80(r1) 368(r1) Saved VRSAVE
; -84(r1) 364(r1) +++
; -88(r1) 360(r1) Saved FPR31
; -92(r1) 356(r1) +++
; -96(r1) 352(r1) Saved FPR30
;... ... ...
;-212(r1) 236(r1) +++
;-216(r1) 232(r1) Saved FPR15
;-220(r1) 228(r1) +++
;-224(r1) 224(r1) Saved FPR14
;-228(r1) 220(r1) +++ value
;-232(r1) 216(r1) +++ len
;-236(r1) 212(r1) +++
;-240(r1) 208(r1) Saved VR31
;-244(r1) 204(r1) +++
;-248(r1) 200(r1) +++
;-252(r1) 196(r1) +++
;-256(r1) 192(r1) Saved VR30
;... ... ...
;-388(r1) 60(r1) +++
;-392(r1) 56(r1) +++
;-396(r1) 52(r1) +++
;-400(r1) 48(r1) Saved VR21
;-404(r1) 44(r1) +++
;-408(r1) 40(r1) +++ Param 5 (GPR7)
;-412(r1) 36(r1) +++ Param 4 (GPR6)
;-416(r1) 32(r1) Saved VR20 Param 3 (GPR5)
;-420(r1) 28(r1) - Param 2 (GPR4)
;-424(r1) 24(r1) - Param 1 (GPR3)
;-428(r1) 20(r1) - Reserved
;-432(r1) 16(r1) - Reserved
;-436(r1) 12(r1) - Reserved
;-440(r1) 8(r1) - New LR
;-444(r1) 4(r1) - New CR
;-448(r1) 0(r1) Saved GPR1
_co_switch:
stmw r13,-76(r1) ;save preserved GPRs
stfd f14,-224(r1) ;save preserved FPRs
stfd f15,-216(r1)
stfd f16,-208(r1)
stfd f17,-200(r1)
stfd f18,-192(r1)
stfd f19,-184(r1)
stfd f20,-176(r1)
stfd f21,-168(r1)
stfd f22,-160(r1)
stfd f23,-152(r1)
stfd f24,-144(r1)
stfd f25,-136(r1)
stfd f26,-128(r1)
stfd f27,-120(r1)
stfd f28,-112(r1)
stfd f29,-104(r1)
stfd f30,-96(r1)
stfd f31,-88(r1)
mflr r0 ;save return address
stw r0,8(r1)
mfcr r2 ;save condition codes
stw r2,4(r1)
stwu r1,-448(r1) ;create stack frame (save 19 GPRs, 18 FRPs, 12 VRs, VRSAVE)
mr r30,r3 ;save new context pointer
bcl 20,31,L_co_switch$spb ;get address of co_active_context
L_co_switch$spb:
mflr r31
addis r29,r31,ha16(_co_environ-L_co_switch$spb) ;get environment flags
lwz r8,lo16(_co_environ-L_co_switch$spb)(r29)
andis. r9,r8,0x8000 ;is it initialised?
bne+ L_co_switch$initialised
addi r0,0,4 ;len = sizeof(int)
stw r0,216(r1)
addis r3,r31,ha16(_sysctl_altivec-L_co_switch$spb) ;GPR3 = "hw.optional.altivec"
addi r3,r3,lo16(_sysctl_altivec-L_co_switch$spb)
addi r4,r1,220 ;GPR4 = &value
addi r5,r1,216 ;GPR5 = &len
addi r6,0,0 ;newp = 0
addi r7,0,0 ;newlen = 0
bl L_sysctlbyname$stub ;call sysctlbyname
lwz r2,220(r1) ;fetch result
addis r8,0,0x8000 ;set initialised bit
cmpwi cr5,r3,0 ;assume error means not present
cmpwi cr6,r2,0 ;test result
blt- cr5,L_co_switch$store_environ
beq cr6,L_co_switch$store_environ
oris r8,r8,0x4000 ;set the flag to say we have it!
L_co_switch$store_environ:
stw r8,lo16(_co_environ-L_co_switch$spb)(r29) ;store environment flags
L_co_switch$initialised:
andis. r10,r8,0x4000 ;do we have Altivec/VMX?
beq L_co_switch$save_no_vmx
mfspr r11,256 ;save VRSAVE
andi. r0,r11,0x0FFF ;short-circuit if it's zero
stw r11,368(r1)
beq L_co_switch$save_no_vmx
andi. r0,r11,0x0800 ;check bit 20
addi r2,0,32 ;starting index
beq L_co_switch$save_skip_vr20
stvx v20,r1,r2 ;save VR20
L_co_switch$save_skip_vr20:
addi r2,r2,16 ;stride
andi. r0,r11,0x0400 ;check bit 21
beq L_co_switch$save_skip_vr21
stvx v21,r1,r2 ;save VR21
L_co_switch$save_skip_vr21:
addi r2,r2,16 ;stride
andi. r0,r11,0x0200 ;check bit 22
beq L_co_switch$save_skip_vr22
stvx v22,r1,r2 ;save VR22
L_co_switch$save_skip_vr22:
addi r2,r2,16 ;stride
andi. r0,r11,0x0100 ;check bit 23
beq L_co_switch$save_skip_vr23
stvx v23,r1,r2 ;save VR23
L_co_switch$save_skip_vr23:
addi r2,r2,16 ;stride
andi. r0,r11,0x0080 ;check bit 24
beq L_co_switch$save_skip_vr24
stvx v24,r1,r2 ;save VR24
L_co_switch$save_skip_vr24:
addi r2,r2,16 ;stride
andi. r0,r11,0x0040 ;check bit 25
beq L_co_switch$save_skip_vr25
stvx v25,r1,r2 ;save VR25
L_co_switch$save_skip_vr25:
addi r2,r2,16 ;stride
andi. r0,r11,0x0020 ;check bit 26
beq L_co_switch$save_skip_vr26
stvx v26,r1,r2 ;save VR26
L_co_switch$save_skip_vr26:
addi r2,r2,16 ;stride
andi. r0,r11,0x0010 ;check bit 27
beq L_co_switch$save_skip_vr27
stvx v27,r1,r2 ;save VR27
L_co_switch$save_skip_vr27:
addi r2,r2,16 ;stride
andi. r0,r11,0x0008 ;check bit 28
beq L_co_switch$save_skip_vr28
stvx v28,r1,r2 ;save VR28
L_co_switch$save_skip_vr28:
addi r2,r2,16 ;stride
andi. r0,r11,0x0004 ;check bit 29
beq L_co_switch$save_skip_vr29
stvx v29,r1,r2 ;save VR29
L_co_switch$save_skip_vr29:
addi r2,r2,16 ;stride
andi. r0,r11,0x0002 ;check bit 30
beq L_co_switch$save_skip_vr30
stvx v30,r1,r2 ;save VR30
L_co_switch$save_skip_vr30:
addi r2,r2,16 ;stride
andi. r0,r11,0x0001 ;check bit 31
beq L_co_switch$save_skip_vr31
stvx v31,r1,r2 ;save VR31
L_co_switch$save_skip_vr31:
L_co_switch$save_no_vmx:
addis r4,r31,ha16(_co_active_context-L_co_switch$spb) ;save current context
lwz r5,lo16(_co_active_context-L_co_switch$spb)(r4)
stw r30,lo16(_co_active_context-L_co_switch$spb)(r4);set new context
stw r1,0(r5) ;save current stack pointer
lwz r1,0(r30) ;get new stack pointer
andis. r10,r8,0x4000 ;do we have Altivec/VMX?
beq L_co_switch$restore_no_vmx
lwz r11,368(r1) ;restore VRSAVE
andi. r0,r11,0x0FFF ;short-circuit if it's zero
mtspr 256,r11
beq L_co_switch$restore_no_vmx
andi. r0,r11,0x0800 ;check bit 20
addi r2,0,32 ;starting index
beq L_co_switch$restore_skip_vr20
lvx v20,r1,r2 ;restore VR20
L_co_switch$restore_skip_vr20:
addi r2,r2,16 ;stride
andi. r0,r11,0x0400 ;check bit 21
beq L_co_switch$restore_skip_vr21
lvx v21,r1,r2 ;restore VR21
L_co_switch$restore_skip_vr21:
addi r2,r2,16 ;stride
andi. r0,r11,0x0200 ;check bit 22
beq L_co_switch$restore_skip_vr22
lvx v22,r1,r2 ;restore VR22
L_co_switch$restore_skip_vr22:
addi r2,r2,16 ;stride
andi. r0,r11,0x0100 ;check bit 23
beq L_co_switch$restore_skip_vr23
lvx v23,r1,r2 ;restore VR23
L_co_switch$restore_skip_vr23:
addi r2,r2,16 ;stride
andi. r0,r11,0x0080 ;check bit 24
beq L_co_switch$restore_skip_vr24
lvx v24,r1,r2 ;restore VR24
L_co_switch$restore_skip_vr24:
addi r2,r2,16 ;stride
andi. r0,r11,0x0040 ;check bit 25
beq L_co_switch$restore_skip_vr25
lvx v25,r1,r2 ;restore VR25
L_co_switch$restore_skip_vr25:
addi r2,r2,16 ;stride
andi. r0,r11,0x0020 ;check bit 26
beq L_co_switch$restore_skip_vr26
lvx v26,r1,r2 ;restore VR26
L_co_switch$restore_skip_vr26:
addi r2,r2,16 ;stride
andi. r0,r11,0x0010 ;check bit 27
beq L_co_switch$restore_skip_vr27
lvx v27,r1,r2 ;restore VR27
L_co_switch$restore_skip_vr27:
addi r2,r2,16 ;stride
andi. r0,r11,0x0008 ;check bit 28
beq L_co_switch$restore_skip_vr28
lvx v28,r1,r2 ;restore VR28
L_co_switch$restore_skip_vr28:
addi r2,r2,16 ;stride
andi. r0,r11,0x0004 ;check bit 29
beq L_co_switch$restore_skip_vr29
lvx v29,r1,r2 ;restore VR29
L_co_switch$restore_skip_vr29:
addi r2,r2,16 ;stride
andi. r0,r11,0x0002 ;check bit 30
beq L_co_switch$restore_skip_vr30
lvx v30,r1,r2 ;restore VR30
L_co_switch$restore_skip_vr30:
addi r2,r2,16 ;stride
andi. r0,r11,0x0001 ;check bit 31
beq L_co_switch$restore_skip_vr31
lvx v31,r1,r2 ;restore VR31
L_co_switch$restore_skip_vr31:
L_co_switch$restore_no_vmx:
lwz r1,0(r1) ;deallocate stack frame
lwz r6,8(r1) ;return address in GPR6
lwz r7,4(r1) ;condition codes in GPR7
addi r0,0,0 ;make thread main crash if it returns
lmw r13,-76(r1) ;restore preserved GPRs
lfd f14,-224(r1) ;restore preserved FPRs
lfd f15,-216(r1)
lfd f16,-208(r1)
lfd f17,-200(r1)
lfd f18,-192(r1)
lfd f19,-184(r1)
lfd f20,-176(r1)
lfd f21,-168(r1)
lfd f22,-160(r1)
lfd f23,-152(r1)
lfd f24,-144(r1)
lfd f25,-136(r1)
lfd f26,-128(r1)
lfd f27,-120(r1)
lfd f28,-112(r1)
lfd f29,-104(r1)
lfd f30,-96(r1)
lfd f31,-88(r1)
mtlr r0
mtctr r6 ;restore return address
mtcrf 32,r7 ;restore preserved condition codes
mtcrf 16,r7
mtcrf 8,r7
bctr ;return
;Import external functions
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.align 5
L_malloc$stub:
.indirect_symbol _malloc
mflr r0
bcl 20,31,L_malloc$spb
L_malloc$spb:
mflr r11
addis r11,r11,ha16(L_malloc$lazy_ptr-L_malloc$spb)
mtlr r0
lwzu r12,lo16(L_malloc$lazy_ptr-L_malloc$spb)(r11)
mtctr r12
bctr
.lazy_symbol_pointer
L_malloc$lazy_ptr:
.indirect_symbol _malloc
.long dyld_stub_binding_helper
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.align 5
L_free$stub:
.indirect_symbol _free
mflr r0
bcl 20,31,L_free$spb
L_free$spb:
mflr r11
addis r11,r11,ha16(L_free$lazy_ptr-L_free$spb)
mtlr r0
lwzu r12,lo16(L_free$lazy_ptr-L_free$spb)(r11)
mtctr r12
bctr
.lazy_symbol_pointer
L_free$lazy_ptr:
.indirect_symbol _free
.long dyld_stub_binding_helper
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.align 5
L_sysctlbyname$stub:
.indirect_symbol _sysctlbyname
mflr r0
bcl 20,31,L_sysctlbyname$spb
L_sysctlbyname$spb:
mflr r11
addis r11,r11,ha16(L_sysctlbyname$lazy_ptr-L_sysctlbyname$spb)
mtlr r0
lwzu r12,lo16(L_sysctlbyname$lazy_ptr-L_sysctlbyname$spb)(r11)
mtctr r12
bctr
.lazy_symbol_pointer
L_sysctlbyname$lazy_ptr:
.indirect_symbol _sysctlbyname
.long dyld_stub_binding_helper
;This needs to be here!
.subsections_via_symbols
-513
View File
@@ -1,513 +0,0 @@
;*****
;libco.ppc64 (2007-12-05)
;author: Vas Crabb
;license: public domain
;
;cross-platform 64-bit PowerPC implementation of libco
;special thanks to byuu for writing the original version
;
;[ABI compatibility]
;- gcc; mac os x; ppc64
;
;[nonvolatile registers]
;- GPR1, GPR13 - GPR31
;- FPR14 - FPR31
;- V20 - V31
;- VRSAVE, CR2 - CR4
;
;[volatile registers]
;- GPR0, GPR2 - GPR12
;- FPR0 - FPR13
;- V0 - V19
;- LR, CTR, XER, CR0, CR1, CR5 - CR7
;*****
;Declare some target-specific stuff
.section __TEXT,__text,regular,pure_instructions
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.machine ppc64
;Constants
.cstring
.align 3
_sysctl_altivec:
.ascii "hw.optional.altivec\0"
;Declare space for variables
.lcomm _co_environ,4,2 ;bit 0 = initialised, bit 1 = have Altivec/VMX
.lcomm _co_primary_buffer,1024,3 ;buffer (will be zeroed by loader)
.data
.align 3
_co_active_context:
.quad _co_primary_buffer
.text
.align 2
;Declare exported names
.globl _co_active
.globl _co_create
.globl _co_delete
.globl _co_switch
;*****
;extern "C" cothread_t co_active();
;return = GPR3
;*****
_co_active:
mflr r0 ;GPR0 = return address
bcl 20,31,L_co_active$spb
L_co_active$spb:
mflr r2 ;GPR2 set for position-independance
addis r3,r2,ha16(_co_active_context-L_co_active$spb) ;get value in GPR3
ld r3,lo16(_co_active_context-L_co_active$spb)(r3)
mtlr r0 ;LR = return address
blr ;return
;*****
;extern "C" cothread_t co_create(unsigned int heapsize, void (*coentry)());
;GPR3 = heapsize
;GPR4 = coentry
;return = GPR3
;*****
_co_create:
mflr r0 ;GPR0 = return address
std r30,-16(r1) ;save GPR30 and GPR31
std r31,-8(r1)
std r0,16(r1) ;save return address
stdu r1,-(2*8+16+48)(r1) ;allocate 16 bytes for locals/parameters
;create heap space (stack + register storage)
addi r31,r3,1024-48 ;subtract space for linkage
mr r30,r4 ;GPR30 = coentry
addi r3,r3,1024 ;allocate extra memory for contextual info
bl L_malloc$stub ;GPR3 = malloc(heapsize + 1024)
add r4,r3,r31 ;GPR4 points to top-of-stack
rldicr r5,r4,0,59 ;force 16-byte alignment
;store thread entry point + registers, so that first call to co_switch will execute coentry
std r30,16(r5) ;store entry point
addi r6,0,2+19+18+12*2+1 ;clear for CR, old GPR1, 19 GPRs, 18 FPRs, 12 VRs, VRSAVE
addi r0,0,0
addi r7,0,8 ;start at 8(GPR5)
mtctr r6
L_co_create$clear_loop:
stdx r0,r5,r7 ;clear a double
addi r7,r7,-8 ;increment pointer
bdnz L_co_create$clear_loop ;loop
stdu r5,-544(r5) ;store top of stack
;initialize context memory heap and return
addis r9,0,0x8000 ;GPR13 not set (system TLS)
std r5,0(r3) ;*cothread_t = stack heap pointer (GPR1)
stw r9,8(r3) ;this is a flag word
ld r1,0(r1) ;deallocate stack frame
ld r8,16(r1) ;fetch return address
ld r30,-16(r1) ;restore GPR30 and GPR31
ld r31,-8(r1)
mtlr r8 ;return address in LR
blr ;return
;*****
;extern "C" void co_delete(cothread_t cothread);
;GPR3 = cothread
;*****
_co_delete:
b L_free$stub ;free(GPR3)
;*****
;extern "C" void co_switch(cothread_t cothread);
;GPR3 = cothread
;*****
;
;Frame looks like:
;
;Old New Value
; 16(r1) 560(r1) Saved LR
; 8(r1) 552(r1) Saved CR
; 0(r1) 544(r1) Old GPR1
; -8(r1) 536(r1) Saved GPR31
; -16(r1) 528(r1) Saved GPR30
;... ... ...
;-144(r1) 400(r1) Saved GPR14
;-152(r1) 392(r1) Saved GPR13
;-160(r1) 384(r1) Saved FPR31
;-168(r1) 376(r1) Saved FPR30
;... ... ...
;-288(r1) 256(r1) Saved FPR15
;-296(r1) 248(r1) Saved FPR14
;-304(r1) 240(r1) Saved VRSAVE
;-312(r1) 232(r1) +++ value
;-320(r1) 224(r1) Saved VR31 len
;-328(r1) 216(r1) +++
;-336(r1) 208(r1) Saved VR30
;... ... ...
;-456(r1) 88(r1) +++
;-464(r1) 80(r1) Saved VR22 Param 5 (GPR7)
;-472(r1) 72(r1) +++ Param 4 (GPR6)
;-480(r1) 64(r1) Saved VR21 Param 3 (GPR5)
;-488(r1) 56(r1) +++ Param 2 (GPR4)
;-496(r1) 48(r1) Saved VR20 Param 1 (GPR3)
;-504(r1) 40(r1) - Reserved
;-512(r1) 32(r1) - Reserved
;-520(r1) 24(r1) - Reserved
;-528(r1) 16(r1) - New LR
;-536(r1) 8(r1) - New CR
;-544(r1) 0(r1) Saved GPR1
_co_switch:
std r13,-152(r1) ;save preserved GPRs
std r14,-144(r1)
std r15,-136(r1)
std r16,-128(r1)
std r17,-120(r1)
std r18,-112(r1)
std r19,-104(r1)
std r20,-96(r1)
std r21,-88(r1)
std r22,-80(r1)
std r23,-72(r1)
std r24,-64(r1)
std r25,-56(r1)
std r26,-48(r1)
std r27,-40(r1)
std r28,-32(r1)
std r29,-24(r1)
std r30,-16(r1)
std r31,-8(r1)
mflr r0 ;save return address
std r0,16(r1)
mfcr r2 ;save condition codes
stw r2,8(r1)
stdu r1,-544(r1) ;create stack frame (save 19 GPRs, 18 FRPs, 12 VRs, VRSAVE)
stfd f14,248(r1) ;save preserved FPRs
stfd f15,256(r1)
stfd f16,264(r1)
stfd f17,272(r1)
stfd f18,280(r1)
stfd f19,288(r1)
stfd f20,296(r1)
stfd f21,304(r1)
stfd f22,312(r1)
stfd f23,320(r1)
stfd f24,328(r1)
stfd f25,336(r1)
stfd f26,344(r1)
stfd f27,352(r1)
stfd f28,360(r1)
stfd f29,368(r1)
stfd f30,376(r1)
stfd f31,384(r1)
mr r30,r3 ;save new context pointer
bcl 20,31,L_co_switch$spb ;get address of co_active_context
L_co_switch$spb:
mflr r31
addis r29,r31,ha16(_co_environ-L_co_switch$spb) ;get environment flags
lwz r8,lo16(_co_environ-L_co_switch$spb)(r29)
andis. r9,r8,0x8000 ;is it initialised?
bne+ L_co_switch$initialised
addi r0,0,4 ;len = sizeof(int)
std r0,224(r1)
addis r3,r31,ha16(_sysctl_altivec-L_co_switch$spb) ;GPR3 = "hw.optional.altivec"
addi r3,r3,lo16(_sysctl_altivec-L_co_switch$spb)
addi r4,r1,232 ;GPR4 = &value
addi r5,r1,224 ;GPR5 = &len
addi r6,0,0 ;newp = 0
addi r7,0,0 ;newlen = 0
bl L_sysctlbyname$stub ;call sysctlbyname
lwz r2,232(r1) ;fetch result
addis r8,0,0x8000 ;set initialised bit
cmpdi cr5,r3,0 ;assume error means not present
cmpwi cr6,r2,0 ;test result
blt- cr5,L_co_switch$store_environ
beq cr6,L_co_switch$store_environ
oris r8,r8,0x4000 ;set the flag to say we have it!
L_co_switch$store_environ:
stw r8,lo16(_co_environ-L_co_switch$spb)(r29) ;store environment flags
L_co_switch$initialised:
andis. r10,r8,0x4000 ;do we have Altivec/VMX?
beq L_co_switch$save_no_vmx
mfspr r11,256 ;save VRSAVE
andi. r0,r11,0x0FFF ;short-circuit if it's zero
stw r11,240(r1)
beq L_co_switch$save_no_vmx
andi. r0,r11,0x0800 ;check bit 20
addi r2,0,48 ;starting index
beq L_co_switch$save_skip_vr20
stvx v20,r1,r2 ;save VR20
L_co_switch$save_skip_vr20:
addi r2,r2,16 ;stride
andi. r0,r11,0x0400 ;check bit 21
beq L_co_switch$save_skip_vr21
stvx v21,r1,r2 ;save VR21
L_co_switch$save_skip_vr21:
addi r2,r2,16 ;stride
andi. r0,r11,0x0200 ;check bit 22
beq L_co_switch$save_skip_vr22
stvx v22,r1,r2 ;save VR22
L_co_switch$save_skip_vr22:
addi r2,r2,16 ;stride
andi. r0,r11,0x0100 ;check bit 23
beq L_co_switch$save_skip_vr23
stvx v23,r1,r2 ;save VR23
L_co_switch$save_skip_vr23:
addi r2,r2,16 ;stride
andi. r0,r11,0x0080 ;check bit 24
beq L_co_switch$save_skip_vr24
stvx v24,r1,r2 ;save VR24
L_co_switch$save_skip_vr24:
addi r2,r2,16 ;stride
andi. r0,r11,0x0040 ;check bit 25
beq L_co_switch$save_skip_vr25
stvx v25,r1,r2 ;save VR25
L_co_switch$save_skip_vr25:
addi r2,r2,16 ;stride
andi. r0,r11,0x0020 ;check bit 26
beq L_co_switch$save_skip_vr26
stvx v26,r1,r2 ;save VR26
L_co_switch$save_skip_vr26:
addi r2,r2,16 ;stride
andi. r0,r11,0x0010 ;check bit 27
beq L_co_switch$save_skip_vr27
stvx v27,r1,r2 ;save VR27
L_co_switch$save_skip_vr27:
addi r2,r2,16 ;stride
andi. r0,r11,0x0008 ;check bit 28
beq L_co_switch$save_skip_vr28
stvx v28,r1,r2 ;save VR28
L_co_switch$save_skip_vr28:
addi r2,r2,16 ;stride
andi. r0,r11,0x0004 ;check bit 29
beq L_co_switch$save_skip_vr29
stvx v29,r1,r2 ;save VR29
L_co_switch$save_skip_vr29:
addi r2,r2,16 ;stride
andi. r0,r11,0x0002 ;check bit 30
beq L_co_switch$save_skip_vr30
stvx v30,r1,r2 ;save VR30
L_co_switch$save_skip_vr30:
addi r2,r2,16 ;stride
andi. r0,r11,0x0001 ;check bit 31
beq L_co_switch$save_skip_vr31
stvx v31,r1,r2 ;save VR31
L_co_switch$save_skip_vr31:
L_co_switch$save_no_vmx:
addis r4,r31,ha16(_co_active_context-L_co_switch$spb) ;save current context
ld r5,lo16(_co_active_context-L_co_switch$spb)(r4)
std r30,lo16(_co_active_context-L_co_switch$spb)(r4);set new context
std r1,0(r5) ;save current stack pointer
ld r1,0(r30) ;get new stack pointer
lwz r12,8(r30) ;have we already set GPR13 (system TLS)?
andis. r0,r12,0x8000
beq+ L_co_switch$gpr13_set
std r13,392(r1)
xoris r12,r12,0x8000
stw r12,8(r30)
L_co_switch$gpr13_set:
andis. r10,r8,0x4000 ;do we have Altivec/VMX?
beq L_co_switch$restore_no_vmx
lwz r11,240(r1) ;restore VRSAVE
andi. r0,r11,0x0FFF ;short-circuit if it's zero
mtspr 256,r11
beq L_co_switch$restore_no_vmx
andi. r0,r11,0x0800 ;check bit 20
addi r2,0,48 ;starting index
beq L_co_switch$restore_skip_vr20
lvx v20,r1,r2 ;restore VR20
L_co_switch$restore_skip_vr20:
addi r2,r2,16 ;stride
andi. r0,r11,0x0400 ;check bit 21
beq L_co_switch$restore_skip_vr21
lvx v21,r1,r2 ;restore VR21
L_co_switch$restore_skip_vr21:
addi r2,r2,16 ;stride
andi. r0,r11,0x0200 ;check bit 22
beq L_co_switch$restore_skip_vr22
lvx v22,r1,r2 ;restore VR22
L_co_switch$restore_skip_vr22:
addi r2,r2,16 ;stride
andi. r0,r11,0x0100 ;check bit 23
beq L_co_switch$restore_skip_vr23
lvx v23,r1,r2 ;restore VR23
L_co_switch$restore_skip_vr23:
addi r2,r2,16 ;stride
andi. r0,r11,0x0080 ;check bit 24
beq L_co_switch$restore_skip_vr24
lvx v24,r1,r2 ;restore VR24
L_co_switch$restore_skip_vr24:
addi r2,r2,16 ;stride
andi. r0,r11,0x0040 ;check bit 25
beq L_co_switch$restore_skip_vr25
lvx v25,r1,r2 ;restore VR25
L_co_switch$restore_skip_vr25:
addi r2,r2,16 ;stride
andi. r0,r11,0x0020 ;check bit 26
beq L_co_switch$restore_skip_vr26
lvx v26,r1,r2 ;restore VR26
L_co_switch$restore_skip_vr26:
addi r2,r2,16 ;stride
andi. r0,r11,0x0010 ;check bit 27
beq L_co_switch$restore_skip_vr27
lvx v27,r1,r2 ;restore VR27
L_co_switch$restore_skip_vr27:
addi r2,r2,16 ;stride
andi. r0,r11,0x0008 ;check bit 28
beq L_co_switch$restore_skip_vr28
lvx v28,r1,r2 ;restore VR28
L_co_switch$restore_skip_vr28:
addi r2,r2,16 ;stride
andi. r0,r11,0x0004 ;check bit 29
beq L_co_switch$restore_skip_vr29
lvx v29,r1,r2 ;restore VR29
L_co_switch$restore_skip_vr29:
addi r2,r2,16 ;stride
andi. r0,r11,0x0002 ;check bit 30
beq L_co_switch$restore_skip_vr30
lvx v30,r1,r2 ;restore VR30
L_co_switch$restore_skip_vr30:
addi r2,r2,16 ;stride
andi. r0,r11,0x0001 ;check bit 31
beq L_co_switch$restore_skip_vr31
lvx v31,r1,r2 ;restore VR31
L_co_switch$restore_skip_vr31:
L_co_switch$restore_no_vmx:
lfd f14,248(r1) ;restore preserved FPRs
lfd f15,256(r1)
lfd f16,264(r1)
lfd f17,272(r1)
lfd f18,280(r1)
lfd f19,288(r1)
lfd f20,296(r1)
lfd f21,304(r1)
lfd f22,312(r1)
lfd f23,320(r1)
lfd f24,328(r1)
lfd f25,336(r1)
lfd f26,344(r1)
lfd f27,352(r1)
lfd f28,360(r1)
lfd f29,368(r1)
lfd f30,376(r1)
lfd f31,384(r1)
addi r0,0,0 ;make thread main crash if it returns
ld r1,0(r1) ;deallocate stack frame
ld r6,16(r1) ;return address in GPR6
lwz r7,8(r1) ;condition codes in GPR7
ld r13,-152(r1) ;restore preserved GPRs
ld r14,-144(r1)
ld r15,-136(r1)
ld r16,-128(r1)
ld r17,-120(r1)
ld r18,-112(r1)
ld r19,-104(r1)
ld r20,-96(r1)
ld r21,-88(r1)
ld r22,-80(r1)
ld r23,-72(r1)
ld r24,-64(r1)
ld r25,-56(r1)
ld r26,-48(r1)
ld r27,-40(r1)
ld r28,-32(r1)
ld r29,-24(r1)
ld r30,-16(r1)
ld r31,-8(r1)
mtlr r0
mtctr r6 ;restore return address
mtcrf 32,r7 ;restore preserved condition codes
mtcrf 16,r7
mtcrf 8,r7
bctr ;return
;Import external functions
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.align 5
L_malloc$stub:
.indirect_symbol _malloc
mflr r0
bcl 20,31,L_malloc$spb
L_malloc$spb:
mflr r11
addis r11,r11,ha16(L_malloc$lazy_ptr-L_malloc$spb)
mtlr r0
ldu r12,lo16(L_malloc$lazy_ptr-L_malloc$spb)(r11)
mtctr r12
bctr
.lazy_symbol_pointer
L_malloc$lazy_ptr:
.indirect_symbol _malloc
.quad dyld_stub_binding_helper
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.align 5
L_free$stub:
.indirect_symbol _free
mflr r0
bcl 20,31,L_free$spb
L_free$spb:
mflr r11
addis r11,r11,ha16(L_free$lazy_ptr-L_free$spb)
mtlr r0
ldu r12,lo16(L_free$lazy_ptr-L_free$spb)(r11)
mtctr r12
bctr
.lazy_symbol_pointer
L_free$lazy_ptr:
.indirect_symbol _free
.quad dyld_stub_binding_helper
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.align 5
L_sysctlbyname$stub:
.indirect_symbol _sysctlbyname
mflr r0
bcl 20,31,L_sysctlbyname$spb
L_sysctlbyname$spb:
mflr r11
addis r11,r11,ha16(L_sysctlbyname$lazy_ptr-L_sysctlbyname$spb)
mtlr r0
ldu r12,lo16(L_sysctlbyname$lazy_ptr-L_sysctlbyname$spb)(r11)
mtctr r12
bctr
.lazy_symbol_pointer
L_sysctlbyname$lazy_ptr:
.indirect_symbol _sysctlbyname
.quad dyld_stub_binding_helper
;This needs to be here!
.subsections_via_symbols
-102
View File
@@ -1,102 +0,0 @@
/*
libco.sjlj (2008-01-28)
author: Nach
license: public domain
*/
/*
* Note this was designed for UNIX systems. Based on ideas expressed in a paper
* by Ralf Engelschall.
* For SJLJ on other systems, one would want to rewrite springboard() and
* co_create() and hack the jmb_buf stack pointer.
*/
#define LIBCO_C
#include "libco.h"
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
sigjmp_buf context;
void (*coentry)(void);
void *stack;
} cothread_struct;
static thread_local cothread_struct co_primary;
static thread_local cothread_struct *creating, *co_running = 0;
static void springboard(int ignored) {
if(sigsetjmp(creating->context, 0)) {
co_running->coentry();
}
}
cothread_t co_active() {
if(!co_running) co_running = &co_primary;
return (cothread_t)co_running;
}
cothread_t co_create(unsigned int size, void (*coentry)(void)) {
if(!co_running) co_running = &co_primary;
cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct));
if(thread) {
struct sigaction handler;
struct sigaction old_handler;
stack_t stack;
stack_t old_stack;
thread->coentry = thread->stack = 0;
stack.ss_flags = 0;
stack.ss_size = size;
thread->stack = stack.ss_sp = malloc(size);
if(stack.ss_sp && !sigaltstack(&stack, &old_stack)) {
handler.sa_handler = springboard;
handler.sa_flags = SA_ONSTACK;
sigemptyset(&handler.sa_mask);
creating = thread;
if(!sigaction(SIGUSR1, &handler, &old_handler)) {
if(!raise(SIGUSR1)) {
thread->coentry = coentry;
}
sigaltstack(&old_stack, 0);
sigaction(SIGUSR1, &old_handler, 0);
}
}
if(thread->coentry != coentry) {
co_delete(thread);
thread = 0;
}
}
return (cothread_t)thread;
}
void co_delete(cothread_t cothread) {
if(cothread) {
if(((cothread_struct*)cothread)->stack) {
free(((cothread_struct*)cothread)->stack);
}
free(cothread);
}
}
void co_switch(cothread_t cothread) {
if(!sigsetjmp(co_running->context, 0)) {
co_running = (cothread_struct*)cothread;
siglongjmp(co_running->context, 1);
}
}
#ifdef __cplusplus
}
#endif
-67
View File
@@ -1,67 +0,0 @@
/*
libco.ucontext (2008-01-28)
author: Nach
license: public domain
*/
/*
* WARNING: the overhead of POSIX ucontext is very high,
* assembly versions of libco or libco_sjlj should be much faster
*
* This library only exists for two reasons:
* 1 - as an initial test for the viability of a ucontext implementation
* 2 - to demonstrate the power and speed of libco over existing implementations,
* such as pth (which defaults to wrapping ucontext on unix targets)
*
* Use this library only as a *last resort*
*/
#define LIBCO_C
#include "libco.h"
#include <stdlib.h>
#include <ucontext.h>
#ifdef __cplusplus
extern "C" {
#endif
static thread_local ucontext_t co_primary;
static thread_local ucontext_t *co_running = 0;
cothread_t co_active() {
if(!co_running) co_running = &co_primary;
return (cothread_t)co_running;
}
cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) {
if(!co_running) co_running = &co_primary;
ucontext_t *thread = (ucontext_t*)malloc(sizeof(ucontext_t));
if(thread) {
if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) {
thread->uc_link = co_running;
thread->uc_stack.ss_size = heapsize;
makecontext(thread, coentry, 0);
} else {
co_delete((cothread_t)thread);
thread = 0;
}
}
return (cothread_t)thread;
}
void co_delete(cothread_t cothread) {
if(cothread) {
if(((ucontext_t*)cothread)->uc_stack.ss_sp) { free(((ucontext_t*)cothread)->uc_stack.ss_sp); }
free(cothread);
}
}
void co_switch(cothread_t cothread) {
ucontext_t *old_thread = co_running;
co_running = (ucontext_t*)cothread;
swapcontext(old_thread, co_running);
}
#ifdef __cplusplus
}
#endif
-93
View File
@@ -1,93 +0,0 @@
/*
libco.x86 (2009-10-12)
author: byuu
license: public domain
*/
#define LIBCO_C
#include "libco.h"
#include <assert.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_MSC_VER)
#define fastcall __fastcall
#elif defined(__GNUC__)
#define fastcall __attribute__((fastcall))
#else
#error "libco: please define fastcall macro"
#endif
static thread_local long co_active_buffer[64];
static thread_local cothread_t co_active_handle = 0;
static void (fastcall *co_swap)(cothread_t, cothread_t) = 0;
//ABI: fastcall
static unsigned char co_swap_function[] = {
0x89, 0x22, 0x8B, 0x21, 0x58, 0x89, 0x6A, 0x04, 0x89, 0x72, 0x08, 0x89, 0x7A, 0x0C, 0x89, 0x5A,
0x10, 0x8B, 0x69, 0x04, 0x8B, 0x71, 0x08, 0x8B, 0x79, 0x0C, 0x8B, 0x59, 0x10, 0xFF, 0xE0,
};
#ifdef _WIN32
#include <windows.h>
void co_init() {
DWORD old_privileges;
VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges);
}
#else
#include <unistd.h>
#include <sys/mman.h>
void co_init() {
unsigned long addr = (unsigned long)co_swap_function;
unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE));
unsigned long size = (addr - base) + sizeof co_swap_function;
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
}
#endif
static void crash() {
assert(0); /* called only if cothread_t entrypoint returns */
}
cothread_t co_active() {
if(!co_active_handle) co_active_handle = &co_active_buffer;
return co_active_handle;
}
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
cothread_t handle;
if(!co_swap) {
co_init();
co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function;
}
if(!co_active_handle) co_active_handle = &co_active_buffer;
size += 256; /* allocate additional space for storage */
size &= ~15; /* align stack to 16-byte boundary */
if(handle = (cothread_t)malloc(size)) {
long *p = (long*)((char*)handle + size); /* seek to top of stack */
*--p = (long)crash; /* crash if entrypoint returns */
*--p = (long)entrypoint; /* start of function */
*(long*)handle = (long)p; /* stack pointer */
}
return handle;
}
void co_delete(cothread_t handle) {
free(handle);
}
void co_switch(cothread_t handle) {
register cothread_t co_previous_handle = co_active_handle;
co_swap(co_active_handle = handle, co_previous_handle);
}
#ifdef __cplusplus
}
#endif
+214
View File
@@ -0,0 +1,214 @@
/* bsnes
project started: 10/14/2004
author: byuu */
#include "base.h"
#include "main.h"
#include "timing/timing.h"
#include "cpu/g65816.h"
#include "apu/spc700.h"
#include "bridge/bridge.h"
extern snes_timer *snes_time;
extern g65816 *gx816;
extern sony_spc700 *spc700;
extern ppustate ppu;
extern port_bridge *cpu_apu_bridge;
debugstate debugger;
void debug_test_breakpoint_hit(byte source, byte flag, ulong offset, byte value, int i) {
dprintf("* breakpoint %d hit", i);
debugger.bp_list[i].hit_count++;
debugger.refresh_bp = true;
debug_set_state(DEBUGMODE_WAIT);
if(source == BPSRC_SPCRAM) {
disas_spc700_op();
} else {
disas_g65816_op();
}
}
void debug_test_breakpoint(byte source, byte flag, ulong offset, byte value) {
int i;
if(debug_get_state() == DEBUGMODE_DISABLED)return;
for(i=0;i<16;i++) {
if(debugger.bp_list[i].source != source)continue;
if(debugger.bp_list[i].flags & flag) {
if(debugger.bp_list[i].offset == offset) {
if(debugger.bp_list[i].flags & BP_VAL) {
if(debugger.bp_list[i].value == value) {
debug_test_breakpoint_hit(source, flag, offset, value, i);
}
} else {
debug_test_breakpoint_hit(source, flag, offset, value, i);
}
}
}
}
}
ulong debug_write_status(void) {
if(debugger_enabled() == false)return DEBUGWRITE_NONE;
if(debug_get_state() == DEBUGMODE_RUN) {
if(debugger.trace_enabled == false)return DEBUGWRITE_NONE;
if(debugger.trace_output_enabled == true) {
return DEBUGWRITE_CONSOLE | DEBUGWRITE_TRACE;
}
return DEBUGWRITE_TRACE;
}
return DEBUGWRITE_CONSOLE;
}
void init_debugstate(void) {
debugger.mode = DEBUGMODE_DISABLED;
debugger.mem_ptr = 0x7e0000;
debugger.disas_cpu_op = true;
debugger.disas_apu_op = true;
debugger.refresh_mem = true;
debugger.refresh_bp = true;
debugger.refresh_status = true;
debugger.cpu_op_executed = false;
debugger.apu_op_executed = false;
debugger.output_cpu_instrs = true;
debugger.output_apu_instrs = true;
debugger.output_debug_info = true;
debugger.trace_enabled = false;
debugger.trace_output_enabled = false;
debugger.lock_up = debugger.lock_down = debugger.lock_left = debugger.lock_right = false;
debugger.lock_a = debugger.lock_b = debugger.lock_x = debugger.lock_y = false;
debugger.lock_l = debugger.lock_r = debugger.lock_select = debugger.lock_start = false;
}
void RunSNES(void) {
if(emu_state.rom_loaded == false)return;
if(debugger_enabled() == false) {
gx816->Run();
spc700->Run();
return;
}
if(debug_get_state() == DEBUGMODE_RUN) {
gx816->Run();
spc700->Run();
if(debugger.trace_enabled == true) {
if(debugger.disas_cpu_op == true) {
disas_g65816_op();
debugger.disas_cpu_op = false;
}
if(debugger.disas_apu_op == true) {
disas_spc700_op();
debugger.disas_apu_op = false;
}
}
} else {
if(debugger.disas_cpu_op == true) {
disas_g65816_op();
debugger.disas_cpu_op = false;
}
if(debugger.disas_apu_op == true) {
disas_spc700_op();
debugger.disas_apu_op = false;
}
if(debugger.refresh_mem == true) {
debug_refresh_mem();
debugger.refresh_mem = false;
}
if(debugger.refresh_bp == true) {
debug_refresh_bp();
debugger.refresh_bp = false;
}
if(debugger.refresh_status == true) {
debug_update_status();
debugger.refresh_status = false;
}
if(debug_get_state() == DEBUGMODE_WAIT)return;
if(debug_get_state() == DEBUGMODE_CPUSTEP) {
gx816->Run();
spc700->Run();
if(debugger.cpu_op_executed == true) {
debug_set_state(DEBUGMODE_WAIT);
}
}
if(debug_get_state() == DEBUGMODE_APUSTEP) {
gx816->Run();
spc700->Run();
if(debugger.apu_op_executed == true) {
debug_set_state(DEBUGMODE_WAIT);
}
}
}
debug_update_status();
}
extern vfunc spc700_optbl[256];
void InitSNES(void) {
int i, z;
snes_time = new snes_timer();
gx816 = new g65816();
gx816->PowerOn(1);
spc700 = new sony_spc700();
spc700->Reset();
snes_time->reset_clock();
cpu_apu_bridge = new port_bridge();
if(*emu_state.rom_name == 0) {
emu_state.rom_loaded = false;
} else {
gx816->LoadROM();
emu_state.rom_loaded = true;
}
for(i=0;i<16;i++) {
debugger.bp_list[i].offset = 0;
debugger.bp_list[i].flags = BP_OFF;
debugger.bp_list[i].source = BPSRC_MEM;
debugger.bp_list[i].value = 0;
debugger.bp_list[i].hit_count = 0;
}
}
void ResetSNES(void) {
int i;
gx816->Reset();
spc700->Reset();
snes_time->reset_clock();
for(i=0;i<16;i++) {
debugger.bp_list[i].offset = 0;
debugger.bp_list[i].flags = BP_OFF;
debugger.bp_list[i].source = BPSRC_MEM;
debugger.bp_list[i].value = 0;
debugger.bp_list[i].hit_count = 0;
}
}
#include <windows.h>
int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
char fn[MAX_PATH];
strcpy(fn, lpcmdline);
//remove quotes from filename, if neccesary (if path contains spaces, quotes will be around command line arg)
if(*fn == '\"') {
strcpy(emu_state.rom_name, fn + 1);
emu_state.rom_name[strlen(emu_state.rom_name) - 1] = 0;
} else {
strcpy(emu_state.rom_name, fn);
}
//create save ram file name
strcpy(emu_state.sram_name, emu_state.rom_name);
if(strlen(emu_state.sram_name) > 4) {
emu_state.sram_name[strlen(emu_state.sram_name) - 4] = 0;
}
strcat(emu_state.sram_name, ".srm");
init_debugstate();
__winmain(); //located in win/gui.cpp
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
void __winmain(void);
/*
*1 - how many instructions to execute before saving sram data
to emu_state.sram_name
*/
emustate emu_state = {
false, //rom loaded
20000000, //sram save tick count *1
"", "" //rom name, sram name
};
videostate render = {
512, 448, //display resolution
256, 224, //snes internal resolution
false, //fullscreen
true, //show menu
0, //frame skip
0, //frame count
{ true, true, true }, //bg1 enable
{ true, true, true }, //bg2 enable
{ true, true, true }, //bg3 enable
{ true, true, true }, //bg4 enable
{ true, true, true, true, true } //oam enable
};
+434
View File
@@ -0,0 +1,434 @@
#include "../base.h"
#include "../cpu/g65816.h"
#include "../timing/timing.h"
extern g65816 *gx816;
extern emustate emu_state;
extern debugstate debugger;
extern snes_timer *snes_time;
void g65816::InitializeROM(byte memory_map) {
memset(rom, 0, 0x600000);
map = memory_map;
}
void g65816::InitializeWRAM(byte value) {
memset(wram, value, 0x020000);
memset(sram, 0x00, 0x0e0000);
}
/***********************
*** SNES Memory Map ***
**************************************************
*** 00-3f 0000-1fff First 8k WRAM ***
*** 2000-5fff MMIO ***
*** 6000-7fff Expansion RAM (Unmapped) ***
*** 8000-ffff Cartridge ROM ***
*** 40-7d 0000-ffff Cartridge ROM ***
*** 7e-7f 0000-ffff 128k WRAM ***
*** 80-bf 0000-1fff First 8k WRAM ***
*** 2000-5fff MMIO ***
*** 6000-7fff Expansion RAM (Unmapped) ***
*** 8000-ffff Cartridge ROM ***
*** c0-ff 0000-ffff Cartridge ROM ***
**************************************************/
ulong g65816::mirror_offset(ulong addr) {
byte db;
word a;
ulong r = 0;
db = (addr >> 16) & 0xff;
a = (addr & 0xffff);
if(db >= 0x00 && db <= 0x3f) {
if(a >= 0x0000 && a <= 0x1fff) {
r = 0x7e0000 | (a & 0x1fff);
} else if(a >= 0x2000 && a <= 0x5fff) {
r = a;
} else if(a >= 0x6000 && a <= 0x7fff) {
r = (db << 16) | a;
} else if(a >= 0x8000 && a <= 0xffff) {
r = (db << 16) | a;
}
} else if(db >= 0x40 && db <= 0x7d) {
r = (db << 16) | a;
} else if(db >= 0x7e && db <= 0x7f) {
r = addr;
} else if(db >= 0x80 && db <= 0xbf) {
if(a >= 0x0000 && a <= 0x1fff) {
r = 0x7e0000 | (a & 0x1fff);
} else if(a >= 0x2000 && a <= 0x5fff) {
r = a;
} else if(a >= 0x6000 && a <= 0x7fff) {
r = (db << 16) | a;
} else if(a >= 0x8000 && a <= 0xffff) {
r = ((db & 0x7f) << 16) | a;
}
} else if(db >= 0xc0 && db <= 0xff) {
r = addr;
}
return r;
}
ulong g65816::convert_offset(byte read_mode, ulong addr, bool mirror) {
byte db;
switch(read_mode) {
case MEMMODE_DP:
addr = (regs.d + (addr & 0xffff)) & 0xffff;
break;
case MEMMODE_DPX:
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
break;
case MEMMODE_DPY:
addr = (regs.d + regs.y + (addr & 0xffff)) & 0xffff;
break;
case MEMMODE_IDP:
addr = (regs.d + (addr & 0xffff)) & 0xffff;
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
addr |= (regs.db << 16);
break;
case MEMMODE_IDPX:
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
addr |= (regs.db << 16);
break;
case MEMMODE_IDPY:
addr = (regs.d + (addr & 0xffff)) & 0xffff;
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
addr += (regs.db << 16) + regs.y;
break;
case MEMMODE_ILDP:
addr = (regs.d + (addr & 0xffff));
addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
break;
case MEMMODE_ILDPY:
addr = (regs.d + (addr & 0xffff));
addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
addr += regs.y;
break;
case MEMMODE_ADDR:
addr = addr & 0xffff;
addr |= (regs.db << 16);
break;
case MEMMODE_ADDR_PC:
addr = addr & 0xffff;
addr |= (regs.pc & 0xff0000);
break;
case MEMMODE_ADDRX:
addr = (regs.db << 16) + (addr & 0xffff);
addr += regs.x;
break;
case MEMMODE_ADDRY:
addr = (regs.db << 16) + (addr & 0xffff);
addr += regs.y;
break;
case MEMMODE_IADDRX:
addr += regs.x;
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, (addr & 0x00ffff));
addr |= (regs.pc & 0xff0000);
break;
case MEMMODE_ILADDR:
addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
break;
case MEMMODE_IADDR_PC:
addr |= (regs.pc & 0xff0000);
break;
case MEMMODE_IADDRX_PC:
addr += regs.x;
addr |= (regs.pc & 0xff0000);
break;
case MEMMODE_ILADDR_PC:
break;
case MEMMODE_LONG:
break;
case MEMMODE_LONGX:
addr += regs.x;
break;
case MEMMODE_SR:
addr = (regs.s + (addr & 0xff)) & 0xffff;
break;
case MEMMODE_ISRY:
addr = (regs.s + (addr & 0xff)) & 0xffff;
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
addr += (regs.db << 16) + regs.y;
break;
case OPMODE_ADDR:
addr &= 0xffff;
break;
case OPMODE_LONG:
addr &= 0xffffff;
break;
case OPMODE_DBR:
addr = (regs.db << 16) + addr;
break;
case OPMODE_PBR:
addr = (regs.pc & 0xff0000) | (addr & 0xffff);
break;
case OPMODE_DP:
addr = (regs.d + (addr & 0xffff)) & 0xffff;
break;
case OPMODE_SP:
addr = (regs.s + (addr & 0xffff)) & 0xffff;
break;
}
if(mirror == true) {
return mirror_offset(addr);
} else {
return addr;
}
}
ulong g65816::read_operand(byte size) {
ulong r;
r = gx816->mem_read(MEMMODE_NONE, size, gx816->regs.pc + 1);
//add size + 1 cycles. the extra cycle is for the actual opcode
//byte itself being read in by the main cpu emulation routine.
snes_time->add_cpu_pcycles(size + 1);
return r;
}
byte g65816::mem_getbyte_direct(ulong addr, byte access_mode) {
byte db;
word a;
db = (addr >> 16) & 0xff;
a = (addr & 0xffff);
if(db == 0x00 && a >= 0x2000 && a <= 0x5fff) {
if(access_mode == MEMACCESS_DEBUGGER) {
return 0x00;
} else {
return mmio_read(addr);
}
}
if(db == 0x7e || db == 0x7f) {
return wram[addr & 0x01ffff];
} else if(db != 0x7e && db != 0x7f && a >= 0x8000 && a <= 0xffff) {
return rom_read(addr, MEMSIZE_BYTE);
} else if(db >= 0x30 && db <= 0x3f) {
if(a >= 0x6000 && a <= 0x7fff) {
addr = ((db - 0x30) * 0x2000) + (a - 0x6000);
addr &= (sram_size - 1);
return sram[addr];
}
} else if(db >= 0x70 && db <= 0x7d) {
addr -= 0x700000;
addr &= (sram_size - 1);
return sram[addr];
} else if(db >= 0xc0 && db <= 0xff) {
return rom_read(addr, MEMSIZE_BYTE);
}
return 0;
}
byte g65816::mem_getbyte(ulong addr, byte access_mode) {
int i;
byte r;
r = mem_getbyte_direct(addr, access_mode);
if(debug_get_state() == DEBUGMODE_DISABLED)return r;
if(access_mode == MEMACCESS_DEBUGGER)return r; //don't report breakpoint hits from debugger
debug_test_bp(BPSRC_MEM, BP_READ, addr, r);
return r;
}
void g65816::mem_putbyte_direct(ulong addr, byte value, byte access_mode) {
byte db;
word a;
db = (addr >> 16) & 0xff;
a = (addr & 0xffff);
if(db == 0x00 && a >= 0x2000 && a <= 0x5fff) {
mmio_write(a, value);
} else if(db == 0x7e || db == 0x7f) {
wram[addr & 0x01ffff] = value;
} else if(db >= 0x30 && db <= 0x3f) {
if(a >= 0x6000 && a <= 0x7fff) {
addr = ((db - 0x30) * 0x2000) + (a - 0x6000);
addr &= (sram_size - 1);
sram[addr] = value;
}
} else if(db >= 0x70 && db <= 0x7d) {
addr -= 0x700000;
addr &= (sram_size - 1);
sram[addr] = value;
}
if(access_mode == MEMACCESS_DEBUGGER) {
if(gx816->map == MEMMAP_LOROM) {
if((db >= 0x00 && db <= 0x5f) || (db >= 0x80 && db <= 0xdf)) {
if(addr >= 0x8000 && addr <= 0xffff) {
rom_write(addr, value, MEMSIZE_BYTE);
}
}
} else if(gx816->map == MEMMAP_HIROM) {
if(db >= 0xc0 && db <= 0xff) {
rom_write(addr, value, MEMSIZE_BYTE);
}
}
}
}
void g65816::mem_putbyte(ulong addr, byte value, byte access_mode) {
int i;
mem_putbyte_direct(addr, value, access_mode);
if(debug_get_state() == DEBUGMODE_DISABLED)return;
if(access_mode == MEMACCESS_DEBUGGER)return; //don't report breakpoint hits from debugger
debug_test_bp(BPSRC_MEM, BP_WRITE, addr, value);
}
ulong g65816::mem_read(byte read_mode, byte read_size, ulong addr, byte access_mode) {
ulong r;
addr = convert_offset(read_mode, addr);
switch(read_size) {
case MEMSIZE_BYTE:
r = mem_getbyte(addr, access_mode);
break;
case MEMSIZE_WORD:
r = mem_getbyte(addr, access_mode) |
mem_getbyte(addr+1, access_mode)<<8;
break;
case MEMSIZE_LONG:
r = mem_getbyte(addr, access_mode) |
mem_getbyte(addr+1, access_mode)<<8 |
mem_getbyte(addr+2, access_mode)<<16;
break;
}
return r;
}
void g65816::mem_write(byte write_mode, byte write_size, ulong addr, ulong value, byte access_mode) {
addr = convert_offset(write_mode, addr);
switch(write_size) {
case MEMSIZE_BYTE:
mem_putbyte(addr, value, access_mode);
break;
case MEMSIZE_WORD:
mem_putbyte(addr, value, access_mode);
mem_putbyte(addr+1, value>>8, access_mode);
break;
case MEMSIZE_LONG:
mem_putbyte(addr, value, access_mode);
mem_putbyte(addr+1, value>>8, access_mode);
mem_putbyte(addr+2, value>>16, access_mode);
break;
}
debugger.refresh_mem = true;
}
/*
todo: move address mirroring into mem_getbyte
in case there are different memory speeds depending
on pre-mirrored addresses.
*/
byte g65816::op_read(byte mode, ulong addr) {
byte r;
addr = convert_offset(mode, addr);
r = mem_getbyte(addr);
snes_time->add_cpu_mcycles(1, addr);
return r;
}
void g65816::op_write(byte mode, ulong addr, byte value) {
mem_putbyte(convert_offset(mode, addr), value);
snes_time->add_cpu_mcycles(1, addr);
}
byte g65816::stack_read(void) {
byte r;
gx816->regs.s++;
if(gx816->regs.e == true) {
gx816->regs.s = 0x0100 | (gx816->regs.s & 0xff);
}
r = mem_getbyte(convert_offset(OPMODE_SP, 0));
snes_time->add_cpu_mcycles(1, gx816->regs.s);
return r;
}
void g65816::stack_write(byte value) {
mem_putbyte(convert_offset(OPMODE_SP, 0), value);
gx816->regs.s--;
if(gx816->regs.e == true) {
gx816->regs.s = 0x0100 | (gx816->regs.s & 0xff);
}
snes_time->add_cpu_mcycles(1, gx816->regs.s);
}
/*
note: case 4 (write) condition is handled directly
in the opcode, since it is always true.
*/
void g65816::op_cond(byte c, ulong n0, ulong n1) {
switch(c) {
case 2: //dl != 0
if((regs.d & 0xff) != 0x00) {
snes_time->add_cpu_icycles(1);
}
break;
case 4: //read across page boundaries, write, or x=0
if((n0 & 0xff00) != (n1 & 0xff00) || !(gx816->regs.p & PF_X)) {
snes_time->add_cpu_icycles(1);
}
break;
}
}
ulong g65816::rom_read(ulong addr, byte read_size) {
ulong r;
if(map == MEMMAP_LOROM) {
if(read_size == MEMSIZE_BYTE) {
r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)];
} else if(read_size == MEMSIZE_WORD) {
r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] |
rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] << 8;
} else if(read_size == MEMSIZE_LONG) {
r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] |
rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] << 8 |
rom[(((addr + 2) & 0x7f0000) >> 1) | ((addr + 2) & 0x7fff)] << 16;
}
} else if(map == MEMMAP_HIROM) {
if(read_size == MEMSIZE_BYTE) {
r = rom[addr & 0x3fffff];
} else if(read_size == MEMSIZE_WORD) {
r = rom[addr & 0x3fffff] |
rom[(addr + 1) & 0x3fffff] << 8;
} else if(read_size == MEMSIZE_LONG) {
r = rom[addr & 0x3fffff] |
rom[(addr + 1) & 0x3fffff] << 8 |
rom[(addr + 2) & 0x3fffff] << 16;
}
}
return r;
}
void g65816::rom_write(ulong addr, ulong v, byte write_size) {
if(map == MEMMAP_LOROM) {
if(write_size == MEMSIZE_BYTE) {
rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
} else if(write_size == MEMSIZE_WORD) {
rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] = v >> 8;
} else if(write_size == MEMSIZE_LONG) {
rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] = v >> 8;
rom[(((addr + 2) & 0x7f0000) >> 1) | ((addr + 2) & 0x7fff)] = v >> 16;
}
} else if(map == MEMMAP_HIROM) {
if(write_size == MEMSIZE_BYTE) {
rom[addr & 0x3fffff] = v;
} else if(write_size == MEMSIZE_WORD) {
rom[addr & 0x3fffff] = v;
rom[(addr + 1) & 0x3fffff] = v >> 8;
} else if(write_size == MEMSIZE_LONG) {
rom[addr & 0x3fffff] = v;
rom[(addr + 1) & 0x3fffff] = v >> 8;
rom[(addr + 2) & 0x3fffff] = v >> 16;
}
}
}
+393
View File
@@ -0,0 +1,393 @@
#include "../base.h"
#include "libvlist.cpp"
typedef struct {
char *s;
ulong size;
}string;
typedef struct {
vectorlist list;
ulong count;
}stringlist;
/***********************
string library functions
***********************/
void strresize(string *str, ulong size) {
char *t;
int sl;
if(str->size == size)return;
sl = strlen(str->s);
t = (char*)malloc(size + 1);
strncpy(t, str->s, size);
free(str->s);
str->s = t;
str->size = size;
}
string *newstr(void) {
string *s;
s = (string*)malloc(sizeof(string));
s->size = 16;
s->s = (char*)malloc(s->size + 1);
*s->s = 0;
return s;
}
void memfree(string *s) {
if(s->s)free(s->s);
free(s);
}
/***************************
stringlist library functions
***************************/
void stradd(stringlist *sl, ulong num) {
int i;
string *s;
while(sl->count < (num + 1)) {
s = newstr();
sl->list.add((ulong)s);
sl->count++;
}
}
string *strget(stringlist *sl, ulong num) {
string *s;
if(sl->count < (num + 1)) { stradd(sl, num); }
s = (string*)sl->list.get(num);
return s;
}
stringlist *newstrlist(void) {
stringlist *sl;
sl = (stringlist*)malloc(sizeof(stringlist));
sl->count = 0;
stradd(sl, 1);
return sl;
}
ulong count(stringlist *sl) {
return sl->count;
}
/****************************
string manipulation functions
****************************/
char *strptr(string *s) { return s->s; }
char *strptr(stringlist *sl, ulong num) { return strget(sl, num)->s; }
void strcpy(string *dest, char *src) {
int srclen = strlen(src);
if(srclen > dest->size) { strresize(dest, srclen); }
strncpy(dest->s, src, dest->size);
}
void strcpy(string *dest, string *src) { strcpy(dest, src->s); }
void strcpy(stringlist *dest, ulong num, char *src) { strcpy(strget(dest, num), src); }
void strcpy(stringlist *dest, ulong num, string *src) { strcpy(strget(dest, num), src->s); }
void strcpy(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { strcpy(strget(dest, destnum), strptr(src, srcnum)); }
void strset(string *dest, ulong pos, byte c) {
char *s;
if(pos > dest->size) { strresize(dest, pos); }
dest->s[pos] = c;
}
void strset(stringlist *dest, ulong num, ulong pos, byte c) { strset(strget(dest, num), pos, c); }
void strcat(string *dest, char *src) {
int srclen, destlen;
srclen = strlen(src);
destlen = strlen(dest->s);
if(srclen + destlen > dest->size) { strresize(dest, srclen + destlen); }
strncat(dest->s, src, srclen + destlen);
}
void strcat(string *dest, string *src) { strcat(dest, src->s); }
void strcat(stringlist *dest, ulong num, char *src) { strcat(strget(dest, num), src); }
void strcat(stringlist *dest, ulong num, string *src) { strcat(strget(dest, num), src->s); }
void strcat(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { strcat(strget(dest, destnum), strptr(src, srcnum)); }
ulong strlen(string *s) { return strlen(s->s); }
ulong strlen(stringlist *sl, ulong num) { return strlen(strget(sl, num)->s); }
void strinsert(string *dest, char *src, ulong pos) {
string *s = newstr();
strcpy(s, strptr(dest)+pos);
strset(dest, pos, 0);
strcat(dest, src);
strcat(dest, s);
memfree(s);
}
void strinsert(string *dest, string *src, ulong pos) { strinsert(dest, src->s, pos); }
void strinsert(stringlist *dest, ulong num, char *src, ulong pos) { strinsert(strget(dest, num), src, pos); }
void strinsert(stringlist *dest, ulong num, string *src, ulong pos) { strinsert(strget(dest, num), src->s, pos); }
void strinsert(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum, ulong pos) { strinsert(strget(dest, destnum), strptr(src, srcnum), pos); }
void strremove(string *dest, ulong start, ulong length = 0) {
int destlen;
char *s;
int i, sl = strlen(dest->s);
if(start > dest->size) { strresize(dest, start); }
if(!length) {
strset(dest, start, 0);
return;
}
s = strptr(dest);
for(i=start;i<sl;i++) { s[i] = s[i+length]; }
s[i] = 0;
}
void strremove(stringlist *sl, ulong num, ulong start, ulong length = 0) { strremove(strget(sl, num), start, length); }
ulong strcmp(string *dest, char *src) { return strcmp(dest->s, src); }
ulong strcmp(string *dest, string *src) { return strcmp(dest->s, src->s); }
ulong strcmp(stringlist *dest, ulong num, char *src) { return strcmp(strget(dest, num)->s, src); }
ulong strcmp(stringlist *dest, ulong num, string *src) { return strcmp(strget(dest, num)->s, src->s); }
ulong strcmp(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strcmp(strget(dest, destnum)->s, strptr(src, srcnum)); }
ulong stricmp(char *dest, char *src) {
int i, sl = strlen(dest);
if(sl != strlen(src))return 1;
for(i=0;i<sl;i++) {
if(dest[i] >= 'A' && dest[i] <= 'Z') {
if(dest[i]!=src[i] && dest[i]+0x20!=src[i])return 1;
} else if(dest[i] >='a' && dest[i] <= 'z') {
if(dest[i]!=src[i] && dest[i]-0x20!=src[i])return 1;
} else {
if(dest[i] != src[i])return 1;
}
}
return 0;
}
ulong stricmp(string *dest, char *src) { return stricmp(dest->s, src); }
ulong stricmp(string *dest, string *src) { return stricmp(dest->s, src->s); }
ulong stricmp(stringlist *dest, ulong num, char *src) { return stricmp(strget(dest, num)->s, src); }
ulong stricmp(stringlist *dest, ulong num, string *src) { return stricmp(strget(dest, num)->s, src->s); }
ulong stricmp(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return stricmp(strget(dest, destnum)->s, strptr(src, srcnum)); }
void strlower(char *str) {
int i, sl = strlen(str);
for(i=0;i<sl;i++) { if(str[i] >= 'A' && str[i] <= 'Z')str[i] += 0x20; }
}
void strlower(string *str) { strlower(str->s); }
void strlower(stringlist *sl, ulong num) { strlower(strptr(sl, num)); }
void strupper(char *str) {
int i, sl = strlen(str);
for(i=0;i<sl;i++) { if(str[i] >='a' && str[i] <='z')str[i] -= 0x20; }
}
void strupper(string *str) { strupper(str->s); }
void strupper(stringlist *sl, ulong num) { strupper(strptr(sl, num)); }
ulong strpos(char *str, char *key) {
int i, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return null;
for(i=0;i<=ssl-ksl;i++) {
if(!memcmp(str+i, key, ksl))return i;
}
return null;
}
ulong strpos(string *dest, char *src) { return strpos(dest->s, src); }
ulong strpos(string *dest, string *src) { return strpos(dest->s, src->s); }
ulong strpos(stringlist *dest, ulong num, char *src) { return strpos(strget(dest, num)->s, src); }
ulong strpos(stringlist *dest, ulong num, string *src) { return strpos(strget(dest, num)->s, src->s); }
ulong strpos(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strpos(strget(dest, destnum)->s, strptr(src, srcnum)); }
ulong strpos_q(char *str, char *key) {
int i, z, ssl = strlen(str), ksl = strlen(key);
byte x;
if(ksl > ssl)return null;
for(i=0;i<=ssl-ksl;) {
x = str[i];
if(x == '\"' || x == '\'') {
z = i++;
while(str[i] != x && i < ssl)i++;
if(i >= ssl)i = z;
}
if(!memcmp(str+i, key, ksl)) {
return i;
} else {
i++;
}
}
return null;
}
ulong strpos_q(string *dest, char *src) { return strpos_q(dest->s, src); }
ulong strpos_q(string *dest, string *src) { return strpos_q(dest->s, src->s); }
ulong strpos_q(stringlist *dest, ulong num, char *src) { return strpos_q(strget(dest, num)->s, src); }
ulong strpos_q(stringlist *dest, ulong num, string *src) { return strpos_q(strget(dest, num)->s, src->s); }
ulong strpos_q(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strpos_q(strget(dest, destnum)->s, strptr(src, srcnum)); }
void strtr(char *dest, char *before, char *after) {
int i, l, sl = strlen(dest), bsl = strlen(before), asl = strlen(after);
if((bsl != asl) || bsl == 0)return;
for(i=0;i<sl;i++) {
for(l=0;l<bsl;l++) {
if(dest[i] == before[l])dest[i] = after[l];
}
}
}
void strtr(string *dest, char *before, char *after) { strtr(dest->s, before, after); }
void strtr(stringlist *dest, ulong num, char *before, char *after) { strtr(strptr(dest, num), before, after); }
ulong strbegin(char *str, char *key) {
int i, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return 1;
if(!memcmp(str, key, ksl))return 0;
return 1;
}
ulong strbegin(string *str, char *key) { return strbegin(str->s, key); }
ulong strbegin(stringlist *str, ulong num, char *key) { return strbegin(strptr(str, num), key); }
ulong stribegin(char *str, char *key) {
int i, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return 1;
for(i=0;i<ksl;i++) {
if(str[i] >= 'A' && str[i] <= 'Z') {
if(str[i] != key[i] && str[i]+0x20 != key[i])return 1;
} else if(str[i] >= 'a' && str[i] <= 'z') {
if(str[i] != key[i] && str[i]-0x20 != key[i])return 1;
} else {
if(str[i] != key[i])return 1;
}
}
return 0;
}
ulong stribegin(string *str, char *key) { return stribegin(str->s, key); }
ulong stribegin(stringlist *str, ulong num, char *key) { return stribegin(strptr(str, num), key); }
ulong strend(char *str, char *key) {
int i, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return 1;
if(!memcmp(str + ssl - ksl, key, ksl))return 0;
return 1;
}
ulong strend(string *str, char *key) { return strend(str->s, key); }
ulong strend(stringlist *str, ulong num, char *key) { return strend(strptr(str, num), key); }
ulong striend(char *str, char *key) {
int i, z, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return 1;
for(i=ssl-ksl, z=0;i<ssl;i++, z++) {
if(str[i] >= 'A' && str[i] <= 'Z') {
if(str[i] != key[z] && str[i]+0x20 != key[z])return 1;
} else if(str[i] >= 'a' && str[i] <= 'z') {
if(str[i] != key[z] && str[i]-0x20 != key[z])return 1;
} else {
if(str[i] != key[z])return 1;
}
}
return 0;
}
ulong striend(string *str, char *key) { return striend(str->s, key); }
ulong striend(stringlist *str, ulong num, char *key) { return striend(strptr(str, num), key); }
void strltrim(char *str, char *key) {
int i, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return;
if(!strbegin(str, key)) {
for(i=0;i<ssl-ksl;i++)str[i] = str[i + ksl];
str[i] = 0;
}
}
void strltrim(string *str, char *key) { strltrim(str->s, key); }
void strltrim(stringlist *str, ulong num, char *key) { strltrim(strptr(str, num), key); }
void striltrim(char *str, char *key) {
int i, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return;
if(!stribegin(str, key)) {
for(i=0;i<ssl-ksl;i++)str[i] = str[i + ksl];
str[i] = 0;
}
}
void striltrim(string *str, char *key) { striltrim(str->s, key); }
void striltrim(stringlist *str, ulong num, char *key) { striltrim(strptr(str, num), key); }
void strrtrim(char *str, char *key) {
int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return;
if(!strend(str, key)) {
str[ssl - ksl] = 0;
}
}
void strrtrim(string *str, char *key) { strrtrim(str->s, key); }
void strrtrim(stringlist *str, ulong num, char *key) { strrtrim(strptr(str, num), key); }
void strirtrim(char *str, char *key) {
int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return;
if(!striend(str, key)) {
str[ssl - ksl] = 0;
}
}
void strirtrim(string *str, char *key) { strirtrim(str->s, key); }
void strirtrim(stringlist *str, ulong num, char *key) { strirtrim(strptr(str, num), key); }
ulong strhex(char *str) {
ulong r = 0, m = 0;
int i, ssl = strlen(str);
byte x;
for(i=0;i<ssl;i++) {
if(str[i] >= '0' && str[i] <= '9');
else if(str[i] >= 'A' && str[i] <= 'F');
else if(str[i] >= 'a' && str[i] <= 'f');
else break;
}
for(--i;i>=0;i--, m+=4) {
x = str[i];
if(x >= '0' && x <= '9')x -= '0';
else if(x >= 'A' && x <= 'F')x -= 'A' - 0x0a;
else if(x >= 'a' && x <= 'f')x -= 'a' - 0x0a;
else return r;
r |= x << m;
}
return r;
}
ulong strhex(string *str) { return strhex(str->s); }
ulong strhex(stringlist *str, ulong num) { return strhex(strptr(str, num)); }
ulong strdec(char *str) {
ulong r = 0, m = 1;
int i, ssl = strlen(str);
byte x;
for(i=0;i<ssl;i++) {
if(str[i] >= '0' && str[i] <= '9');
else break;
}
for(--i;i>=0;i--, m*=10) {
x = str[i];
if(x >= '0' && x <= '9')x -= '0';
else return r;
r += x * m;
}
return r;
}
ulong strdec(string *str) { return strdec(str->s); }
ulong strdec(stringlist *str, ulong num) { return strdec(strptr(str, num)); }
ulong strbin(char *str) {
ulong r = 0, m = 0;
int i, ssl = strlen(str);
byte x;
for(i=0;i<ssl;i++) {
if(str[i] == '0' || str[i] == '1');
else break;
}
for(--i;i>=0;i--, m++) {
x = str[i];
if(str[i] == '0' || str[i] == '1')x -= '0';
else return r;
r |= x << m;
}
return r;
}
ulong strbin(string *str) { return strbin(str->s); }
ulong strbin(stringlist *str, ulong num) { return strbin(strptr(str, num)); }
#include "libstr_math.cpp"
#include "libstr_split.cpp"
#include "libstr_replace.cpp"
#include "libstr_sprintf.cpp"
+181
View File
@@ -0,0 +1,181 @@
#define STRMATH_ADD 1
#define STRMATH_SUB 2
#define STRMATH_MUL 3
#define STRMATH_DIV 4
#define STRMATH_MOD 5
#define STRMATH_AND 6
#define STRMATH_OR 7
#define STRMATH_XOR 8
#define STRMATH_SHL 9
#define STRMATH_SHR 10
#define STRMATH_LINKED 64
#define STRMATHMODE_NEG 1
#define STRMATHMODE_NOT 2
#define __strunktonum() \
if (s1[0] == '0' && s1[1] == 'x')r = strhex(s1 + 2); \
else if(s1[0] == '0' && s1[1] == 'b')r = strbin(s1 + 2); \
else r = strdec(s1)
#define __strmath_setmode() \
if (str[i] == '-') { mode = STRMATHMODE_NEG; i++; } \
else if(str[i] == '~') { mode = STRMATHMODE_NOT; i++; } \
else if(str[i] == '+') { i++; } \
else mode=0
#define __strmath_modeset() \
if (mode == STRMATHMODE_NEG)r *= -1; \
else if(mode == STRMATHMODE_NOT)r =~ r
#define __strmath_set(__x) \
s1[z] = 0; \
z = 0; \
__strunktonum(); \
__strmath_modeset(); \
array[array_size++] = r; \
array_gate[array_size] = __x
/***************************************
strmath(str)
resolves all math entities from within
str, and returns numerical result
example: strmath("5+5")=10
***************************************/
ulong p_strmath(char *str) {
int i = 0, ssl = strlen(str);
byte x, mode = 0;
ulong r, array[128], array_size = 0, z = 0;
byte array_gate[128];
char *s1;
if(!ssl)return 0;
s1 = (char*)malloc(ssl + 1);
__strmath_setmode();
while(i < ssl) {
x = str[i++];
if (x == '+') { __strmath_set(STRMATH_ADD); __strmath_setmode(); }
else if(x == '-') { __strmath_set(STRMATH_SUB); __strmath_setmode(); }
else if(x == '*') { __strmath_set(STRMATH_MUL); __strmath_setmode(); }
else if(x == '/') { __strmath_set(STRMATH_DIV); __strmath_setmode(); }
else if(x == '%') { __strmath_set(STRMATH_MOD); __strmath_setmode(); }
else if(x == '&') { __strmath_set(STRMATH_AND); __strmath_setmode(); }
else if(x == '|') { __strmath_set(STRMATH_OR ); __strmath_setmode(); }
else if(x == '^') { __strmath_set(STRMATH_XOR); __strmath_setmode(); }
else if(x == '<' && str[i] == '<') { __strmath_set(STRMATH_SHL); i++; __strmath_setmode(); }
else if(x == '>' && str[i] == '>') { __strmath_set(STRMATH_SHR); i++; __strmath_setmode(); }
else s1[z++] = x;
}
s1[z] = 0;
__strunktonum();
__strmath_modeset();
array[array_size++] = r;
free(s1);
for(i=1;i<array_size;i++) {
if (array_gate[i] == STRMATH_SHL) { array[i-1] <<= array[i]; array_gate[i] = STRMATH_LINKED; }
else if(array_gate[i] == STRMATH_SHR) { array[i-1] >>= array[i]; array_gate[i] = STRMATH_LINKED; }
}
for(i=1;i<array_size;i++) {
if (array_gate[i] == STRMATH_MUL) { array[i-1] *= array[i]; array_gate[i] = STRMATH_LINKED; }
else if(array_gate[i] == STRMATH_DIV) { array[i-1] /= array[i]; array_gate[i] = STRMATH_LINKED; }
}
r = array[0];
for(i=1;i<array_size;i++) {
if (array_gate[i] == STRMATH_ADD)r += array[i];
else if(array_gate[i] == STRMATH_SUB)r -= array[i];
else if(array_gate[i] == STRMATH_MOD)r %= array[i];
else if(array_gate[i] == STRMATH_AND)r &= array[i];
else if(array_gate[i] == STRMATH_OR )r |= array[i];
else if(array_gate[i] == STRMATH_XOR)r ^= array[i];
}
return r;
}
ulong strmath(char *in_str) {
ulong r = 0;
ulong pdepth = 0, cpdepth, maxpdepth = 0;
ulong pstart, pend, spos;
int i, sc, sl = strlen(in_str);
char *str = (char*)malloc(sl + 1), *str0;
char *pstr;
char num[64];
strcpy(str, in_str);
for(i=0;i<sl;i++) {
if(str[i]=='(') {
pdepth++;
if(pdepth > maxpdepth)maxpdepth = pdepth;
} else if(str[i]==')') {
if(pdepth == 0) {
free(str);
return null; //error! too many )'s
}
pdepth --;
}
}
if(pdepth != 0) {
free(str);
return null; //error! unequal ('s to )'s
}
pdepth = maxpdepth;
while(pdepth) {
cpdepth = 0;
for(i=0;i<sl;) {
if(str[i] == '(')cpdepth++;
if(str[i] == ')')cpdepth--;
i++;
if(cpdepth == pdepth) {
pstart = i;
while(str[i] != ')')i++;
pend = i;
pstr = (char*)malloc(pend-pstart+1);
memcpy(pstr, str+pstart, pend-pstart);
pstr[pend-pstart]=0;
r = p_strmath(pstr);
free(pstr);
sprintf(num, "%d", r);
str0 = (char*)malloc(sl + strlen(num) + 1);
memcpy(str0, str, pstart - 1);
spos = pstart - 1;
memcpy(str0+spos, num, strlen(num));
spos += strlen(num);
sc = spos;
memcpy(str0+spos, str+pend+1, sl-pend-1);
spos += sl - pend - 1;
sl = spos;
str0[sl] = 0;
free(str);
str = str0;
cpdepth--;
i = sc;
}
}
pdepth--;
}
r = p_strmath(str);
free(str);
return r;
}
ulong strmath(string *str) { return strmath(str->s); }
ulong strmath(stringlist *str, ulong num) { return strmath(strptr(str, num)); }
ulong strmathentity(char *str) {
int i, ssl = strlen(str);
for(i=0;i<ssl;i++) {
if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' ||
str[i] == '%' || str[i] == '&' || str[i] == '|' || str[i] == '^' ||
(str[i] == '<' && str[i+1] == '<') || (str[i] == '>' && str[i+1] == '>'))return 1;
}
return 0;
}
ulong strmathentity(string *str) { return strmathentity(str->s); }
ulong strmathentity(stringlist *str, ulong num) { return strmathentity(strptr(str, num)); }
+82
View File
@@ -0,0 +1,82 @@
void replace(string *str, char *key, char *token) {
int i, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str);
ulong replace_count = 0, size;
char *data;
if(ksl > ssl)return;
if(tsl > ksl) { //the new string may be longer than the old string...
for(i=0;i<=ssl-ksl;) { //so let's find out how big of a string we'll need...
if(!memcmp(str->s + i, key, ksl)) {
replace_count++;
i += ksl;
} else i++;
}
size = ssl + ((tsl - ksl) * replace_count);
if(size > str->size)strresize(str, size);
}
data = (char*)malloc(size + 1);
for(i=z=0;i<ssl;) {
if(i <= ssl - ksl) {
if(!memcmp(str->s + i, key, ksl)) {
memcpy(data + z, token, tsl);
z += tsl;
i += ksl;
} else data[z++] = str->s[i++];
} else data[z++] = str->s[i++];
}
data[z] = 0;
strcpy(str, data);
free(data);
}
void replace_q(string *str, char *key, char *token) {
int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str);
byte x;
ulong replace_count = 0, size;
char *data;
if(ksl > ssl)return;
if(tsl > ksl) {
for(i=0;i<=ssl-ksl;) {
x = str->s[i];
if(x == '\"' || x == '\'') {
l = i;
i++;
while(str->s[i++] != x) {
if(i == ssl) {
i = l;
break;
}
}
}
if(!memcmp(str->s + i, key, ksl)) {
replace_count++;
i += ksl;
} else i++;
}
size = ssl + ((tsl - ksl) * replace_count);
if(size > str->size)strresize(str, size);
}
data = (char*)malloc(size + 1);
for(i=z=0;i<ssl;) {
x = str->s[i];
if(x == '\"' || x == '\'') {
l = i++;
while(str->s[i] != x && i < ssl)i++;
if(i >= ssl)i = l;
else {
memcpy(data + z, str->s + l, i - l);
z += i - l;
}
}
if(i <= ssl - ksl) {
if(!memcmp(str->s + i, key, ksl)) {
memcpy(data + z, token, tsl);
z += tsl;
i += ksl;
replace_count++;
} else data[z++] = str->s[i++];
} else data[z++] = str->s[i++];
}
data[z] = 0;
strcpy(str, data);
free(data);
}
+41
View File
@@ -0,0 +1,41 @@
void split(stringlist *dest, char *key, char *src) {
int i, ssl = strlen(src), ksl = strlen(key);
byte x;
ulong lp = 0, split_count = 0;
for(i=0;i<=ssl-ksl;) {
if(!memcmp(src + i, key, ksl)) {
x = src[i];
src[i] = 0;
strcpy(dest, split_count++, src + lp);
src[i] = x;
i += ksl;
lp = i;
} else i++;
}
strcpy(dest, split_count++, src + lp);
}
void split(stringlist *dest, char *key, string *src) { split(dest, key, src->s); }
void split_q(stringlist *dest, char *key, char *src) {
int i, z, ssl = strlen(src), ksl = strlen(key);
byte x;
ulong lp = 0, split_count = 0;
for(i=0;i<=ssl-ksl;) {
x = src[i];
if(x=='\"' || x=='\'') {
z = i++;
while(src[i] != x && i < ssl)i++;
if(i >= ssl)i = z;
}
if(!memcmp(src + i, key, ksl)) {
x = src[i];
src[i] = 0;
strcpy(dest, split_count++, src + lp);
src[i] = x;
i += ksl;
lp = i;
} else i++;
}
strcpy(dest, split_count++, src + lp);
}
void split_q(stringlist *dest, char *key, string *src) { split_q(dest, key, src->s); }
+130
View File
@@ -0,0 +1,130 @@
void numtobin(char *s, ulong num) {
ulong mask = 0x80000000, len = 0, z = 0;
for(;mask;mask>>=1,len++) { if(num&mask)break; }
len = 32 - len;
do {
if(num&(1<<(len-1)))s[z++] = '1';
else s[z++] = '0';
}while(--len);
s[z] = 0;
}
void sprintf(string *str, char *s, ...) {
va_list args;
char t[2], n[256];
int i, l, sl, z;
byte pad_type, pad_len;
ulong num;
char *r;
va_start(args, s);
strcpy(str, "");
for(i=0;i<strlen(s);i++) {
if(s[i] == '%') {
i++;
if(s[i] == '0' && s[i+1] == '.' && (s[i+2] >= '0' && s[i+2] <= '9')) {
pad_type = 1;
if(s[i+3] >= '0' && s[i+3] <= '9') { pad_len = (s[i+2]-'0')*10 + (s[i+3]-'0'); i+=4; }
else { pad_len = (s[i+2]-'0'); i+=3; }
}
else if(s[i] >= '0' && s[i] <= '9') {
pad_type = 2;
if(s[i+1] >= '0' && s[i+1] <= '9') { pad_len = (s[i]-'0')*10 + (s[i+1]-'0'); i+=2; }
else { pad_len = (s[i]-'0'); i+=1; }
}
else { pad_type = 0; }
if(s[i] == 'd') {
num = va_arg(args, ulong);
sprintf(n, "%d", num);
} else if(s[i] == 'x') {
num = va_arg(args, ulong);
sprintf(n, "%x", num);
} else if(s[i] == 'b') {
num = va_arg(args, ulong);
numtobin(n, num);
} else if(s[i] == 's') {
r = va_arg(args, char*);
}
if(pad_type != 0) {
if(s[i] == 's')sl = strlen(r);
else sl = strlen(n);
if(sl < pad_len) {
while(sl < pad_len) {
strcat(str, (pad_type == 1)?"0":" ");
sl++;
}
}
}
if(s[i] == 's')strcat(str, r);
else strcat(str, n);
} else {
t[0] = s[i];
t[1] = 0;
strcat(str, t);
}
}
va_end(args);
}
void sprintf(stringlist *str_list, ulong str_num, char *s, ...) {
va_list args;
char t[2], n[256];
int i, l, sl, z;
byte pad_type, pad_len;
ulong num;
char *r;
string *str = strget(str_list, str_num);
va_start(args, s);
strcpy(str, "");
for(i=0;i<strlen(s);i++) {
if(s[i] == '%') {
i++;
if(s[i] == '0' && s[i+1] == '.' && (s[i+2] >= '0' && s[i+2] <= '9')) {
pad_type = 1;
if(s[i+3] >= '0' && s[i+3] <= '9') { pad_len = (s[i+2]-'0')*10 + (s[i+3]-'0'); i+=4; }
else { pad_len = (s[i+2]-'0'); i+=3; }
}
else if(s[i] >= '0' && s[i] <= '9') {
pad_type = 2;
if(s[i+1] >= '0' && s[i+1] <= '9') { pad_len = (s[i]-'0')*10 + (s[i+1]-'0'); i+=2; }
else { pad_len = (s[i]-'0'); i+=1; }
}
else { pad_type = 0; }
if(s[i] == 'd') {
num = va_arg(args, ulong);
sprintf(n, "%d", num);
} else if(s[i] == 'x') {
num = va_arg(args, ulong);
sprintf(n, "%x", num);
} else if(s[i] == 'b') {
num = va_arg(args, ulong);
numtobin(n, num);
} else if(s[i] == 's') {
r = va_arg(args, char*);
}
if(pad_type != 0) {
if(s[i] == 's')sl = strlen(r);
else sl = strlen(n);
if(sl < pad_len) {
while(sl < pad_len) {
strcat(str, (pad_type == 1)?"0":" ");
sl++;
}
}
}
if(s[i] == 's')strcat(str, r);
else strcat(str, n);
} else {
t[0] = s[i];
t[1] = 0;
strcat(str, t);
}
}
va_end(args);
}
+55
View File
@@ -0,0 +1,55 @@
ulong __vector_resize(ulong val)
{
int i;
for(i=0;i<32;i++) {
if((1<<i) >= val)break;
}
//if the value is >2 million, this will fail, in which case,
//just use value. otherwise, use the power of 2.
if((1<<i) > val)val = 1<<i;
return val;
}
class vectorlist {
public:
ulong *list, *newlist, size, newsize, max_size;
void alloc(ulong size) {
if(size < max_size)return;
newsize = __vector_resize(size);
newlist = (ulong*)malloc(newsize*4);
memcpy(newlist, list, max_size*4);
free(list);
list = newlist;
max_size = newsize;
}
void add(ulong val) {
size++;
if(size > max_size)alloc(size + 1);
list[size - 1] = val;
}
void set(ulong num, ulong val) {
if(num >= max_size)alloc(num + 1);
list[num] = val;
if(++num > size)size = num;
}
ulong get(ulong num) {
if(num >= max_size)return 0;
return list[num];
}
vectorlist() {
list = 0;
size = 0;
max_size = 8;
list = (ulong*)malloc(8*4);
}
~vectorlist() {
if(list)free(list);
}
};
-109
View File
@@ -1,109 +0,0 @@
# Makefile
# author: byuu
# license: public domain
[A-Z] = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
[a-z] = a b c d e f g h i j k l m n o p q r s t u v w x y z
[0-9] = 0 1 2 3 4 5 6 7 8 9
[markup] = ` ~ ! @ \# $$ % ^ & * ( ) - _ = + [ { ] } \ | ; : ' " , < . > / ?
[all] = $([A-Z]) $([a-z]) $([0-9]) $([markup])
[space] :=
[space] +=
#####
# platform detection
#####
ifeq ($(platform),)
uname := $(shell uname -a)
ifeq ($(uname),)
platform := win
delete = del $(subst /,\,$1)
else ifneq ($(findstring Darwin,$(uname)),)
platform := osx
delete = rm -f $1
else
platform := x
delete = rm -f $1
endif
endif
ifeq ($(compiler),)
ifeq ($(platform),win)
compiler := gcc
else ifeq ($(platform),osx)
compiler := gcc-mp-4.5
else
compiler := gcc-4.5
endif
endif
ifeq ($(prefix),)
prefix := /usr/local
endif
#####
# function rwildcard(directory, pattern)
#####
rwildcard = \
$(strip \
$(filter $(if $2,$2,%), \
$(foreach f, \
$(wildcard $1*), \
$(eval t = $(call rwildcard,$f/)) \
$(if $t,$t,$f) \
) \
) \
)
#####
# function strtr(source, from, to)
#####
strtr = \
$(eval __temp := $1) \
$(strip \
$(foreach c, \
$(join $(addsuffix :,$2),$3), \
$(eval __temp := \
$(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)),$(__temp)) \
) \
) \
$(__temp) \
)
#####
# function strupper(source)
#####
strupper = $(call strtr,$1,$([a-z]),$([A-Z]))
#####
# function strlower(source)
#####
strlower = $(call strtr,$1,$([A-Z]),$([a-z]))
#####
# function strlen(source)
#####
strlen = \
$(eval __temp := $(subst $([space]),_,$1)) \
$(words \
$(strip \
$(foreach c, \
$([all]), \
$(eval __temp := \
$(subst $c,$c ,$(__temp)) \
) \
) \
$(__temp) \
) \
)
#####
# function streq(source)
#####
streq = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),,1)
#####
# function strne(source)
#####
strne = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),1,)
-17
View File
@@ -1,17 +0,0 @@
#ifndef NALL_ALGORITHM_HPP
#define NALL_ALGORITHM_HPP
#undef min
#undef max
namespace nall {
template<typename T, typename U> T min(const T &t, const U &u) {
return t < u ? t : u;
}
template<typename T, typename U> T max(const T &t, const U &u) {
return t > u ? t : u;
}
}
#endif
-74
View File
@@ -1,74 +0,0 @@
#ifndef NALL_ANY_HPP
#define NALL_ANY_HPP
#include <typeinfo>
#include <type_traits>
#include <nall/static.hpp>
namespace nall {
class any {
public:
bool empty() const { return container; }
const std::type_info& type() const { return container ? container->type() : typeid(void); }
template<typename T> any& operator=(const T& value_) {
typedef typename static_if<
std::is_array<T>::value,
typename std::remove_extent<typename std::add_const<T>::type>::type*,
T
>::type auto_t;
if(type() == typeid(auto_t)) {
static_cast<holder<auto_t>*>(container)->value = (auto_t)value_;
} else {
if(container) delete container;
container = new holder<auto_t>((auto_t)value_);
}
return *this;
}
any() : container(0) {}
template<typename T> any(const T& value_) : container(0) { operator=(value_); }
private:
struct placeholder {
virtual const std::type_info& type() const = 0;
} *container;
template<typename T> struct holder : placeholder {
T value;
const std::type_info& type() const { return typeid(T); }
holder(const T& value_) : value(value_) {}
};
template<typename T> friend T any_cast(any&);
template<typename T> friend T any_cast(const any&);
template<typename T> friend T* any_cast(any*);
template<typename T> friend const T* any_cast(const any*);
};
template<typename T> T any_cast(any &value) {
typedef typename std::remove_reference<T>::type nonref;
if(value.type() != typeid(nonref)) throw;
return static_cast<any::holder<nonref>*>(value.container)->value;
}
template<typename T> T any_cast(const any &value) {
typedef const typename std::remove_reference<T>::type nonref;
if(value.type() != typeid(nonref)) throw;
return static_cast<any::holder<nonref>*>(value.container)->value;
}
template<typename T> T* any_cast(any *value) {
if(!value || value->type() != typeid(T)) return 0;
return &static_cast<any::holder<T>*>(value->container)->value;
}
template<typename T> const T* any_cast(const any *value) {
if(!value || value->type() != typeid(T)) return 0;
return &static_cast<any::holder<T>*>(value->container)->value;
}
}
#endif
-141
View File
@@ -1,141 +0,0 @@
#ifndef NALL_ARRAY_HPP
#define NALL_ARRAY_HPP
#include <stdlib.h>
#include <initializer_list>
#include <type_traits>
#include <utility>
#include <nall/algorithm.hpp>
#include <nall/bit.hpp>
#include <nall/concept.hpp>
#include <nall/foreach.hpp>
#include <nall/utility.hpp>
namespace nall {
//dynamic vector array
//neither constructor nor destructor is ever invoked;
//thus, this should only be used for POD objects.
template<typename T> class array {
protected:
T *pool;
unsigned poolsize, buffersize;
public:
unsigned size() const { return buffersize; }
unsigned capacity() const { return poolsize; }
void reset() {
if(pool) free(pool);
pool = 0;
poolsize = 0;
buffersize = 0;
}
void reserve(unsigned newsize) {
if(newsize == poolsize) return;
pool = (T*)realloc(pool, newsize * sizeof(T));
poolsize = newsize;
buffersize = min(buffersize, newsize);
}
void resize(unsigned newsize) {
if(newsize > poolsize) reserve(bit::round(newsize)); //round reserve size up to power of 2
buffersize = newsize;
}
T* get(unsigned minsize = 0) {
if(minsize > buffersize) resize(minsize);
if(minsize > buffersize) throw "array[] out of bounds";
return pool;
}
void append(const T data) {
operator[](buffersize) = data;
}
template<typename U> void insert(unsigned index, const U list) {
unsigned listsize = container_size(list);
resize(buffersize + listsize);
memmove(pool + index + listsize, pool + index, (buffersize - index) * sizeof(T));
foreach(item, list) pool[index++] = item;
}
void insert(unsigned index, const T item) {
insert(index, array<T>{ item });
}
void remove(unsigned index, unsigned count = 1) {
for(unsigned i = index; count + i < buffersize; i++) {
pool[i] = pool[count + i];
}
if(count + index >= buffersize) resize(index); //every element >= index was removed
else resize(buffersize - count);
}
optional<unsigned> find(const T data) {
for(unsigned i = 0; i < size(); i++) if(pool[i] == data) return { true, i };
return { false, 0 };
}
void clear() {
memset(pool, 0, buffersize * sizeof(T));
}
array() : pool(0), poolsize(0), buffersize(0) {
}
array(std::initializer_list<T> list) : pool(0), poolsize(0), buffersize(0) {
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
}
~array() {
reset();
}
//copy
array& operator=(const array &source) {
if(pool) free(pool);
buffersize = source.buffersize;
poolsize = source.poolsize;
pool = (T*)malloc(sizeof(T) * poolsize); //allocate entire pool size,
memcpy(pool, source.pool, sizeof(T) * buffersize); //... but only copy used pool objects
return *this;
}
array(const array &source) : pool(0), poolsize(0), buffersize(0) {
operator=(source);
}
//move
array& operator=(array &&source) {
if(pool) free(pool);
pool = source.pool;
poolsize = source.poolsize;
buffersize = source.buffersize;
source.pool = 0;
source.reset();
return *this;
}
array(array &&source) : pool(0), poolsize(0), buffersize(0) {
operator=(std::move(source));
}
//index
inline T& operator[](unsigned index) {
if(index >= buffersize) resize(index + 1);
if(index >= buffersize) throw "array[] out of bounds";
return pool[index];
}
inline const T& operator[](unsigned index) const {
if(index >= buffersize) throw "array[] out of bounds";
return pool[index];
}
};
template<typename T> struct has_size<array<T>> { enum { value = true }; };
}
#endif
-90
View File
@@ -1,90 +0,0 @@
#ifndef NALL_BASE64_HPP
#define NALL_BASE64_HPP
#include <string.h>
#include <nall/stdint.hpp>
namespace nall {
class base64 {
public:
static bool encode(char *&output, const uint8_t* input, unsigned inlength) {
output = new char[inlength * 8 / 6 + 6]();
unsigned i = 0, o = 0;
while(i < inlength) {
switch(i % 3) {
case 0: {
output[o++] = enc(input[i] >> 2);
output[o] = enc((input[i] & 3) << 4);
} break;
case 1: {
uint8_t prev = dec(output[o]);
output[o++] = enc(prev + (input[i] >> 4));
output[o] = enc((input[i] & 15) << 2);
} break;
case 2: {
uint8_t prev = dec(output[o]);
output[o++] = enc(prev + (input[i] >> 6));
output[o++] = enc(input[i] & 63);
} break;
}
i++;
}
return true;
}
static bool decode(uint8_t *&output, unsigned &outlength, const char *input) {
unsigned inlength = strlen(input), infix = 0;
output = new uint8_t[inlength]();
unsigned i = 0, o = 0;
while(i < inlength) {
uint8_t x = dec(input[i]);
switch(i++ & 3) {
case 0: {
output[o] = x << 2;
} break;
case 1: {
output[o++] |= x >> 4;
output[o] = (x & 15) << 4;
} break;
case 2: {
output[o++] |= x >> 2;
output[o] = (x & 3) << 6;
} break;
case 3: {
output[o++] |= x;
} break;
}
}
outlength = o;
return true;
}
private:
static char enc(uint8_t n) {
static char lookup_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
return lookup_table[n & 63];
}
static uint8_t dec(char n) {
if(n >= 'A' && n <= 'Z') return n - 'A';
if(n >= 'a' && n <= 'z') return n - 'a' + 26;
if(n >= '0' && n <= '9') return n - '0' + 52;
if(n == '-') return 62;
if(n == '_') return 63;
return 0;
}
};
}
#endif
-51
View File
@@ -1,51 +0,0 @@
#ifndef NALL_BIT_HPP
#define NALL_BIT_HPP
namespace nall {
template<int bits> inline unsigned uclamp(const unsigned x) {
enum { y = (1U << bits) - 1 };
return y + ((x - y) & -(x < y)); //min(x, y);
}
template<int bits> inline unsigned uclip(const unsigned x) {
enum { m = (1U << bits) - 1 };
return (x & m);
}
template<int bits> inline signed sclamp(const signed x) {
enum { b = 1U << (bits - 1), m = (1U << (bits - 1)) - 1 };
return (x > m) ? m : (x < -b) ? -b : x;
}
template<int bits> inline signed sclip(const signed x) {
enum { b = 1U << (bits - 1), m = (1U << bits) - 1 };
return ((x & m) ^ b) - b;
}
namespace bit {
//lowest(0b1110) == 0b0010
template<typename T> inline T lowest(const T x) {
return x & -x;
}
//clear_lowest(0b1110) == 0b1100
template<typename T> inline T clear_lowest(const T x) {
return x & (x - 1);
}
//set_lowest(0b0101) == 0b0111
template<typename T> inline T set_lowest(const T x) {
return x | (x + 1);
}
//round up to next highest single bit:
//round(15) == 16, round(16) == 16, round(17) == 32
inline unsigned round(unsigned x) {
if((x & (x - 1)) == 0) return x;
while(x & (x - 1)) x &= x - 1;
return x << 1;
}
}
}
#endif
-34
View File
@@ -1,34 +0,0 @@
#ifndef NALL_CONCEPT_HPP
#define NALL_CONCEPT_HPP
#include <nall/static.hpp>
#include <nall/utility.hpp>
namespace nall {
//unsigned count() const;
template<typename T> struct has_count { enum { value = false }; };
//unsigned length() const;
template<typename T> struct has_length { enum { value = false }; };
//unsigned size() const;
template<typename T> struct has_size { enum { value = false }; };
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
return object.count();
}
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_length<T>>::type = 0) {
return object.length();
}
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_size<T>>::type = 0) {
return object.size();
}
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<std::is_array<T>>::type = 0) {
return sizeof(T) / sizeof(typename std::remove_extent<T>::type);
}
}
#endif
-123
View File
@@ -1,123 +0,0 @@
#ifndef NALL_CONFIG_HPP
#define NALL_CONFIG_HPP
#include <nall/file.hpp>
#include <nall/string.hpp>
#include <nall/vector.hpp>
namespace nall {
namespace configuration_traits {
template<typename T> struct is_boolean { enum { value = false }; };
template<> struct is_boolean<bool> { enum { value = true }; };
template<typename T> struct is_signed { enum { value = false }; };
template<> struct is_signed<signed> { enum { value = true }; };
template<typename T> struct is_unsigned { enum { value = false }; };
template<> struct is_unsigned<unsigned> { enum { value = true }; };
template<typename T> struct is_double { enum { value = false }; };
template<> struct is_double<double> { enum { value = true }; };
template<typename T> struct is_string { enum { value = false }; };
template<> struct is_string<string> { enum { value = true }; };
}
class configuration {
public:
enum type_t { boolean_t, signed_t, unsigned_t, double_t, string_t, unknown_t };
struct item_t {
uintptr_t data;
string name;
string desc;
type_t type;
string get() const {
switch(type) {
case boolean_t: return string() << *(bool*)data;
case signed_t: return string() << *(signed*)data;
case unsigned_t: return string() << *(unsigned*)data;
case double_t: return string() << *(double*)data;
case string_t: return string() << "\"" << *(string*)data << "\"";
}
return "???";
}
void set(string s) {
switch(type) {
case boolean_t: *(bool*)data = (s == "true"); break;
case signed_t: *(signed*)data = strsigned(s); break;
case unsigned_t: *(unsigned*)data = strunsigned(s); break;
case double_t: *(double*)data = strdouble(s); break;
case string_t: s.trim("\""); *(string*)data = s; break;
}
}
};
linear_vector<item_t> list;
template<typename T>
void attach(T &data, const char *name, const char *desc = "") {
unsigned n = list.size();
list[n].data = (uintptr_t)&data;
list[n].name = name;
list[n].desc = desc;
if(configuration_traits::is_boolean<T>::value) list[n].type = boolean_t;
else if(configuration_traits::is_signed<T>::value) list[n].type = signed_t;
else if(configuration_traits::is_unsigned<T>::value) list[n].type = unsigned_t;
else if(configuration_traits::is_double<T>::value) list[n].type = double_t;
else if(configuration_traits::is_string<T>::value) list[n].type = string_t;
else list[n].type = unknown_t;
}
virtual bool load(const char *filename) {
string data;
if(data.readfile(filename) == true) {
data.replace("\r", "");
lstring line;
line.split("\n", data);
for(unsigned i = 0; i < line.size(); i++) {
if(auto position = qstrpos(line[i], "#")) line[i][position()] = 0;
if(!qstrpos(line[i], " = ")) continue;
lstring part;
part.qsplit(" = ", line[i]);
part[0].trim();
part[1].trim();
for(unsigned n = 0; n < list.size(); n++) {
if(part[0] == list[n].name) {
list[n].set(part[1]);
break;
}
}
}
return true;
} else {
return false;
}
}
virtual bool save(const char *filename) const {
file fp;
if(fp.open(filename, file::mode::write)) {
for(unsigned i = 0; i < list.size(); i++) {
string output;
output << list[i].name << " = " << list[i].get();
if(list[i].desc != "") output << " # " << list[i].desc;
output << "\r\n";
fp.print(output);
}
fp.close();
return true;
} else {
return false;
}
}
};
}
#endif
-66
View File
@@ -1,66 +0,0 @@
#ifndef NALL_CRC32_HPP
#define NALL_CRC32_HPP
#include <nall/stdint.hpp>
namespace nall {
const uint32_t crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
inline uint32_t crc32_adjust(uint32_t crc32, uint8_t input) {
return ((crc32 >> 8) & 0x00ffffff) ^ crc32_table[(crc32 ^ input) & 0xff];
}
inline uint32_t crc32_calculate(const uint8_t *data, unsigned length) {
uint32_t crc32 = ~0;
for(unsigned i = 0; i < length; i++) {
crc32 = crc32_adjust(crc32, data[i]);
}
return ~crc32;
}
}
#endif
-30
View File
@@ -1,30 +0,0 @@
#ifndef NALL_DETECT_HPP
#define NALL_DETECT_HPP
/* Compiler detection */
#if defined(__GNUC__)
#define COMPILER_GCC
#elif defined(_MSC_VER)
#define COMPILER_VISUALC
#endif
/* Platform detection */
#if defined(_WIN32)
#define PLATFORM_WIN
#elif defined(__APPLE__)
#define PLATFORM_OSX
#elif defined(linux) || defined(__sun__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define PLATFORM_X
#endif
/* Endian detection */
#if defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64)
#define ARCH_LSB
#elif defined(__powerpc__) || defined(_M_PPC) || defined(__BIG_ENDIAN__)
#define ARCH_MSB
#endif
#endif
-75
View File
@@ -1,75 +0,0 @@
#ifndef NALL_DICTIONARY_HPP
#define NALL_DICTIONARY_HPP
#include <nall/array.hpp>
#include <nall/string.hpp>
#include <nall/utility.hpp>
namespace nall {
class dictionary {
public:
string operator[](const char *input) {
for(unsigned i = 0; i < index_input.size(); i++) {
if(index_input[i] == input) return index_output[i];
}
//no match, use input; remove input identifier, if one exists
if(strbegin(input, "{{")) {
if(auto pos = strpos(input, "}}")) {
string temp = substr(input, pos() + 2);
return temp;
}
}
return input;
}
bool import(const char *filename) {
string data;
if(data.readfile(filename) == false) return false;
data.ltrim<1>("\xef\xbb\xbf"); //remove UTF-8 marker, if it exists
data.replace("\r", "");
lstring line;
line.split("\n", data);
for(unsigned i = 0; i < line.size(); i++) {
lstring part;
//format: "Input" = "Output"
part.qsplit("=", line[i]);
if(part.size() != 2) continue;
//remove whitespace
part[0].trim();
part[1].trim();
//remove quotes
part[0].trim<1>("\"");
part[1].trim<1>("\"");
unsigned n = index_input.size();
index_input[n] = part[0];
index_output[n] = part[1];
}
return true;
}
void reset() {
index_input.reset();
index_output.reset();
}
~dictionary() {
reset();
}
dictionary& operator=(const dictionary&) = delete;
dictionary(const dictionary&) = delete;
protected:
lstring index_input;
lstring index_output;
};
}
#endif
-151
View File
@@ -1,151 +0,0 @@
#ifndef NALL_DIRECTORY_HPP
#define NALL_DIRECTORY_HPP
#include <nall/foreach.hpp>
#include <nall/sort.hpp>
#include <nall/string.hpp>
#if defined(_WIN32)
#include <nall/utf8.hpp>
#else
#include <dirent.h>
#include <stdio.h>
#include <sys/types.h>
#endif
namespace nall {
struct directory {
static bool exists(const string &pathname);
static lstring folders(const string &pathname, const string &pattern = "*");
static lstring files(const string &pathname, const string &pattern = "*");
static lstring contents(const string &pathname, const string &pattern = "*");
};
#if defined(_WIN32)
inline bool directory::exists(const string &pathname) {
DWORD result = GetFileAttributes(utf16_t(pathname));
if(result == INVALID_FILE_ATTRIBUTES) return false;
return (result & FILE_ATTRIBUTE_DIRECTORY);
}
inline lstring directory::folders(const string &pathname, const string &pattern) {
lstring list;
string path = pathname;
path.transform("/", "\\");
if(!strend(path, "\\")) path.append("\\");
path.append("*");
HANDLE handle;
WIN32_FIND_DATA data;
handle = FindFirstFile(utf16_t(path), &data);
if(handle != INVALID_HANDLE_VALUE) {
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
string name = utf8_t(data.cFileName);
if(wildcard(name, pattern)) list.append(string(name, "/"));
}
}
while(FindNextFile(handle, &data) != false) {
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
string name = utf8_t(data.cFileName);
if(wildcard(name, pattern)) list.append(string(name, "/"));
}
}
}
FindClose(handle);
}
if(list.size() > 0) sort(&list[0], list.size());
return list;
}
inline lstring directory::files(const string &pathname, const string &pattern) {
lstring list;
string path = pathname;
path.transform("/", "\\");
if(!strend(path, "\\")) path.append("\\");
path.append("*");
HANDLE handle;
WIN32_FIND_DATA data;
handle = FindFirstFile(utf16_t(path), &data);
if(handle != INVALID_HANDLE_VALUE) {
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
string name = utf8_t(data.cFileName);
if(wildcard(name, pattern)) list.append(name);
}
while(FindNextFile(handle, &data) != false) {
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
string name = utf8_t(data.cFileName);
if(wildcard(name, pattern)) list.append(name);
}
}
FindClose(handle);
}
if(list.size() > 0) sort(&list[0], list.size());
return list;
}
inline lstring directory::contents(const string &pathname, const string &pattern) {
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
lstring files = directory::files(pathname, pattern);
foreach(file, files) folders.append(file);
return folders;
}
#else
inline bool directory::exists(const string &pathname) {
DIR *dp = opendir(pathname);
if(!dp) return false;
closedir(dp);
return true;
}
inline lstring directory::folders(const string &pathname, const string &pattern) {
lstring list;
DIR *dp;
struct dirent *ep;
dp = opendir(pathname);
if(dp) {
while(ep = readdir(dp)) {
if(!strcmp(ep->d_name, ".")) continue;
if(!strcmp(ep->d_name, "..")) continue;
if(ep->d_type & DT_DIR) {
if(wildcard(ep->d_name, pattern)) list.append(string(ep->d_name, "/"));
}
}
closedir(dp);
}
if(list.size() > 0) sort(&list[0], list.size());
return list;
}
inline lstring directory::files(const string &pathname, const string &pattern) {
lstring list;
DIR *dp;
struct dirent *ep;
dp = opendir(pathname);
if(dp) {
while(ep = readdir(dp)) {
if(!strcmp(ep->d_name, ".")) continue;
if(!strcmp(ep->d_name, "..")) continue;
if((ep->d_type & DT_DIR) == 0) {
if(wildcard(ep->d_name, pattern)) list.append(ep->d_name);
}
}
closedir(dp);
}
if(list.size() > 0) sort(&list[0], list.size());
return list;
}
inline lstring directory::contents(const string &pathname, const string &pattern) {
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
lstring files = directory::files(pathname, pattern);
foreach(file, files) folders.append(file);
return folders;
}
#endif
}
#endif
-96
View File
@@ -1,96 +0,0 @@
#ifndef NALL_DL_HPP
#define NALL_DL_HPP
//dynamic linking support
#include <nall/detect.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
#include <nall/utility.hpp>
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
#include <dlfcn.h>
#elif defined(PLATFORM_WIN)
#include <windows.h>
#include <nall/utf8.hpp>
#endif
namespace nall {
struct library {
bool opened() const { return handle; }
bool open(const char*, const char* = "");
void* sym(const char*);
void close();
library() : handle(0) {}
~library() { close(); }
library& operator=(const library&) = delete;
library(const library&) = delete;
private:
uintptr_t handle;
};
#if defined(PLATFORM_X)
inline bool library::open(const char *name, const char *path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".so"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
return handle;
}
inline void* library::sym(const char *name) {
if(!handle) return 0;
return dlsym((void*)handle, name);
}
inline void library::close() {
if(!handle) return;
dlclose((void*)handle);
handle = 0;
}
#elif defined(PLATFORM_OSX)
inline bool library::open(const char *name, const char *path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
return handle;
}
inline void* library::sym(const char *name) {
if(!handle) return 0;
return dlsym((void*)handle, name);
}
inline void library::close() {
if(!handle) return;
dlclose((void*)handle);
handle = 0;
}
#elif defined(PLATFORM_WIN)
inline bool library::open(const char *name, const char *path) {
if(handle) close();
string filepath(path, *path && !strend(path, "/") && !strend(path, "\\") ? "\\" : "", name, ".dll");
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath));
return handle;
}
inline void* library::sym(const char *name) {
if(!handle) return 0;
return (void*)GetProcAddress((HMODULE)handle, name);
}
inline void library::close() {
if(!handle) return;
FreeLibrary((HMODULE)handle);
handle = 0;
}
#else
inline bool library::open(const char*, const char*) { return false; }
inline void* library::sym(const char*) { return 0; }
inline void library::close() {}
#endif
};
#endif
-38
View File
@@ -1,38 +0,0 @@
#ifndef NALL_ENDIAN_HPP
#define NALL_ENDIAN_HPP
#if !defined(ARCH_MSB)
//little-endian: uint8_t[] { 0x01, 0x02, 0x03, 0x04 } == 0x04030201
#define order_lsb2(a,b) a,b
#define order_lsb3(a,b,c) a,b,c
#define order_lsb4(a,b,c,d) a,b,c,d
#define order_lsb5(a,b,c,d,e) a,b,c,d,e
#define order_lsb6(a,b,c,d,e,f) a,b,c,d,e,f
#define order_lsb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g
#define order_lsb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h
#define order_msb2(a,b) b,a
#define order_msb3(a,b,c) c,b,a
#define order_msb4(a,b,c,d) d,c,b,a
#define order_msb5(a,b,c,d,e) e,d,c,b,a
#define order_msb6(a,b,c,d,e,f) f,e,d,c,b,a
#define order_msb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a
#define order_msb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a
#else
//big-endian: uint8_t[] { 0x01, 0x02, 0x03, 0x04 } == 0x01020304
#define order_lsb2(a,b) b,a
#define order_lsb3(a,b,c) c,b,a
#define order_lsb4(a,b,c,d) d,c,b,a
#define order_lsb5(a,b,c,d,e) e,d,c,b,a
#define order_lsb6(a,b,c,d,e,f) f,e,d,c,b,a
#define order_lsb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a
#define order_lsb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a
#define order_msb2(a,b) a,b
#define order_msb3(a,b,c) a,b,c
#define order_msb4(a,b,c,d) a,b,c,d
#define order_msb5(a,b,c,d,e) a,b,c,d,e
#define order_msb6(a,b,c,d,e,f) a,b,c,d,e,f
#define order_msb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g
#define order_msb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h
#endif
#endif
-261
View File
@@ -1,261 +0,0 @@
#ifndef NALL_FILE_HPP
#define NALL_FILE_HPP
#include <stdio.h>
#include <string.h>
#if !defined(_WIN32)
#include <unistd.h>
#else
#include <io.h>
#endif
#include <nall/stdint.hpp>
#include <nall/string.hpp>
#include <nall/utf8.hpp>
#include <nall/utility.hpp>
namespace nall {
inline FILE* fopen_utf8(const char *utf8_filename, const char *mode) {
#if !defined(_WIN32)
return fopen(utf8_filename, mode);
#else
return _wfopen(utf16_t(utf8_filename), utf16_t(mode));
#endif
}
class file {
public:
enum class mode : unsigned { read, write, readwrite, writeread };
enum class index : unsigned { absolute, relative };
uint8_t read() {
if(!fp) return 0xff; //file not open
if(file_mode == mode::write) return 0xff; //reads not permitted
if(file_offset >= file_size) return 0xff; //cannot read past end of file
buffer_sync();
return buffer[(file_offset++) & buffer_mask];
}
uintmax_t readl(unsigned length = 1) {
uintmax_t data = 0;
for(int i = 0; i < length; i++) {
data |= (uintmax_t)read() << (i << 3);
}
return data;
}
uintmax_t readm(unsigned length = 1) {
uintmax_t data = 0;
while(length--) {
data <<= 8;
data |= read();
}
return data;
}
void read(uint8_t *buffer, unsigned length) {
while(length--) *buffer++ = read();
}
void write(uint8_t data) {
if(!fp) return; //file not open
if(file_mode == mode::read) return; //writes not permitted
buffer_sync();
buffer[(file_offset++) & buffer_mask] = data;
buffer_dirty = true;
if(file_offset > file_size) file_size = file_offset;
}
void writel(uintmax_t data, unsigned length = 1) {
while(length--) {
write(data);
data >>= 8;
}
}
void writem(uintmax_t data, unsigned length = 1) {
for(int i = length - 1; i >= 0; i--) {
write(data >> (i << 3));
}
}
void write(const uint8_t *buffer, unsigned length) {
while(length--) write(*buffer++);
}
template<typename... Args> void print(Args... args) {
string data(args...);
const char *p = data;
while(*p) write(*p++);
}
void flush() {
buffer_flush();
fflush(fp);
}
void seek(int offset, index index_ = index::absolute) {
if(!fp) return; //file not open
buffer_flush();
uintmax_t req_offset = file_offset;
switch(index_) {
case index::absolute: req_offset = offset; break;
case index::relative: req_offset += offset; break;
}
if(req_offset < 0) req_offset = 0; //cannot seek before start of file
if(req_offset > file_size) {
if(file_mode == mode::read) { //cannot seek past end of file
req_offset = file_size;
} else { //pad file to requested location
file_offset = file_size;
while(file_size < req_offset) write(0x00);
}
}
file_offset = req_offset;
}
int offset() {
if(!fp) return -1; //file not open
return file_offset;
}
int size() {
if(!fp) return -1; //file not open
return file_size;
}
bool truncate(unsigned size) {
if(!fp) return false; //file not open
#if !defined(_WIN32)
return ftruncate(fileno(fp), size) == 0;
#else
return _chsize(fileno(fp), size) == 0;
#endif
}
bool end() {
if(!fp) return true; //file not open
return file_offset >= file_size;
}
static bool exists(const char *fn) {
#if !defined(_WIN32)
FILE *fp = fopen(fn, "rb");
#else
FILE *fp = _wfopen(utf16_t(fn), L"rb");
#endif
if(fp) {
fclose(fp);
return true;
}
return false;
}
static unsigned size(const char *fn) {
#if !defined(_WIN32)
FILE *fp = fopen(fn, "rb");
#else
FILE *fp = _wfopen(utf16_t(fn), L"rb");
#endif
unsigned filesize = 0;
if(fp) {
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
fclose(fp);
}
return filesize;
}
bool open() {
return fp;
}
bool open(const char *fn, mode mode_) {
if(fp) return false;
switch(file_mode = mode_) {
#if !defined(_WIN32)
case mode::read: fp = fopen(fn, "rb"); break;
case mode::write: fp = fopen(fn, "wb+"); break; //need read permission for buffering
case mode::readwrite: fp = fopen(fn, "rb+"); break;
case mode::writeread: fp = fopen(fn, "wb+"); break;
#else
case mode::read: fp = _wfopen(utf16_t(fn), L"rb"); break;
case mode::write: fp = _wfopen(utf16_t(fn), L"wb+"); break;
case mode::readwrite: fp = _wfopen(utf16_t(fn), L"rb+"); break;
case mode::writeread: fp = _wfopen(utf16_t(fn), L"wb+"); break;
#endif
}
if(!fp) return false;
buffer_offset = -1; //invalidate buffer
file_offset = 0;
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
return true;
}
void close() {
if(!fp) return;
buffer_flush();
fclose(fp);
fp = 0;
}
file() {
memset(buffer, 0, sizeof buffer);
buffer_offset = -1;
buffer_dirty = false;
fp = 0;
file_offset = 0;
file_size = 0;
file_mode = mode::read;
}
~file() {
close();
}
file& operator=(const file&) = delete;
file(const file&) = delete;
private:
enum { buffer_size = 1 << 12, buffer_mask = buffer_size - 1 };
char buffer[buffer_size];
int buffer_offset;
bool buffer_dirty;
FILE *fp;
unsigned file_offset;
unsigned file_size;
mode file_mode;
void buffer_sync() {
if(!fp) return; //file not open
if(buffer_offset != (file_offset & ~buffer_mask)) {
buffer_flush();
buffer_offset = file_offset & ~buffer_mask;
fseek(fp, buffer_offset, SEEK_SET);
unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask);
if(length) unsigned unused = fread(buffer, 1, length, fp);
}
}
void buffer_flush() {
if(!fp) return; //file not open
if(file_mode == mode::read) return; //buffer cannot be written to
if(buffer_offset < 0) return; //buffer unused
if(buffer_dirty == false) return; //buffer unmodified since read
fseek(fp, buffer_offset, SEEK_SET);
unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask);
if(length) unsigned unused = fwrite(buffer, 1, length, fp);
buffer_offset = -1; //invalidate buffer
buffer_dirty = false;
}
};
}
#endif
-200
View File
@@ -1,200 +0,0 @@
#ifndef NALL_FILEMAP_HPP
#define NALL_FILEMAP_HPP
#include <nall/stdint.hpp>
#include <nall/utf8.hpp>
#include <stdio.h>
#include <stdlib.h>
#if defined(_WIN32)
#include <windows.h>
#else
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
namespace nall {
class filemap {
public:
enum class mode : unsigned { read, write, readwrite, writeread };
bool opened() const { return p_opened(); }
bool open(const char *filename, mode mode_) { return p_open(filename, mode_); }
void close() { return p_close(); }
unsigned size() const { return p_size; }
uint8_t* data() { return p_handle; }
const uint8_t* data() const { return p_handle; }
filemap() : p_size(0), p_handle(0) { p_ctor(); }
filemap(const char *filename, mode mode_) : p_size(0), p_handle(0) { p_ctor(); p_open(filename, mode_); }
~filemap() { p_dtor(); }
private:
unsigned p_size;
uint8_t *p_handle;
#if defined(_WIN32)
//=============
//MapViewOfFile
//=============
HANDLE p_filehandle, p_maphandle;
bool p_opened() const {
return p_handle;
}
bool p_open(const char *filename, mode mode_) {
int desired_access, creation_disposition, flprotect, map_access;
switch(mode_) {
default: return false;
case mode::read:
desired_access = GENERIC_READ;
creation_disposition = OPEN_EXISTING;
flprotect = PAGE_READONLY;
map_access = FILE_MAP_READ;
break;
case mode::write:
//write access requires read access
desired_access = GENERIC_WRITE;
creation_disposition = CREATE_ALWAYS;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
case mode::readwrite:
desired_access = GENERIC_READ | GENERIC_WRITE;
creation_disposition = OPEN_EXISTING;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
case mode::writeread:
desired_access = GENERIC_READ | GENERIC_WRITE;
creation_disposition = CREATE_NEW;
flprotect = PAGE_READWRITE;
map_access = FILE_MAP_ALL_ACCESS;
break;
}
p_filehandle = CreateFileW(utf16_t(filename), desired_access, FILE_SHARE_READ, NULL,
creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL);
if(p_filehandle == INVALID_HANDLE_VALUE) return false;
p_size = GetFileSize(p_filehandle, NULL);
p_maphandle = CreateFileMapping(p_filehandle, NULL, flprotect, 0, p_size, NULL);
if(p_maphandle == INVALID_HANDLE_VALUE) {
CloseHandle(p_filehandle);
p_filehandle = INVALID_HANDLE_VALUE;
return false;
}
p_handle = (uint8_t*)MapViewOfFile(p_maphandle, map_access, 0, 0, p_size);
return p_handle;
}
void p_close() {
if(p_handle) {
UnmapViewOfFile(p_handle);
p_handle = 0;
}
if(p_maphandle != INVALID_HANDLE_VALUE) {
CloseHandle(p_maphandle);
p_maphandle = INVALID_HANDLE_VALUE;
}
if(p_filehandle != INVALID_HANDLE_VALUE) {
CloseHandle(p_filehandle);
p_filehandle = INVALID_HANDLE_VALUE;
}
}
void p_ctor() {
p_filehandle = INVALID_HANDLE_VALUE;
p_maphandle = INVALID_HANDLE_VALUE;
}
void p_dtor() {
close();
}
#else
//====
//mmap
//====
int p_fd;
bool p_opened() const {
return p_handle;
}
bool p_open(const char *filename, mode mode_) {
int open_flags, mmap_flags;
switch(mode_) {
default: return false;
case mode::read:
open_flags = O_RDONLY;
mmap_flags = PROT_READ;
break;
case mode::write:
open_flags = O_RDWR | O_CREAT; //mmap() requires read access
mmap_flags = PROT_WRITE;
break;
case mode::readwrite:
open_flags = O_RDWR;
mmap_flags = PROT_READ | PROT_WRITE;
break;
case mode::writeread:
open_flags = O_RDWR | O_CREAT;
mmap_flags = PROT_READ | PROT_WRITE;
break;
}
p_fd = ::open(filename, open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if(p_fd < 0) return false;
struct stat p_stat;
fstat(p_fd, &p_stat);
p_size = p_stat.st_size;
p_handle = (uint8_t*)mmap(0, p_size, mmap_flags, MAP_SHARED, p_fd, 0);
if(p_handle == MAP_FAILED) {
p_handle = 0;
::close(p_fd);
p_fd = -1;
return false;
}
return p_handle;
}
void p_close() {
if(p_handle) {
munmap(p_handle, p_size);
p_handle = 0;
}
if(p_fd >= 0) {
::close(p_fd);
p_fd = -1;
}
}
void p_ctor() {
p_fd = -1;
}
void p_dtor() {
p_close();
}
#endif
};
}
#endif
-12
View File
@@ -1,12 +0,0 @@
#ifndef NALL_FOREACH_HPP
#define NALL_FOREACH_HPP
#include <type_traits>
#include <nall/concept.hpp>
#undef foreach
#define foreach(iter, object) \
for(unsigned foreach_counter = 0, foreach_limit = container_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
for(auto &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
#endif
-60
View File
@@ -1,60 +0,0 @@
#ifndef NALL_FUNCTION_HPP
#define NALL_FUNCTION_HPP
namespace nall {
template<typename T> class function;
template<typename R, typename... P> class function<R (P...)> {
struct container {
virtual R operator()(P... p) const = 0;
virtual container* copy() const = 0;
virtual ~container() {}
} *callback;
struct global : container {
R (*function)(P...);
R operator()(P... p) const { return function(std::forward<P>(p)...); }
container* copy() const { return new global(function); }
global(R (*function)(P...)) : function(function) {}
};
template<typename C> struct member : container {
R (C::*function)(P...);
C *object;
R operator()(P... p) const { return (object->*function)(std::forward<P>(p)...); }
container* copy() const { return new member(function, object); }
member(R (C::*function)(P...), C *object) : function(function), object(object) {}
};
template<typename L> struct lambda : container {
L object;
R operator()(P... p) const { return object(std::forward<P>(p)...); }
container* copy() const { return new lambda(object); }
lambda(const L& object) : object(object) {}
};
public:
operator bool() const { return callback; }
R operator()(P... p) const { return (*callback)(std::forward<P>(p)...); }
void reset() { if(callback) { delete callback; callback = 0; } }
function& operator=(const function &source) {
if(this != &source) {
if(callback) { delete callback; callback = 0; }
if(source.callback) callback = source.callback->copy();
}
return *this;
}
function(const function &source) { operator=(source); }
function() : callback(0) {}
function(void *function) : callback(0) { if(function) callback = new global((R (*)(P...))function); }
function(R (*function)(P...)) { callback = new global(function); }
template<typename C> function(R (C::*function)(P...), C *object) { callback = new member<C>(function, object); }
template<typename C> function(R (C::*function)(P...) const, C *object) { callback = new member<C>((R (C::*)(P...))function, object); }
template<typename L> function(const L& object) { callback = new lambda<L>(object); }
~function() { if(callback) delete callback; }
};
}
#endif
-386
View File
@@ -1,386 +0,0 @@
#ifndef NALL_INPUT_HPP
#define NALL_INPUT_HPP
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
namespace nall {
struct Keyboard;
Keyboard& keyboard(unsigned = 0);
static const char KeyboardScancodeName[][64] = {
"Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
"PrintScreen", "ScrollLock", "Pause", "Tilde",
"Num1", "Num2", "Num3", "Num4", "Num5", "Num6", "Num7", "Num8", "Num9", "Num0",
"Dash", "Equal", "Backspace",
"Insert", "Delete", "Home", "End", "PageUp", "PageDown",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"LeftBracket", "RightBracket", "Backslash", "Semicolon", "Apostrophe", "Comma", "Period", "Slash",
"Keypad1", "Keypad2", "Keypad3", "Keypad4", "Keypad5", "Keypad6", "Keypad7", "Keypad8", "Keypad9", "Keypad0",
"Point", "Enter", "Add", "Subtract", "Multiply", "Divide",
"NumLock", "CapsLock",
"Up", "Down", "Left", "Right",
"Tab", "Return", "Spacebar", "Menu",
"Shift", "Control", "Alt", "Super",
};
struct Keyboard {
const unsigned ID;
enum { Base = 1 };
enum { Count = 8, Size = 128 };
enum Scancode {
Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
PrintScreen, ScrollLock, Pause, Tilde,
Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9, Num0,
Dash, Equal, Backspace,
Insert, Delete, Home, End, PageUp, PageDown,
A, B, C, D, E, F, G, H, I, J, K, L, M,
N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
LeftBracket, RightBracket, Backslash, Semicolon, Apostrophe, Comma, Period, Slash,
Keypad1, Keypad2, Keypad3, Keypad4, Keypad5, Keypad6, Keypad7, Keypad8, Keypad9, Keypad0,
Point, Enter, Add, Subtract, Multiply, Divide,
NumLock, CapsLock,
Up, Down, Left, Right,
Tab, Return, Spacebar, Menu,
Shift, Control, Alt, Super,
Limit,
};
static signed numberDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(keyboard(i).belongsTo(scancode)) return i;
}
return -1;
}
static signed keyDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(keyboard(i).isKey(scancode)) return scancode - keyboard(i).key(Escape);
}
return -1;
}
static signed modifierDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(keyboard(i).isModifier(scancode)) return scancode - keyboard(i).key(Shift);
}
return -1;
}
static bool isAnyKey(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(keyboard(i).isKey(scancode)) return true;
}
return false;
}
static bool isAnyModifier(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(keyboard(i).isModifier(scancode)) return true;
}
return false;
}
static uint16_t decode(const char *name) {
string s(name);
if(!strbegin(name, "KB")) return 0;
s.ltrim("KB");
unsigned id = strunsigned(s);
auto pos = strpos(s, "::");
if(!pos) return 0;
s = substr(s, pos() + 2);
for(unsigned i = 0; i < Limit; i++) {
if(s == KeyboardScancodeName[i]) return Base + Size * id + i;
}
return 0;
}
string encode(uint16_t code) const {
unsigned index = 0;
for(unsigned i = 0; i < Count; i++) {
if(code >= Base + Size * i && code < Base + Size * (i + 1)) {
index = code - (Base + Size * i);
break;
}
}
return string() << "KB" << ID << "::" << KeyboardScancodeName[index];
}
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
uint16_t key(unsigned id) const { return Base + Size * ID + id; }
bool isKey(unsigned id) const { return id >= key(Escape) && id <= key(Menu); }
bool isModifier(unsigned id) const { return id >= key(Shift) && id <= key(Super); }
bool belongsTo(uint16_t scancode) const { return isKey(scancode) || isModifier(scancode); }
Keyboard(unsigned ID_) : ID(ID_) {}
};
inline Keyboard& keyboard(unsigned id) {
static Keyboard kb0(0), kb1(1), kb2(2), kb3(3), kb4(4), kb5(5), kb6(6), kb7(7);
switch(id) { default:
case 0: return kb0; case 1: return kb1; case 2: return kb2; case 3: return kb3;
case 4: return kb4; case 5: return kb5; case 6: return kb6; case 7: return kb7;
}
}
static const char MouseScancodeName[][64] = {
"Xaxis", "Yaxis", "Zaxis",
"Button0", "Button1", "Button2", "Button3", "Button4", "Button5", "Button6", "Button7",
};
struct Mouse;
Mouse& mouse(unsigned = 0);
struct Mouse {
const unsigned ID;
enum { Base = Keyboard::Base + Keyboard::Size * Keyboard::Count };
enum { Count = 8, Size = 16 };
enum { Axes = 3, Buttons = 8 };
enum Scancode {
Xaxis, Yaxis, Zaxis,
Button0, Button1, Button2, Button3, Button4, Button5, Button6, Button7,
Limit,
};
static signed numberDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(mouse(i).belongsTo(scancode)) return i;
}
return -1;
}
static signed axisDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(mouse(i).isAxis(scancode)) return scancode - mouse(i).axis(0);
}
return -1;
}
static signed buttonDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(mouse(i).isButton(scancode)) return scancode - mouse(i).button(0);
}
return -1;
}
static bool isAnyAxis(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(mouse(i).isAxis(scancode)) return true;
}
return false;
}
static bool isAnyButton(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(mouse(i).isButton(scancode)) return true;
}
return false;
}
static uint16_t decode(const char *name) {
string s(name);
if(!strbegin(name, "MS")) return 0;
s.ltrim("MS");
unsigned id = strunsigned(s);
auto pos = strpos(s, "::");
if(!pos) return 0;
s = substr(s, pos() + 2);
for(unsigned i = 0; i < Limit; i++) {
if(s == MouseScancodeName[i]) return Base + Size * id + i;
}
return 0;
}
string encode(uint16_t code) const {
unsigned index = 0;
for(unsigned i = 0; i < Count; i++) {
if(code >= Base + Size * i && code < Base + Size * (i + 1)) {
index = code - (Base + Size * i);
break;
}
}
return string() << "MS" << ID << "::" << MouseScancodeName[index];
}
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
uint16_t axis(unsigned id) const { return Base + Size * ID + Xaxis + id; }
uint16_t button(unsigned id) const { return Base + Size * ID + Button0 + id; }
bool isAxis(unsigned id) const { return id >= axis(0) && id <= axis(2); }
bool isButton(unsigned id) const { return id >= button(0) && id <= button(7); }
bool belongsTo(uint16_t scancode) const { return isAxis(scancode) || isButton(scancode); }
Mouse(unsigned ID_) : ID(ID_) {}
};
inline Mouse& mouse(unsigned id) {
static Mouse ms0(0), ms1(1), ms2(2), ms3(3), ms4(4), ms5(5), ms6(6), ms7(7);
switch(id) { default:
case 0: return ms0; case 1: return ms1; case 2: return ms2; case 3: return ms3;
case 4: return ms4; case 5: return ms5; case 6: return ms6; case 7: return ms7;
}
}
static const char JoypadScancodeName[][64] = {
"Hat0", "Hat1", "Hat2", "Hat3", "Hat4", "Hat5", "Hat6", "Hat7",
"Axis0", "Axis1", "Axis2", "Axis3", "Axis4", "Axis5", "Axis6", "Axis7",
"Axis8", "Axis9", "Axis10", "Axis11", "Axis12", "Axis13", "Axis14", "Axis15",
"Button0", "Button1", "Button2", "Button3", "Button4", "Button5", "Button6", "Button7",
"Button8", "Button9", "Button10", "Button11", "Button12", "Button13", "Button14", "Button15",
"Button16", "Button17", "Button18", "Button19", "Button20", "Button21", "Button22", "Button23",
"Button24", "Button25", "Button26", "Button27", "Button28", "Button29", "Button30", "Button31",
};
struct Joypad;
Joypad& joypad(unsigned = 0);
struct Joypad {
const unsigned ID;
enum { Base = Mouse::Base + Mouse::Size * Mouse::Count };
enum { Count = 8, Size = 64 };
enum { Hats = 8, Axes = 16, Buttons = 32 };
enum Scancode {
Hat0, Hat1, Hat2, Hat3, Hat4, Hat5, Hat6, Hat7,
Axis0, Axis1, Axis2, Axis3, Axis4, Axis5, Axis6, Axis7,
Axis8, Axis9, Axis10, Axis11, Axis12, Axis13, Axis14, Axis15,
Button0, Button1, Button2, Button3, Button4, Button5, Button6, Button7,
Button8, Button9, Button10, Button11, Button12, Button13, Button14, Button15,
Button16, Button17, Button18, Button19, Button20, Button21, Button22, Button23,
Button24, Button25, Button26, Button27, Button28, Button29, Button30, Button31,
Limit,
};
enum Hat { HatCenter = 0, HatUp = 1, HatRight = 2, HatDown = 4, HatLeft = 8 };
static signed numberDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(joypad(i).belongsTo(scancode)) return i;
}
return -1;
}
static signed hatDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(joypad(i).isHat(scancode)) return scancode - joypad(i).hat(0);
}
return -1;
}
static signed axisDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(joypad(i).isAxis(scancode)) return scancode - joypad(i).axis(0);
}
return -1;
}
static signed buttonDecode(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(joypad(i).isButton(scancode)) return scancode - joypad(i).button(0);
}
return -1;
}
static bool isAnyHat(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(joypad(i).isHat(scancode)) return true;
}
return false;
}
static bool isAnyAxis(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(joypad(i).isAxis(scancode)) return true;
}
return false;
}
static bool isAnyButton(uint16_t scancode) {
for(unsigned i = 0; i < Count; i++) {
if(joypad(i).isButton(scancode)) return true;
}
return false;
}
static uint16_t decode(const char *name) {
string s(name);
if(!strbegin(name, "JP")) return 0;
s.ltrim("JP");
unsigned id = strunsigned(s);
auto pos = strpos(s, "::");
if(!pos) return 0;
s = substr(s, pos() + 2);
for(unsigned i = 0; i < Limit; i++) {
if(s == JoypadScancodeName[i]) return Base + Size * id + i;
}
return 0;
}
string encode(uint16_t code) const {
unsigned index = 0;
for(unsigned i = 0; i < Count; i++) {
if(code >= Base + Size * i && code < Base + Size * (i + 1)) {
index = code - (Base + Size * i);
}
}
return string() << "JP" << ID << "::" << JoypadScancodeName[index];
}
uint16_t operator[](Scancode code) const { return Base + ID * Size + code; }
uint16_t hat(unsigned id) const { return Base + Size * ID + Hat0 + id; }
uint16_t axis(unsigned id) const { return Base + Size * ID + Axis0 + id; }
uint16_t button(unsigned id) const { return Base + Size * ID + Button0 + id; }
bool isHat(unsigned id) const { return id >= hat(0) && id <= hat(7); }
bool isAxis(unsigned id) const { return id >= axis(0) && id <= axis(15); }
bool isButton(unsigned id) const { return id >= button(0) && id <= button(31); }
bool belongsTo(uint16_t scancode) const { return isHat(scancode) || isAxis(scancode) || isButton(scancode); }
Joypad(unsigned ID_) : ID(ID_) {}
};
inline Joypad& joypad(unsigned id) {
static Joypad jp0(0), jp1(1), jp2(2), jp3(3), jp4(4), jp5(5), jp6(6), jp7(7);
switch(id) { default:
case 0: return jp0; case 1: return jp1; case 2: return jp2; case 3: return jp3;
case 4: return jp4; case 5: return jp5; case 6: return jp6; case 7: return jp7;
}
}
struct Scancode {
enum { None = 0, Limit = Joypad::Base + Joypad::Size * Joypad::Count };
static uint16_t decode(const char *name) {
uint16_t code;
code = Keyboard::decode(name);
if(code) return code;
code = Mouse::decode(name);
if(code) return code;
code = Joypad::decode(name);
if(code) return code;
return None;
}
static string encode(uint16_t code) {
for(unsigned i = 0; i < Keyboard::Count; i++) {
if(keyboard(i).belongsTo(code)) return keyboard(i).encode(code);
}
for(unsigned i = 0; i < Mouse::Count; i++) {
if(mouse(i).belongsTo(code)) return mouse(i).encode(code);
}
for(unsigned i = 0; i < Joypad::Count; i++) {
if(joypad(i).belongsTo(code)) return joypad(i).encode(code);
}
return "None";
}
};
}
#endif
-81
View File
@@ -1,81 +0,0 @@
#ifndef NALL_LZSS_HPP
#define NALL_LZSS_HPP
#include <nall/array.hpp>
#include <nall/new.hpp>
#include <nall/stdint.hpp>
namespace nall {
class lzss {
public:
static bool encode(uint8_t *&output, unsigned &outlength, const uint8_t *input, unsigned inlength) {
output = new(zeromemory) uint8_t[inlength * 9 / 8 + 9];
unsigned i = 0, o = 0;
while(i < inlength) {
unsigned flagoffset = o++;
uint8_t flag = 0x00;
for(unsigned b = 0; b < 8 && i < inlength; b++) {
unsigned longest = 0, pointer;
for(unsigned index = 1; index < 4096; index++) {
unsigned count = 0;
while(true) {
if(count >= 15 + 3) break; //verify pattern match is not longer than max length
if(i + count >= inlength) break; //verify pattern match does not read past end of input
if(i + count < index) break; //verify read is not before start of input
if(input[i + count] != input[i + count - index]) break; //verify pattern still matches
count++;
}
if(count > longest) {
longest = count;
pointer = index;
}
}
if(longest < 3) output[o++] = input[i++];
else {
flag |= 1 << b;
uint16_t x = ((longest - 3) << 12) + pointer;
output[o++] = x;
output[o++] = x >> 8;
i += longest;
}
}
output[flagoffset] = flag;
}
outlength = o;
return true;
}
static bool decode(uint8_t *&output, const uint8_t *input, unsigned length) {
output = new(zeromemory) uint8_t[length];
unsigned i = 0, o = 0;
while(o < length) {
uint8_t flag = input[i++];
for(unsigned b = 0; b < 8 && o < length; b++) {
if(!(flag & (1 << b))) output[o++] = input[i++];
else {
uint16_t offset = input[i++];
offset += input[i++] << 8;
uint16_t lookuplength = (offset >> 12) + 3;
offset &= 4095;
for(unsigned index = 0; index < lookuplength && o + index < length; index++) {
output[o + index] = output[o + index - offset];
}
o += lookuplength;
}
}
}
return true;
}
};
}
#endif
-40
View File
@@ -1,40 +0,0 @@
#ifndef NALL_MODULO_HPP
#define NALL_MODULO_HPP
#include <nall/serializer.hpp>
namespace nall {
template<typename T, int size> class modulo_array {
public:
inline T operator[](int index) const {
return buffer[size + index];
}
inline T read(int index) const {
return buffer[size + index];
}
inline void write(unsigned index, const T value) {
buffer[index] =
buffer[index + size] =
buffer[index + size + size] = value;
}
void serialize(serializer &s) {
s.array(buffer, size * 3);
}
modulo_array() {
buffer = new T[size * 3]();
}
~modulo_array() {
delete[] buffer;
}
private:
T *buffer;
};
}
#endif
-122
View File
@@ -1,122 +0,0 @@
#ifndef NALL_PLATFORM_HPP
#define NALL_PLATFORM_HPP
#include <nall/utf8.hpp>
//=========================
//standard platform headers
//=========================
#include <limits>
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined(_WIN32)
#include <io.h>
#include <direct.h>
#include <shlobj.h>
#undef interface
#define dllexport __declspec(dllexport)
#else
#include <unistd.h>
#include <pwd.h>
#include <sys/stat.h>
#define dllexport
#endif
//==================
//warning supression
//==================
//Visual C++
#if defined(_MSC_VER)
//disable libc "deprecation" warnings
#pragma warning(disable:4996)
#endif
//================
//POSIX compliance
//================
#if defined(_MSC_VER)
#define PATH_MAX _MAX_PATH
#define va_copy(dest, src) ((dest) = (src))
#endif
#if defined(_WIN32)
#define getcwd _getcwd
#define ftruncate _chsize
#define putenv _putenv
#define mkdir(n, m) _wmkdir(nall::utf16_t(n))
#define rmdir _rmdir
#define vsnprintf _vsnprintf
#define usleep(n) Sleep(n / 1000)
#endif
//================
//inline expansion
//================
#if defined(__GNUC__)
#define noinline __attribute__((noinline))
#define inline inline
#define alwaysinline inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define noinline __declspec(noinline)
#define inline inline
#define alwaysinline inline __forceinline
#else
#define noinline
#define inline inline
#define alwaysinline inline
#endif
//=========================
//file system functionality
//=========================
#if defined(_WIN32)
inline char* realpath(const char *filename, char *resolvedname) {
wchar_t fn[_MAX_PATH] = L"";
_wfullpath(fn, nall::utf16_t(filename), _MAX_PATH);
strcpy(resolvedname, nall::utf8_t(fn));
return resolvedname;
}
inline char* userpath(char *path) {
wchar_t fp[_MAX_PATH] = L"";
SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, fp);
strcpy(path, nall::utf8_t(fp));
return path;
}
inline char* getcwd(char *path) {
wchar_t fp[_MAX_PATH] = L"";
_wgetcwd(fp, _MAX_PATH);
strcpy(path, nall::utf8_t(fp));
return path;
}
#else
//realpath() already exists
inline char* userpath(char *path) {
*path = 0;
struct passwd *userinfo = getpwuid(getuid());
if(userinfo) strcpy(path, userinfo->pw_dir);
return path;
}
inline char *getcwd(char *path) {
return getcwd(path, PATH_MAX);
}
#endif
#endif
-109
View File
@@ -1,109 +0,0 @@
#ifndef NALL_PRIORITYQUEUE_HPP
#define NALL_PRIORITYQUEUE_HPP
#include <limits>
#include <nall/function.hpp>
#include <nall/serializer.hpp>
#include <nall/utility.hpp>
namespace nall {
template<typename type_t> void priority_queue_nocallback(type_t) {}
//priority queue implementation using binary min-heap array;
//does not require normalize() function.
//O(1) find (tick)
//O(log n) insert (enqueue)
//O(log n) remove (dequeue)
template<typename type_t> class priority_queue {
public:
inline void tick(unsigned ticks) {
basecounter += ticks;
while(heapsize && gte(basecounter, heap[0].counter)) callback(dequeue());
}
//counter is relative to current time (eg enqueue(64, ...) fires in 64 ticks);
//counter cannot exceed std::numeric_limits<unsigned>::max() >> 1.
void enqueue(unsigned counter, type_t event) {
unsigned child = heapsize++;
counter += basecounter;
while(child) {
unsigned parent = (child - 1) >> 1;
if(gte(counter, heap[parent].counter)) break;
heap[child].counter = heap[parent].counter;
heap[child].event = heap[parent].event;
child = parent;
}
heap[child].counter = counter;
heap[child].event = event;
}
type_t dequeue() {
type_t event(heap[0].event);
unsigned parent = 0;
unsigned counter = heap[--heapsize].counter;
while(true) {
unsigned child = (parent << 1) + 1;
if(child >= heapsize) break;
if(child + 1 < heapsize && gte(heap[child].counter, heap[child + 1].counter)) child++;
if(gte(heap[child].counter, counter)) break;
heap[parent].counter = heap[child].counter;
heap[parent].event = heap[child].event;
parent = child;
}
heap[parent].counter = counter;
heap[parent].event = heap[heapsize].event;
return event;
}
void reset() {
basecounter = 0;
heapsize = 0;
}
void serialize(serializer &s) {
s.integer(basecounter);
s.integer(heapsize);
for(unsigned n = 0; n < heapcapacity; n++) {
s.integer(heap[n].counter);
s.integer(heap[n].event);
}
}
priority_queue(unsigned size, function<void (type_t)> callback_ = &priority_queue_nocallback<type_t>)
: callback(callback_) {
heap = new heap_t[size];
heapcapacity = size;
reset();
}
~priority_queue() {
delete[] heap;
}
priority_queue& operator=(const priority_queue&) = delete;
priority_queue(const priority_queue&) = delete;
private:
function<void (type_t)> callback;
unsigned basecounter;
unsigned heapsize;
unsigned heapcapacity;
struct heap_t {
unsigned counter;
type_t event;
} *heap;
//return true if x is greater than or equal to y
inline bool gte(unsigned x, unsigned y) {
return x - y < (std::numeric_limits<unsigned>::max() >> 1);
}
};
}
#endif
-91
View File
@@ -1,91 +0,0 @@
#ifndef NALL_PROPERTY_HPP
#define NALL_PROPERTY_HPP
//nall::property implements ownership semantics into container classes
//example: property<owner>::readonly<type> implies that only owner has full
//access to type; and all other code has readonly access.
//
//this code relies on extended friend semantics from C++0x to work, as it
//declares a friend class via a template paramter. it also exploits a bug in
//G++ 4.x to work even in C++98 mode.
//
//if compiling elsewhere, simply remove the friend class and private semantics
//property can be used either of two ways:
//struct foo {
// property<foo>::readonly<bool> x;
// property<foo>::readwrite<int> y;
//};
//-or-
//struct foo : property<foo> {
// readonly<bool> x;
// readwrite<int> y;
//};
//return types are const T& (byref) instead fo T (byval) to avoid major speed
//penalties for objects with expensive copy constructors
//operator-> provides access to underlying object type:
//readonly<Object> foo;
//foo->bar();
//... will call Object::bar();
//operator='s reference is constant so as to avoid leaking a reference handle
//that could bypass access restrictions
//both constant and non-constant operators are provided, though it may be
//necessary to cast first, for instance:
//struct foo : property<foo> { readonly<int> bar; } object;
//int main() { int value = const_cast<const foo&>(object); }
//writeonly is useful for objects that have non-const reads, but const writes.
//however, to avoid leaking handles, the interface is very restricted. the only
//way to write is via operator=, which requires conversion via eg copy
//constructor. example:
//struct foo {
// foo(bool value) { ... }
//};
//writeonly<foo> bar;
//bar = true;
namespace nall {
template<typename C> struct property {
template<typename T> struct traits { typedef T type; };
template<typename T> struct readonly {
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
private:
T* operator->() { return &value; }
operator T&() { return value; }
const T& operator=(const T& value_) { return value = value_; }
T value;
friend class traits<C>::type;
};
template<typename T> struct writeonly {
void operator=(const T& value_) { value = value_; }
private:
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
T* operator->() { return &value; }
operator T&() { return value; }
T value;
friend class traits<C>::type;
};
template<typename T> struct readwrite {
const T* operator->() const { return &value; }
const T& operator()() const { return value; }
operator const T&() const { return value; }
T* operator->() { return &value; }
operator T&() { return value; }
const T& operator=(const T& value_) { return value = value_; }
T value;
};
};
}
#endif
-20
View File
@@ -1,20 +0,0 @@
#ifndef NALL_RANDOM_HPP
#define NALL_RANDOM_HPP
namespace nall {
//pseudo-random number generator
inline unsigned prng() {
static unsigned n = 0;
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
}
struct random_cyclic {
unsigned seed;
inline unsigned operator()() {
return seed = (seed >> 1) ^ (((seed & 1) - 1) & 0xedb88320);
}
random_cyclic() : seed(0) {}
};
}
#endif
-85
View File
@@ -1,85 +0,0 @@
#ifndef NALL_SERIAL_HPP
#define NALL_SERIAL_HPP
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <nall/stdint.hpp>
namespace nall {
class serial {
public:
//-1 on error, otherwise return bytes read
int read(uint8_t *data, unsigned length) {
if(port_open == false) return -1;
return ::read(port, (void*)data, length);
}
//-1 on error, otherwise return bytes written
int write(const uint8_t *data, unsigned length) {
if(port_open == false) return -1;
return ::write(port, (void*)data, length);
}
bool open(const char *portname, unsigned rate, bool flowcontrol) {
close();
port = ::open(portname, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if(port == -1) return false;
if(ioctl(port, TIOCEXCL) == -1) { close(); return false; }
if(fcntl(port, F_SETFL, 0) == -1) { close(); return false; }
if(tcgetattr(port, &original_attr) == -1) { close(); return false; }
termios attr = original_attr;
cfmakeraw(&attr);
cfsetspeed(&attr, rate);
attr.c_lflag &=~ (ECHO | ECHONL | ISIG | ICANON | IEXTEN);
attr.c_iflag &=~ (BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY);
attr.c_iflag |= (IGNBRK | IGNPAR);
attr.c_oflag &=~ (OPOST);
attr.c_cflag &=~ (CSIZE | CSTOPB | PARENB | CLOCAL);
attr.c_cflag |= (CS8 | CREAD);
if(flowcontrol == false) {
attr.c_cflag &= ~CRTSCTS;
} else {
attr.c_cflag |= CRTSCTS;
}
attr.c_cc[VTIME] = attr.c_cc[VMIN] = 0;
if(tcsetattr(port, TCSANOW, &attr) == -1) { close(); return false; }
return port_open = true;
}
void close() {
if(port != -1) {
tcdrain(port);
if(port_open == true) {
tcsetattr(port, TCSANOW, &original_attr);
port_open = false;
}
::close(port);
port = -1;
}
}
serial() {
port = -1;
port_open = false;
}
~serial() {
close();
}
private:
int port;
bool port_open;
termios original_attr;
};
}
#endif
-146
View File
@@ -1,146 +0,0 @@
#ifndef NALL_SERIALIZER_HPP
#define NALL_SERIALIZER_HPP
#include <type_traits>
#include <utility>
#include <nall/stdint.hpp>
#include <nall/utility.hpp>
namespace nall {
//serializer: a class designed to save and restore the state of classes.
//
//benefits:
//- data() will be portable in size (it is not necessary to specify type sizes.)
//- data() will be portable in endianness (always stored internally as little-endian.)
//- one serialize function can both save and restore class states.
//
//caveats:
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
//- floating-point usage is not portable across platforms
class serializer {
public:
enum mode_t { Load, Save, Size };
mode_t mode() const {
return imode;
}
const uint8_t* data() const {
return idata;
}
unsigned size() const {
return isize;
}
unsigned capacity() const {
return icapacity;
}
template<typename T> void floatingpoint(T &value) {
enum { size = sizeof(T) };
//this is rather dangerous, and not cross-platform safe;
//but there is no standardized way to export FP-values
uint8_t *p = (uint8_t*)&value;
if(imode == Save) {
for(unsigned n = 0; n < size; n++) idata[isize++] = p[n];
} else if(imode == Load) {
for(unsigned n = 0; n < size; n++) p[n] = idata[isize++];
} else {
isize += size;
}
}
template<typename T> void integer(T &value) {
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
if(imode == Save) {
for(unsigned n = 0; n < size; n++) idata[isize++] = value >> (n << 3);
} else if(imode == Load) {
value = 0;
for(unsigned n = 0; n < size; n++) value |= idata[isize++] << (n << 3);
} else if(imode == Size) {
isize += size;
}
}
template<typename T> void array(T &array) {
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
for(unsigned n = 0; n < size; n++) integer(array[n]);
}
template<typename T> void array(T array, unsigned size) {
for(unsigned n = 0; n < size; n++) integer(array[n]);
}
//copy
serializer& operator=(const serializer &s) {
if(idata) delete[] idata;
imode = s.imode;
idata = new uint8_t[s.icapacity];
isize = s.isize;
icapacity = s.icapacity;
memcpy(idata, s.idata, s.icapacity);
return *this;
}
serializer(const serializer &s) : idata(0) {
operator=(s);
}
//move
serializer& operator=(serializer &&s) {
if(idata) delete[] idata;
imode = s.imode;
idata = s.idata;
isize = s.isize;
icapacity = s.icapacity;
s.idata = 0;
return *this;
}
serializer(serializer &&s) {
operator=(std::move(s));
}
//construction
serializer() {
imode = Size;
idata = 0;
isize = 0;
icapacity = 0;
}
serializer(unsigned capacity) {
imode = Save;
idata = new uint8_t[capacity]();
isize = 0;
icapacity = capacity;
}
serializer(const uint8_t *data, unsigned capacity) {
imode = Load;
idata = new uint8_t[capacity];
isize = 0;
icapacity = capacity;
memcpy(idata, data, capacity);
}
~serializer() {
if(idata) delete[] idata;
}
private:
mode_t imode;
uint8_t *idata;
unsigned isize;
unsigned icapacity;
};
};
#endif
-143
View File
@@ -1,143 +0,0 @@
#ifndef NALL_SHA256_HPP
#define NALL_SHA256_HPP
//author: vladitx
namespace nall {
#define PTR(t, a) ((t*)(a))
#define SWAP32(x) ((uint32_t)( \
(((uint32_t)(x) & 0x000000ff) << 24) | \
(((uint32_t)(x) & 0x0000ff00) << 8) | \
(((uint32_t)(x) & 0x00ff0000) >> 8) | \
(((uint32_t)(x) & 0xff000000) >> 24) \
))
#define ST32(a, d) *PTR(uint32_t, a) = (d)
#define ST32BE(a, d) ST32(a, SWAP32(d))
#define LD32(a) *PTR(uint32_t, a)
#define LD32BE(a) SWAP32(LD32(a))
#define LSL32(x, n) ((uint32_t)(x) << (n))
#define LSR32(x, n) ((uint32_t)(x) >> (n))
#define ROR32(x, n) (LSR32(x, n) | LSL32(x, 32 - (n)))
//first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
static const uint32_t T_H[8] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
};
//first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311
static const uint32_t T_K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
};
struct sha256_ctx {
uint8_t in[64];
unsigned inlen;
uint32_t w[64];
uint32_t h[8];
uint64_t len;
};
void sha256_init(sha256_ctx *p) {
memset(p, 0, sizeof(sha256_ctx));
memcpy(p->h, T_H, sizeof(T_H));
}
static void sha256_block(sha256_ctx *p) {
unsigned i;
uint32_t s0, s1;
uint32_t a, b, c, d, e, f, g, h;
uint32_t t1, t2, maj, ch;
for(i = 0; i < 16; i++) p->w[i] = LD32BE(p->in + i * 4);
for(i = 16; i < 64; i++) {
s0 = ROR32(p->w[i - 15], 7) ^ ROR32(p->w[i - 15], 18) ^ LSR32(p->w[i - 15], 3);
s1 = ROR32(p->w[i - 2], 17) ^ ROR32(p->w[i - 2], 19) ^ LSR32(p->w[i - 2], 10);
p->w[i] = p->w[i - 16] + s0 + p->w[i - 7] + s1;
}
a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
e = p->h[4]; f = p->h[5]; g = p->h[6]; h = p->h[7];
for(i = 0; i < 64; i++) {
s0 = ROR32(a, 2) ^ ROR32(a, 13) ^ ROR32(a, 22);
maj = (a & b) ^ (a & c) ^ (b & c);
t2 = s0 + maj;
s1 = ROR32(e, 6) ^ ROR32(e, 11) ^ ROR32(e, 25);
ch = (e & f) ^ (~e & g);
t1 = h + s1 + ch + T_K[i] + p->w[i];
h = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
p->h[0] += a; p->h[1] += b; p->h[2] += c; p->h[3] += d;
p->h[4] += e; p->h[5] += f; p->h[6] += g; p->h[7] += h;
//next block
p->inlen = 0;
}
void sha256_chunk(sha256_ctx *p, const uint8_t *s, unsigned len) {
unsigned l;
p->len += len;
while(len) {
l = 64 - p->inlen;
l = (len < l) ? len : l;
memcpy(p->in + p->inlen, s, l);
s += l;
p->inlen += l;
len -= l;
if(p->inlen == 64) sha256_block(p);
}
}
void sha256_final(sha256_ctx *p) {
uint64_t len;
p->in[p->inlen++] = 0x80;
if(p->inlen > 56) {
memset(p->in + p->inlen, 0, 64 - p->inlen);
sha256_block(p);
}
memset(p->in + p->inlen, 0, 56 - p->inlen);
len = p->len << 3;
ST32BE(p->in + 56, len >> 32);
ST32BE(p->in + 60, len);
sha256_block(p);
}
void sha256_hash(sha256_ctx *p, uint8_t *s) {
uint32_t *t = (uint32_t*)s;
for(unsigned i = 0; i < 8; i++) ST32BE(t++, p->h[i]);
}
#undef PTR
#undef SWAP32
#undef ST32
#undef ST32BE
#undef LD32
#undef LD32BE
#undef LSL32
#undef LSR32
#undef ROR32
}
#endif
Loaded 100 of 1168 files, more files were not shown because too many files have changed in this diff. Show more