mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-10 01:11:44 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
449a3ad426 | ||
|
|
ccfff86140 | ||
|
|
4525d00eba | ||
|
|
d0d8c2a921 | ||
|
|
8a91c95002 | ||
|
|
9484d1bc92 | ||
|
|
4163059b21 | ||
|
|
697f23d45c | ||
|
|
b671e49644 | ||
|
|
92ab697f8c | ||
|
|
4147dc42d0 | ||
|
|
05fca49b11 | ||
|
|
3a81ac94a5 | ||
|
|
3f43747474 | ||
|
|
5b4702afc4 | ||
|
|
7df9157abd | ||
|
|
f1009ec634 | ||
|
|
0bf6c40d1f | ||
|
|
2bafd18a5a | ||
|
|
c434e8a0d5 | ||
|
|
39b1acb177 | ||
|
|
920d139302 | ||
|
|
a59ecb3dd4 | ||
|
|
7b039b712e | ||
|
|
8d8bfe9e7e | ||
|
|
3c2ca5a383 | ||
|
|
b16fe19793 | ||
|
|
70429285ba | ||
|
|
cda10094da | ||
|
|
3c3956744f | ||
|
|
1a32ed7cfa | ||
|
|
fa0f1c1e98 | ||
|
|
9000bb4084 | ||
|
|
973ef89d4a | ||
|
|
94675634c1 | ||
|
|
b85025263a | ||
|
|
165f1e74b5 |
No files matched your search
Regular → Executable
+93
-43
@@ -1,43 +1,93 @@
|
||||
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
|
||||
include nall/Makefile
|
||||
snes := snes
|
||||
profile := compatibility
|
||||
ui := ui-qt
|
||||
|
||||
# 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 ui-qt/data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
install -D -m 644 ui-qt/data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
gconftool-2 --type bool --set /desktop/gnome/interface/menus_have_icons true
|
||||
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 launcher libco nall obj out phoenix ruby snes ui-phoenix ui-qt Makefile cc.bat clean.bat sync.sh
|
||||
|
||||
help:;
|
||||
@@ -1,314 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
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();
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
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)
|
||||
};
|
||||
@@ -1,194 +0,0 @@
|
||||
#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
|
||||
};
|
||||
@@ -1,114 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,377 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,342 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
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
@@ -1,424 +0,0 @@
|
||||
#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);
|
||||
@@ -1,26 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
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);
|
||||
};
|
||||
Binary file not shown.
Regular → Executable
+2
-2
@@ -1,2 +1,2 @@
|
||||
@nmake /NOLOGO
|
||||
@pause
|
||||
@mingw32-make -j 2
|
||||
@pause
|
||||
Regular → Executable
+1
-1
@@ -1 +1 @@
|
||||
@nmake /NOLOGO clean
|
||||
@mingw32-make clean
|
||||
@@ -1,339 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
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();
|
||||
};
|
||||
@@ -1,162 +0,0 @@
|
||||
#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
|
||||
};
|
||||
@@ -1,526 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,504 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,508 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,504 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,511 +0,0 @@
|
||||
/*****************
|
||||
*** 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);
|
||||
}
|
||||
@@ -1,504 +0,0 @@
|
||||
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
@@ -1,504 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,497 +0,0 @@
|
||||
/**********************
|
||||
*** 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);
|
||||
}
|
||||
@@ -1,526 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,873 +0,0 @@
|
||||
/*****************
|
||||
*** 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);
|
||||
}
|
||||
@@ -1,443 +0,0 @@
|
||||
/**********************
|
||||
*** 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);
|
||||
}
|
||||
@@ -1,357 +0,0 @@
|
||||
/*****************
|
||||
*** 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);
|
||||
}
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
<?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>
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Executable
+4
@@ -0,0 +1,4 @@
|
||||
@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
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
clear
|
||||
g++ -std=gnu++0x -s -O3 -fomit-frame-pointer -I.. -o ../out/bsnes launcher.cpp
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#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;
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
1 24 "bsnes.Manifest"
|
||||
IDI_ICON1 ICON DISCARDABLE "bsnes.ico"
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
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
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
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
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
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
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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
|
||||
Executable
+325
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* 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
|
||||
Executable
+478
@@ -0,0 +1,478 @@
|
||||
;*****
|
||||
;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
|
||||
|
||||
Executable
+513
@@ -0,0 +1,513 @@
|
||||
;*****
|
||||
;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
|
||||
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
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
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
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
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
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
@@ -1,214 +0,0 @@
|
||||
/* 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;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
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
|
||||
};
|
||||
@@ -1,434 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,393 +0,0 @@
|
||||
#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"
|
||||
@@ -1,181 +0,0 @@
|
||||
#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)); }
|
||||
@@ -1,82 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
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); }
|
||||
@@ -1,130 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
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);
|
||||
}
|
||||
|
||||
};
|
||||
Executable
+109
@@ -0,0 +1,109 @@
|
||||
# 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.4
|
||||
else
|
||||
compiler := gcc
|
||||
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,)
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#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
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#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
|
||||
Executable
+141
@@ -0,0 +1,141 @@
|
||||
#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
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#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
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#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
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#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
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
#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
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#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
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#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
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#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_once("\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_once("\"");
|
||||
part[1].trim_once("\"");
|
||||
|
||||
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
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#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 lstring folders(const char *pathname);
|
||||
static lstring files(const char *pathname);
|
||||
static lstring contents(const char *pathname);
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
inline lstring directory::folders(const char *pathname) {
|
||||
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) {
|
||||
list.append(string(utf8_t(data.cFileName), "/"));
|
||||
}
|
||||
}
|
||||
while(FindNextFile(handle, &data) != false) {
|
||||
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
|
||||
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
list.append(string(utf8_t(data.cFileName), "/"));
|
||||
}
|
||||
}
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::files(const char *pathname) {
|
||||
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) {
|
||||
list.append(utf8_t(data.cFileName));
|
||||
}
|
||||
while(FindNextFile(handle, &data) != false) {
|
||||
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
list.append(utf8_t(data.cFileName));
|
||||
}
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::contents(const char *pathname) {
|
||||
lstring folders = directory::folders(pathname);
|
||||
lstring files = directory::files(pathname);
|
||||
foreach(file, files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
#else
|
||||
inline lstring directory::folders(const char *pathname) {
|
||||
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) list.append(string(ep->d_name, "/"));
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
inline lstring directory::files(const char *pathname) {
|
||||
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) list.append(ep->d_name);
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::contents(const char *pathname) {
|
||||
lstring folders = directory::folders(pathname);
|
||||
lstring files = directory::files(pathname);
|
||||
foreach(file, files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+96
@@ -0,0 +1,96 @@
|
||||
#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
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#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
|
||||
Executable
+261
@@ -0,0 +1,261 @@
|
||||
#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 FileMode { mode_read, mode_write, mode_readwrite, mode_writeread };
|
||||
enum SeekMode { seek_absolute, seek_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, SeekMode mode = seek_absolute) {
|
||||
if(!fp) return; //file not open
|
||||
buffer_flush();
|
||||
|
||||
uintmax_t req_offset = file_offset;
|
||||
switch(mode) {
|
||||
case seek_absolute: req_offset = offset; break;
|
||||
case seek_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, FileMode 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;
|
||||
FileMode 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
|
||||
Executable
+190
@@ -0,0 +1,190 @@
|
||||
#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 filemode { mode_read, mode_write, mode_readwrite, mode_writeread };
|
||||
|
||||
bool open(const char *filename, filemode mode) { return p_open(filename, mode); }
|
||||
void close() { return p_close(); }
|
||||
unsigned size() const { return p_size; }
|
||||
uint8_t* handle() { return p_handle; }
|
||||
const uint8_t* handle() const { return p_handle; }
|
||||
filemap() : p_size(0), p_handle(0) { p_ctor(); }
|
||||
~filemap() { p_dtor(); }
|
||||
|
||||
private:
|
||||
unsigned p_size;
|
||||
uint8_t *p_handle;
|
||||
|
||||
#if defined(_WIN32)
|
||||
//=============
|
||||
//MapViewOfFile
|
||||
//=============
|
||||
|
||||
HANDLE p_filehandle, p_maphandle;
|
||||
|
||||
bool p_open(const char *filename, filemode 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_open(const char *filename, filemode 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);
|
||||
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
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#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
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#ifndef NALL_FUNCTION_HPP
|
||||
#define NALL_FUNCTION_HPP
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> class function;
|
||||
|
||||
template<typename R, typename... P>
|
||||
class function<R (P...)> {
|
||||
private:
|
||||
struct base1 { virtual void func1(P...) {} };
|
||||
struct base2 { virtual void func2(P...) {} };
|
||||
struct derived : base1, virtual base2 {};
|
||||
|
||||
struct data_t {
|
||||
R (*callback)(const data_t&, P...);
|
||||
union {
|
||||
R (*callback_global)(P...);
|
||||
struct {
|
||||
R (derived::*callback_member)(P...);
|
||||
void *object;
|
||||
};
|
||||
};
|
||||
} data;
|
||||
|
||||
static R callback_global(const data_t &data, P... p) {
|
||||
return data.callback_global(p...);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static R callback_member(const data_t &data, P... p) {
|
||||
return (((C*)data.object)->*((R (C::*&)(P...))data.callback_member))(p...);
|
||||
}
|
||||
|
||||
public:
|
||||
R operator()(P... p) const { return data.callback(data, p...); }
|
||||
operator bool() const { return data.callback; }
|
||||
void reset() { data.callback = 0; }
|
||||
|
||||
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
|
||||
function(const function &source) { operator=(source); }
|
||||
|
||||
//no pointer
|
||||
function() {
|
||||
data.callback = 0;
|
||||
}
|
||||
|
||||
//symbolic link pointer (nall/dl.hpp::sym, etc)
|
||||
function(void *callback) {
|
||||
data.callback = callback ? &callback_global : 0;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
|
||||
//global function pointer
|
||||
function(R (*callback)(P...)) {
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = callback;
|
||||
}
|
||||
|
||||
//member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...), C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//const member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...) const, C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//lambda function pointer
|
||||
template<typename T>
|
||||
function(T callback) {
|
||||
static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch");
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+386
@@ -0,0 +1,386 @@
|
||||
#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
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#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
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#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
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#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
|
||||
|
||||
Executable
+109
@@ -0,0 +1,109 @@
|
||||
#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
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#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
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
# requires nall/Makefile
|
||||
|
||||
# imports:
|
||||
# $(qtlibs) -- list of Qt components to link against
|
||||
|
||||
# exports the following symbols:
|
||||
# $(moc) -- meta-object compiler
|
||||
# $(rcc) -- resource compiler
|
||||
# $(qtinc) -- includes for compiling
|
||||
# $(qtlib) -- libraries for linking
|
||||
|
||||
ifeq ($(moc),)
|
||||
moc := moc
|
||||
endif
|
||||
|
||||
ifeq ($(rcc),)
|
||||
rcc := rcc
|
||||
endif
|
||||
|
||||
ifeq ($(platform),x)
|
||||
qtinc := `pkg-config --cflags $(qtlibs)`
|
||||
qtlib := `pkg-config --libs $(qtlibs)`
|
||||
else ifeq ($(platform),osx)
|
||||
qtinc := $(foreach lib,$(qtlibs),-I/Library/Frameworks/$(lib).framework/Versions/4/Headers)
|
||||
|
||||
qtlib := -L/Library/Frameworks
|
||||
qtlib += $(foreach lib,$(qtlibs),-framework $(lib))
|
||||
qtlib += -framework Carbon
|
||||
qtlib += -framework Cocoa
|
||||
qtlib += -framework OpenGL
|
||||
qtlib += -framework AppKit
|
||||
qtlib += -framework ApplicationServices
|
||||
else ifeq ($(platform),win)
|
||||
ifeq ($(qtpath),)
|
||||
# find Qt install directory from PATH environment variable
|
||||
qtpath := $(foreach path,$(subst ;, ,$(PATH)),$(if $(wildcard $(path)/$(moc).exe),$(path)))
|
||||
qtpath := $(strip $(qtpath))
|
||||
qtpath := $(subst \,/,$(qtpath))
|
||||
qtpath := $(patsubst %/bin,%,$(qtpath))
|
||||
endif
|
||||
|
||||
qtinc := -I$(qtpath)/include
|
||||
qtinc += $(foreach lib,$(qtlibs),-I$(qtpath)/include/$(lib))
|
||||
|
||||
qtlib := -L$(qtpath)/lib
|
||||
qtlib += -L$(qtpath)/plugins/imageformats
|
||||
|
||||
qtlib += $(foreach lib,$(qtlibs),-l$(lib)4)
|
||||
qtlib += -lmingw32 -lqtmain -lcomdlg32 -loleaut32 -limm32 -lwinmm
|
||||
qtlib += -lwinspool -lmsimg32 -lole32 -ladvapi32 -lws2_32 -luuid -lgdi32
|
||||
qtlib += $(foreach lib,$(qtlibs),-l$(lib)4)
|
||||
|
||||
# optional image-file support:
|
||||
# qtlib += -lqjpeg -lqmng
|
||||
endif
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#ifndef NALL_QT_CHECKACTION_HPP
|
||||
#define NALL_QT_CHECKACTION_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
class CheckAction : public QAction {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
bool isChecked() const;
|
||||
void setChecked(bool);
|
||||
void toggleChecked();
|
||||
CheckAction(const QString&, QObject*);
|
||||
|
||||
protected slots:
|
||||
|
||||
protected:
|
||||
bool checked;
|
||||
};
|
||||
|
||||
inline bool CheckAction::isChecked() const {
|
||||
return checked;
|
||||
}
|
||||
|
||||
inline void CheckAction::setChecked(bool checked_) {
|
||||
checked = checked_;
|
||||
if(checked) setIcon(QIcon(":/16x16/item-check-on.png"));
|
||||
else setIcon(QIcon(":/16x16/item-check-off.png"));
|
||||
}
|
||||
|
||||
inline void CheckAction::toggleChecked() {
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
|
||||
inline CheckAction::CheckAction(const QString &text, QObject *parent) : QAction(text, parent) {
|
||||
setChecked(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef NALL_QT_CONCEPT_HPP
|
||||
#define NALL_QT_CONCEPT_HPP
|
||||
|
||||
#include <nall/concept.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> struct has_count<QList<T>> { enum { value = true }; };
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+392
@@ -0,0 +1,392 @@
|
||||
#ifndef NALL_QT_FILEDIALOG_HPP
|
||||
#define NALL_QT_FILEDIALOG_HPP
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/qt/window.moc.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
class FileDialog;
|
||||
|
||||
class NewFolderDialog : public Window {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void show();
|
||||
NewFolderDialog(FileDialog*);
|
||||
|
||||
protected slots:
|
||||
void createFolderAction();
|
||||
|
||||
protected:
|
||||
FileDialog *parent;
|
||||
QVBoxLayout *layout;
|
||||
QLineEdit *folderNameEdit;
|
||||
QHBoxLayout *controlLayout;
|
||||
QPushButton *okButton;
|
||||
QPushButton *cancelButton;
|
||||
};
|
||||
|
||||
class FileView : public QListView {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
|
||||
signals:
|
||||
void changed(const QModelIndex&);
|
||||
void browseUp();
|
||||
|
||||
protected slots:
|
||||
void currentChanged(const QModelIndex&, const QModelIndex&);
|
||||
};
|
||||
|
||||
class FileDialog : public Window {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void showLoad();
|
||||
void showSave();
|
||||
void showFolder();
|
||||
|
||||
void setPath(string path);
|
||||
void setNameFilters(const string &filters);
|
||||
FileDialog();
|
||||
|
||||
signals:
|
||||
void changed(const string&);
|
||||
void activated(const string&);
|
||||
void accepted(const string&);
|
||||
void rejected();
|
||||
|
||||
protected slots:
|
||||
void fileViewChange(const QModelIndex&);
|
||||
void fileViewActivate(const QModelIndex&);
|
||||
void pathBoxChanged();
|
||||
void filterBoxChanged();
|
||||
void createNewFolder();
|
||||
void browseUp();
|
||||
void acceptAction();
|
||||
void rejectAction();
|
||||
|
||||
protected:
|
||||
NewFolderDialog *newFolderDialog;
|
||||
QVBoxLayout *layout;
|
||||
QHBoxLayout *navigationLayout;
|
||||
QComboBox *pathBox;
|
||||
QPushButton *newFolderButton;
|
||||
QPushButton *upFolderButton;
|
||||
QHBoxLayout *browseLayout;
|
||||
QFileSystemModel *fileSystemModel;
|
||||
FileView *fileView;
|
||||
QGroupBox *previewFrame;
|
||||
QLineEdit *fileNameEdit;
|
||||
QHBoxLayout *controlLayout;
|
||||
QComboBox *filterBox;
|
||||
QPushButton *optionsButton;
|
||||
QPushButton *acceptButton;
|
||||
QPushButton *rejectButton;
|
||||
bool lock;
|
||||
void createFolderAction(const string &name);
|
||||
void closeEvent(QCloseEvent*);
|
||||
|
||||
friend class NewFolderDialog;
|
||||
};
|
||||
|
||||
inline void NewFolderDialog::show() {
|
||||
folderNameEdit->setText("");
|
||||
Window::show();
|
||||
folderNameEdit->setFocus();
|
||||
}
|
||||
|
||||
inline void NewFolderDialog::createFolderAction() {
|
||||
string name = folderNameEdit->text().toUtf8().constData();
|
||||
if(name == "") {
|
||||
folderNameEdit->setFocus();
|
||||
} else {
|
||||
parent->createFolderAction(name);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
inline NewFolderDialog::NewFolderDialog(FileDialog *fileDialog) : parent(fileDialog) {
|
||||
setMinimumWidth(240);
|
||||
setWindowTitle("Create New Folder");
|
||||
|
||||
layout = new QVBoxLayout;
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
layout->setMargin(5);
|
||||
layout->setSpacing(5);
|
||||
setLayout(layout);
|
||||
|
||||
folderNameEdit = new QLineEdit;
|
||||
layout->addWidget(folderNameEdit);
|
||||
|
||||
controlLayout = new QHBoxLayout;
|
||||
controlLayout->setAlignment(Qt::AlignRight);
|
||||
layout->addLayout(controlLayout);
|
||||
|
||||
okButton = new QPushButton("Ok");
|
||||
controlLayout->addWidget(okButton);
|
||||
|
||||
cancelButton = new QPushButton("Cancel");
|
||||
controlLayout->addWidget(cancelButton);
|
||||
|
||||
connect(folderNameEdit, SIGNAL(returnPressed()), this, SLOT(createFolderAction()));
|
||||
connect(okButton, SIGNAL(released()), this, SLOT(createFolderAction()));
|
||||
connect(cancelButton, SIGNAL(released()), this, SLOT(close()));
|
||||
}
|
||||
|
||||
inline void FileView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
|
||||
QAbstractItemView::currentChanged(current, previous);
|
||||
emit changed(current);
|
||||
}
|
||||
|
||||
inline void FileView::keyPressEvent(QKeyEvent *event) {
|
||||
//enhance consistency: force OS X to act like Windows and Linux; enter = activate item
|
||||
if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
|
||||
emit activated(currentIndex());
|
||||
return;
|
||||
}
|
||||
|
||||
//simulate popular file manager behavior; backspace = go up one directory
|
||||
if(event->key() == Qt::Key_Backspace) {
|
||||
emit browseUp();
|
||||
return;
|
||||
}
|
||||
|
||||
//fallback: unrecognized keypresses get handled by the widget itself
|
||||
QListView::keyPressEvent(event);
|
||||
}
|
||||
|
||||
inline void FileDialog::showLoad() {
|
||||
acceptButton->setText("Load");
|
||||
fileNameEdit->hide();
|
||||
filterBox->show();
|
||||
show();
|
||||
}
|
||||
|
||||
inline void FileDialog::showSave() {
|
||||
acceptButton->setText("Save");
|
||||
fileNameEdit->show();
|
||||
filterBox->show();
|
||||
show();
|
||||
}
|
||||
|
||||
inline void FileDialog::showFolder() {
|
||||
acceptButton->setText("Choose");
|
||||
fileNameEdit->hide();
|
||||
filterBox->hide();
|
||||
setNameFilters("Folders ()");
|
||||
show();
|
||||
}
|
||||
|
||||
inline void FileDialog::fileViewChange(const QModelIndex &index) {
|
||||
string path = fileSystemModel->filePath(index).toUtf8().constData();
|
||||
if(path == fileSystemModel->rootPath().toUtf8().constData()) path = "";
|
||||
fileNameEdit->setText(notdir(path));
|
||||
emit changed(path);
|
||||
}
|
||||
|
||||
inline void FileDialog::fileViewActivate(const QModelIndex &index) {
|
||||
string path = fileSystemModel->filePath(index).toUtf8().constData();
|
||||
if(fileSystemModel->isDir(index)) {
|
||||
emit activated(path);
|
||||
setPath(path);
|
||||
} else {
|
||||
emit activated(path);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
inline void FileDialog::pathBoxChanged() {
|
||||
if(lock) return;
|
||||
setPath(pathBox->currentText().toUtf8().constData());
|
||||
}
|
||||
|
||||
inline void FileDialog::filterBoxChanged() {
|
||||
if(lock) return;
|
||||
string filters = filterBox->currentText().toUtf8().constData();
|
||||
if(filters.length() == 0) {
|
||||
fileSystemModel->setNameFilters(QStringList() << "*");
|
||||
} else {
|
||||
filters = substr(filters, strpos(filters, "(")());
|
||||
filters.ltrim("(");
|
||||
filters.rtrim(")");
|
||||
lstring part;
|
||||
part.split(" ", filters);
|
||||
QStringList list;
|
||||
for(unsigned i = 0; i < part.size(); i++) list << part[i];
|
||||
fileSystemModel->setNameFilters(list);
|
||||
}
|
||||
}
|
||||
|
||||
inline void FileDialog::createNewFolder() {
|
||||
newFolderDialog->show();
|
||||
}
|
||||
|
||||
inline void FileDialog::browseUp() {
|
||||
if(pathBox->count() > 1) pathBox->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
inline void FileDialog::setPath(string path) {
|
||||
lock = true;
|
||||
newFolderDialog->close();
|
||||
|
||||
if(QDir(path).exists()) {
|
||||
newFolderButton->setEnabled(true);
|
||||
} else {
|
||||
newFolderButton->setEnabled(false);
|
||||
path = "";
|
||||
}
|
||||
|
||||
fileSystemModel->setRootPath(path);
|
||||
fileView->setRootIndex(fileSystemModel->index(path));
|
||||
fileView->setCurrentIndex(fileView->rootIndex());
|
||||
fileView->setFocus();
|
||||
|
||||
pathBox->clear();
|
||||
if(path.length() > 0) {
|
||||
QDir directory(path);
|
||||
while(true) {
|
||||
pathBox->addItem(directory.absolutePath());
|
||||
if(directory.isRoot()) break;
|
||||
directory.cdUp();
|
||||
}
|
||||
}
|
||||
pathBox->addItem("<root>");
|
||||
fileNameEdit->setText("");
|
||||
|
||||
lock = false;
|
||||
}
|
||||
|
||||
inline void FileDialog::setNameFilters(const string &filters) {
|
||||
lock = true;
|
||||
|
||||
lstring list;
|
||||
list.split("\n", filters);
|
||||
|
||||
filterBox->clear();
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
filterBox->addItem(list[i]);
|
||||
}
|
||||
|
||||
lock = false;
|
||||
filterBoxChanged();
|
||||
}
|
||||
|
||||
inline void FileDialog::acceptAction() {
|
||||
string path = fileSystemModel->rootPath().toUtf8().constData();
|
||||
path << "/" << notdir(fileNameEdit->text().toUtf8().constData());
|
||||
path.rtrim("/");
|
||||
if(QDir(path).exists()) {
|
||||
emit accepted(path);
|
||||
setPath(path);
|
||||
} else {
|
||||
emit accepted(path);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
inline void FileDialog::rejectAction() {
|
||||
emit rejected();
|
||||
close();
|
||||
}
|
||||
|
||||
inline void FileDialog::createFolderAction(const string &name) {
|
||||
string path = fileSystemModel->rootPath().toUtf8().constData();
|
||||
path << "/" << notdir(name);
|
||||
mkdir(path, 0755);
|
||||
}
|
||||
|
||||
inline void FileDialog::closeEvent(QCloseEvent *event) {
|
||||
newFolderDialog->close();
|
||||
Window::closeEvent(event);
|
||||
}
|
||||
|
||||
inline FileDialog::FileDialog() {
|
||||
newFolderDialog = new NewFolderDialog(this);
|
||||
resize(640, 360);
|
||||
|
||||
layout = new QVBoxLayout;
|
||||
layout->setMargin(5);
|
||||
layout->setSpacing(5);
|
||||
setLayout(layout);
|
||||
|
||||
navigationLayout = new QHBoxLayout;
|
||||
layout->addLayout(navigationLayout);
|
||||
|
||||
pathBox = new QComboBox;
|
||||
pathBox->setEditable(true);
|
||||
pathBox->setMinimumContentsLength(16);
|
||||
pathBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
|
||||
pathBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
navigationLayout->addWidget(pathBox);
|
||||
|
||||
newFolderButton = new QPushButton;
|
||||
newFolderButton->setIconSize(QSize(16, 16));
|
||||
newFolderButton->setIcon(QIcon(":/16x16/folder-new.png"));
|
||||
navigationLayout->addWidget(newFolderButton);
|
||||
|
||||
upFolderButton = new QPushButton;
|
||||
upFolderButton->setIconSize(QSize(16, 16));
|
||||
upFolderButton->setIcon(QIcon(":/16x16/go-up.png"));
|
||||
navigationLayout->addWidget(upFolderButton);
|
||||
|
||||
browseLayout = new QHBoxLayout;
|
||||
layout->addLayout(browseLayout);
|
||||
|
||||
fileSystemModel = new QFileSystemModel;
|
||||
fileSystemModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||
fileSystemModel->setNameFilterDisables(false);
|
||||
|
||||
fileView = new FileView;
|
||||
fileView->setMinimumWidth(320);
|
||||
fileView->setModel(fileSystemModel);
|
||||
fileView->setIconSize(QSize(16, 16));
|
||||
browseLayout->addWidget(fileView);
|
||||
|
||||
previewFrame = new QGroupBox;
|
||||
previewFrame->hide();
|
||||
browseLayout->addWidget(previewFrame);
|
||||
|
||||
fileNameEdit = new QLineEdit;
|
||||
layout->addWidget(fileNameEdit);
|
||||
|
||||
controlLayout = new QHBoxLayout;
|
||||
controlLayout->setAlignment(Qt::AlignRight);
|
||||
layout->addLayout(controlLayout);
|
||||
|
||||
filterBox = new QComboBox;
|
||||
filterBox->setMinimumContentsLength(16);
|
||||
filterBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
|
||||
filterBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
controlLayout->addWidget(filterBox);
|
||||
|
||||
optionsButton = new QPushButton("Options");
|
||||
optionsButton->hide();
|
||||
controlLayout->addWidget(optionsButton);
|
||||
|
||||
acceptButton = new QPushButton("Ok");
|
||||
controlLayout->addWidget(acceptButton);
|
||||
|
||||
rejectButton = new QPushButton("Cancel");
|
||||
controlLayout->addWidget(rejectButton);
|
||||
|
||||
lock = false;
|
||||
connect(pathBox, SIGNAL(currentIndexChanged(int)), this, SLOT(pathBoxChanged()));
|
||||
connect(newFolderButton, SIGNAL(released()), this, SLOT(createNewFolder()));
|
||||
connect(upFolderButton, SIGNAL(released()), this, SLOT(browseUp()));
|
||||
connect(fileView, SIGNAL(changed(const QModelIndex&)), this, SLOT(fileViewChange(const QModelIndex&)));
|
||||
connect(fileView, SIGNAL(activated(const QModelIndex&)), this, SLOT(fileViewActivate(const QModelIndex&)));
|
||||
connect(fileView, SIGNAL(browseUp()), this, SLOT(browseUp()));
|
||||
connect(fileNameEdit, SIGNAL(returnPressed()), this, SLOT(acceptAction()));
|
||||
connect(filterBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterBoxChanged()));
|
||||
connect(acceptButton, SIGNAL(released()), this, SLOT(acceptAction()));
|
||||
connect(rejectButton, SIGNAL(released()), this, SLOT(rejectAction()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+173
@@ -0,0 +1,173 @@
|
||||
#ifndef NALL_QT_HEXEDITOR_HPP
|
||||
#define NALL_QT_HEXEDITOR_HPP
|
||||
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
class HexEditor : public QTextEdit {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
function<uint8_t (unsigned)> reader;
|
||||
function<void (unsigned, uint8_t)> writer;
|
||||
|
||||
void setColumns(unsigned columns);
|
||||
void setRows(unsigned rows);
|
||||
void setOffset(unsigned offset);
|
||||
void setSize(unsigned size);
|
||||
unsigned lineWidth() const;
|
||||
void refresh();
|
||||
|
||||
HexEditor();
|
||||
|
||||
protected slots:
|
||||
void scrolled();
|
||||
|
||||
protected:
|
||||
QHBoxLayout *layout;
|
||||
QScrollBar *scrollBar;
|
||||
unsigned editorColumns;
|
||||
unsigned editorRows;
|
||||
unsigned editorOffset;
|
||||
unsigned editorSize;
|
||||
bool lock;
|
||||
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
};
|
||||
|
||||
inline void HexEditor::keyPressEvent(QKeyEvent *event) {
|
||||
QTextCursor cursor = textCursor();
|
||||
unsigned x = cursor.position() % lineWidth();
|
||||
unsigned y = cursor.position() / lineWidth();
|
||||
|
||||
int hexCode = -1;
|
||||
switch(event->key()) {
|
||||
case Qt::Key_0: hexCode = 0; break;
|
||||
case Qt::Key_1: hexCode = 1; break;
|
||||
case Qt::Key_2: hexCode = 2; break;
|
||||
case Qt::Key_3: hexCode = 3; break;
|
||||
case Qt::Key_4: hexCode = 4; break;
|
||||
case Qt::Key_5: hexCode = 5; break;
|
||||
case Qt::Key_6: hexCode = 6; break;
|
||||
case Qt::Key_7: hexCode = 7; break;
|
||||
case Qt::Key_8: hexCode = 8; break;
|
||||
case Qt::Key_9: hexCode = 9; break;
|
||||
case Qt::Key_A: hexCode = 10; break;
|
||||
case Qt::Key_B: hexCode = 11; break;
|
||||
case Qt::Key_C: hexCode = 12; break;
|
||||
case Qt::Key_D: hexCode = 13; break;
|
||||
case Qt::Key_E: hexCode = 14; break;
|
||||
case Qt::Key_F: hexCode = 15; break;
|
||||
}
|
||||
|
||||
if(cursor.hasSelection() == false && hexCode != -1) {
|
||||
bool cursorOffsetValid = (x >= 11 && ((x - 11) % 3) != 2);
|
||||
if(cursorOffsetValid) {
|
||||
bool nibble = (x - 11) % 3; //0 = top nibble, 1 = bottom nibble
|
||||
unsigned cursorOffset = y * editorColumns + ((x - 11) / 3);
|
||||
unsigned effectiveOffset = editorOffset + cursorOffset;
|
||||
if(effectiveOffset >= editorSize) effectiveOffset %= editorSize;
|
||||
|
||||
uint8_t data = reader ? reader(effectiveOffset) : 0x00;
|
||||
data &= (nibble == 0 ? 0x0f : 0xf0);
|
||||
data |= (nibble == 0 ? (hexCode << 4) : (hexCode << 0));
|
||||
if(writer) writer(effectiveOffset, data);
|
||||
refresh();
|
||||
|
||||
cursor.setPosition(y * lineWidth() + x + 1); //advance cursor
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
} else {
|
||||
//allow navigation keys to move cursor, but block text input
|
||||
setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
|
||||
QTextEdit::keyPressEvent(event);
|
||||
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||
}
|
||||
}
|
||||
|
||||
inline void HexEditor::setColumns(unsigned columns) {
|
||||
editorColumns = columns;
|
||||
}
|
||||
|
||||
inline void HexEditor::setRows(unsigned rows) {
|
||||
editorRows = rows;
|
||||
scrollBar->setPageStep(editorRows);
|
||||
}
|
||||
|
||||
inline void HexEditor::setOffset(unsigned offset) {
|
||||
lock = true;
|
||||
editorOffset = offset;
|
||||
scrollBar->setSliderPosition(editorOffset / editorColumns);
|
||||
lock = false;
|
||||
}
|
||||
|
||||
inline void HexEditor::setSize(unsigned size) {
|
||||
editorSize = size;
|
||||
bool indivisible = (editorSize % editorColumns) != 0; //add one for incomplete row
|
||||
scrollBar->setRange(0, editorSize / editorColumns + indivisible - editorRows);
|
||||
}
|
||||
|
||||
inline unsigned HexEditor::lineWidth() const {
|
||||
return 11 + 3 * editorColumns;
|
||||
}
|
||||
|
||||
inline void HexEditor::refresh() {
|
||||
string output;
|
||||
char temp[256];
|
||||
unsigned offset = editorOffset;
|
||||
|
||||
for(unsigned y = 0; y < editorRows; y++) {
|
||||
if(offset >= editorSize) break;
|
||||
sprintf(temp, "%.4x:%.4x", (offset >> 16) & 0xffff, (offset >> 0) & 0xffff);
|
||||
output << "<font color='#808080'>" << temp << "</font> ";
|
||||
|
||||
for(unsigned x = 0; x < editorColumns; x++) {
|
||||
if(offset >= editorSize) break;
|
||||
sprintf(temp, "%.2x", reader ? reader(offset) : 0x00);
|
||||
offset++;
|
||||
output << "<font color='" << ((x & 1) ? "#000080" : "#0000ff") << "'>" << temp << "</font>";
|
||||
if(x != (editorColumns - 1)) output << " ";
|
||||
}
|
||||
|
||||
if(y != (editorRows - 1)) output << "<br>";
|
||||
}
|
||||
|
||||
setHtml(output);
|
||||
}
|
||||
|
||||
inline void HexEditor::scrolled() {
|
||||
if(lock) return;
|
||||
unsigned offset = scrollBar->sliderPosition();
|
||||
editorOffset = offset * editorColumns;
|
||||
refresh();
|
||||
}
|
||||
|
||||
inline HexEditor::HexEditor() {
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
layout = new QHBoxLayout;
|
||||
layout->setAlignment(Qt::AlignRight);
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(0);
|
||||
setLayout(layout);
|
||||
|
||||
scrollBar = new QScrollBar(Qt::Vertical);
|
||||
scrollBar->setSingleStep(1);
|
||||
layout->addWidget(scrollBar);
|
||||
|
||||
lock = false;
|
||||
connect(scrollBar, SIGNAL(actionTriggered(int)), this, SLOT(scrolled()));
|
||||
|
||||
setColumns(16);
|
||||
setRows(16);
|
||||
setSize(0);
|
||||
setOffset(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#ifndef NALL_QT_RADIOACTION_HPP
|
||||
#define NALL_QT_RADIOACTION_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
class RadioAction : public QAction {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
bool isChecked() const;
|
||||
void setChecked(bool);
|
||||
void toggleChecked();
|
||||
RadioAction(const QString&, QObject*);
|
||||
|
||||
protected slots:
|
||||
|
||||
protected:
|
||||
bool checked;
|
||||
};
|
||||
|
||||
inline bool RadioAction::isChecked() const {
|
||||
return checked;
|
||||
}
|
||||
|
||||
inline void RadioAction::setChecked(bool checked_) {
|
||||
checked = checked_;
|
||||
if(checked) setIcon(QIcon(":/16x16/item-radio-on.png"));
|
||||
else setIcon(QIcon(":/16x16/item-radio-off.png"));
|
||||
}
|
||||
|
||||
inline void RadioAction::toggleChecked() {
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
|
||||
inline RadioAction::RadioAction(const QString &text, QObject *parent) : QAction(text, parent) {
|
||||
setChecked(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#ifndef NALL_QT_WINDOW_HPP
|
||||
#define NALL_QT_WINDOW_HPP
|
||||
|
||||
#include <nall/base64.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
class Window : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void setGeometryString(string *geometryString);
|
||||
void setCloseOnEscape(bool);
|
||||
void show();
|
||||
void hide();
|
||||
void shrink();
|
||||
|
||||
Window();
|
||||
|
||||
protected slots:
|
||||
|
||||
protected:
|
||||
string *geometryString;
|
||||
bool closeOnEscape;
|
||||
void keyReleaseEvent(QKeyEvent *event);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
};
|
||||
|
||||
inline void Window::setGeometryString(string *geometryString_) {
|
||||
geometryString = geometryString_;
|
||||
if(geometryString && isVisible() == false) {
|
||||
uint8_t *data;
|
||||
unsigned length;
|
||||
base64::decode(data, length, *geometryString);
|
||||
QByteArray array((const char*)data, length);
|
||||
delete[] data;
|
||||
restoreGeometry(array);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Window::setCloseOnEscape(bool value) {
|
||||
closeOnEscape = value;
|
||||
}
|
||||
|
||||
inline void Window::show() {
|
||||
if(geometryString && isVisible() == false) {
|
||||
uint8_t *data;
|
||||
unsigned length;
|
||||
base64::decode(data, length, *geometryString);
|
||||
QByteArray array((const char*)data, length);
|
||||
delete[] data;
|
||||
restoreGeometry(array);
|
||||
}
|
||||
QWidget::show();
|
||||
QApplication::processEvents();
|
||||
activateWindow();
|
||||
raise();
|
||||
}
|
||||
|
||||
inline void Window::hide() {
|
||||
if(geometryString && isVisible() == true) {
|
||||
char *data;
|
||||
QByteArray geometry = saveGeometry();
|
||||
base64::encode(data, (const uint8_t*)geometry.data(), geometry.length());
|
||||
*geometryString = data;
|
||||
delete[] data;
|
||||
}
|
||||
QWidget::hide();
|
||||
}
|
||||
|
||||
inline void Window::shrink() {
|
||||
if(isFullScreen()) return;
|
||||
|
||||
for(unsigned i = 0; i < 2; i++) {
|
||||
resize(0, 0);
|
||||
usleep(2000);
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
inline void Window::keyReleaseEvent(QKeyEvent *event) {
|
||||
if(closeOnEscape && (event->key() == Qt::Key_Escape)) close();
|
||||
QWidget::keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
inline void Window::closeEvent(QCloseEvent *event) {
|
||||
if(geometryString) {
|
||||
char *data;
|
||||
QByteArray geometry = saveGeometry();
|
||||
base64::encode(data, (const uint8_t*)geometry.data(), geometry.length());
|
||||
*geometryString = data;
|
||||
delete[] data;
|
||||
}
|
||||
QWidget::closeEvent(event);
|
||||
}
|
||||
|
||||
inline Window::Window() {
|
||||
geometryString = 0;
|
||||
closeOnEscape = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#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
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#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
|
||||
Loaded 100 of 1159 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user