mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-09 01:09:46 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fc86eae6d | ||
|
|
927c97eb06 | ||
|
|
cf09d41669 | ||
|
|
724747ac9e | ||
|
|
e1e275eb38 | ||
|
|
e30fcade43 | ||
|
|
42dbf73d18 | ||
|
|
2a90e12999 | ||
|
|
d129b72ced | ||
|
|
bc0b86891a | ||
|
|
52443936e6 | ||
|
|
6694a1c986 | ||
|
|
7ffaeb2ac1 | ||
|
|
67e6a6e742 | ||
|
|
9a3650c6ab | ||
|
|
0a3d6e4c53 | ||
|
|
378b78dad7 | ||
|
|
721e0b1762 | ||
|
|
2bf3dbf375 | ||
|
|
396003e7f6 | ||
|
|
a92a554d7b | ||
|
|
9ea35ce569 | ||
|
|
348bace8ed | ||
|
|
5cbf5b617b | ||
|
|
d5cd21eb0c | ||
|
|
8b7dd89059 | ||
|
|
6c4e3ec790 | ||
|
|
8d64f9b155 | ||
|
|
bc5fd8c53c | ||
|
|
64072325c4 | ||
|
|
017f9926fc | ||
|
|
c31543ea58 | ||
|
|
7c3aaf12b0 | ||
|
|
3fad0a0105 | ||
|
|
72a2967eeb | ||
|
|
a8ee35633c | ||
|
|
7dda70baa4 | ||
|
|
2c61ce2522 | ||
|
|
266495b475 | ||
|
|
133d568f76 | ||
|
|
b433838e9f | ||
|
|
a3abe8ebaa | ||
|
|
f88ef9e9a2 | ||
|
|
a136378a7b | ||
|
|
012cdd4b14 | ||
|
|
eecc085e42 | ||
|
|
6b4104867f | ||
|
|
53fe43afd8 | ||
|
|
054bdd4094 | ||
|
|
ecf96726f9 | ||
|
|
cab5917806 | ||
|
|
c833b69087 | ||
|
|
1a065bafb1 | ||
|
|
ea077a7d96 | ||
|
|
a937f9b79b | ||
|
|
2d73086569 | ||
|
|
5810e69be3 | ||
|
|
a198e555dc | ||
|
|
20afa076ef | ||
|
|
92da6bde26 | ||
|
|
73113da41e | ||
|
|
a7ffc31282 | ||
|
|
1c6a8543cd | ||
|
|
4dbce5a0b2 | ||
|
|
3f960374ad | ||
|
|
d8a386031f | ||
|
|
f0796e546e | ||
|
|
2d49a4408d | ||
|
|
a7ffbd784b | ||
|
|
afdb3c4d20 | ||
|
|
ebd6a52811 | ||
|
|
42a9f9cfa4 | ||
|
|
2330ed6e8c | ||
|
|
71780949b0 | ||
|
|
1c3c7fe0a7 | ||
|
|
e0a9f1cf2c | ||
|
|
246d6aaf08 | ||
|
|
da7d9f2662 | ||
|
|
e0a5452e8d | ||
|
|
6ea4bc031f | ||
|
|
676a3adbf7 | ||
|
|
b27e0a719d | ||
|
|
a62aa94b65 | ||
|
|
9762a092d2 | ||
|
|
05526571e7 | ||
|
|
3bd29088d1 | ||
|
|
26643a43de | ||
|
|
7e8958b102 | ||
|
|
edac93b800 | ||
|
|
0730f847e5 | ||
|
|
5ae0c80ee8 | ||
|
|
d0ef8e7488 | ||
|
|
6c3aec7dc9 | ||
|
|
4016ae1d43 | ||
|
|
9e53c51b58 | ||
|
|
ce2b543679 | ||
|
|
1a29b59225 | ||
|
|
1926561ced | ||
|
|
e2db2c24fc | ||
|
|
8a53e9ed22 | ||
|
|
5286481d8d | ||
|
|
440a59c879 | ||
|
|
96e9333ec2 | ||
|
|
775c111fef | ||
|
|
3ffa44cef9 | ||
|
|
f28d70f9e6 | ||
|
|
73fdbf893f | ||
|
|
da5263bfc3 | ||
|
|
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
+75
-43
@@ -1,43 +1,75 @@
|
||||
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
|
||||
gameboy := gameboy
|
||||
profile := compatibility
|
||||
ui := ui
|
||||
|
||||
# debugger
|
||||
options :=
|
||||
|
||||
# compiler
|
||||
c := $(compiler) -std=gnu99
|
||||
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||
flags := -O3 -fomit-frame-pointer -I.
|
||||
link :=
|
||||
objects := libco
|
||||
|
||||
# profile-guided instrumentation
|
||||
# flags += -fprofile-generate
|
||||
# link += -lgcov
|
||||
|
||||
# profile-guided optimization
|
||||
# flags += -fprofile-use
|
||||
|
||||
flags := $(flags) $(foreach o,$(call strupper,$(options)),-D$o)
|
||||
|
||||
# platform
|
||||
ifeq ($(platform),x)
|
||||
link += -s -ldl -lX11 -lXext
|
||||
else ifeq ($(platform),osx)
|
||||
else ifeq ($(platform),win)
|
||||
link += -mwindows
|
||||
# link += -mconsole
|
||||
link += -mthreads -s -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32
|
||||
link += -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
||||
else
|
||||
unknown_platform: help;
|
||||
endif
|
||||
|
||||
# implicit rules
|
||||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(c) $(flags) $1 -c $< -o $@, \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(cpp) $(flags) $1 -c $< -o $@ \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
%.o: $<; $(call compile)
|
||||
|
||||
all: build;
|
||||
|
||||
obj/libco.o: libco/libco.c libco/*
|
||||
|
||||
include $(ui)/Makefile
|
||||
|
||||
# targets
|
||||
clean:
|
||||
-@$(call delete,obj/*.o)
|
||||
-@$(call delete,obj/*.a)
|
||||
-@$(call delete,obj/*.so)
|
||||
-@$(call delete,obj/*.dylib)
|
||||
-@$(call delete,obj/*.dll)
|
||||
-@$(call delete,*.res)
|
||||
-@$(call delete,*.pgd)
|
||||
-@$(call delete,*.pgc)
|
||||
-@$(call delete,*.ilk)
|
||||
-@$(call delete,*.pdb)
|
||||
-@$(call delete,*.manifest)
|
||||
|
||||
archive-all:
|
||||
tar -cjf bsnes.tar.bz2 data gameboy libco nall obj out phoenix ruby snes ui ui-gameboy ui-libsnes 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 8
|
||||
@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="*"/>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Name=bsnes
|
||||
Comment=SNES emulator
|
||||
Exec=bsnes
|
||||
Icon=bsnes
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Game;Emulator;
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Executable
+58121
File diff suppressed because it is too large.
Load diff
Executable
+12
@@ -0,0 +1,12 @@
|
||||
gameboy_objects := gameboy-system gameboy-scheduler
|
||||
gameboy_objects += gameboy-memory gameboy-cartridge
|
||||
gameboy_objects += gameboy-cpu gameboy-apu gameboy-lcd
|
||||
objects += $(gameboy_objects)
|
||||
|
||||
obj/gameboy-system.o: $(gameboy)/system/system.cpp $(call rwildcard,$(gameboy)/system/)
|
||||
obj/gameboy-scheduler.o: $(gameboy)/scheduler/scheduler.cpp $(call rwildcard,$(gameboy)/scheduler/)
|
||||
obj/gameboy-cartridge.o: $(gameboy)/cartridge/cartridge.cpp $(call rwildcard,$(gameboy)/cartridge/)
|
||||
obj/gameboy-memory.o: $(gameboy)/memory/memory.cpp $(call rwildcard,$(gameboy)/memory/)
|
||||
obj/gameboy-cpu.o: $(gameboy)/cpu/cpu.cpp $(call rwildcard,$(gameboy)/cpu/)
|
||||
obj/gameboy-apu.o: $(gameboy)/apu/apu.cpp $(call rwildcard,$(gameboy)/apu/)
|
||||
obj/gameboy-lcd.o: $(gameboy)/lcd/lcd.cpp $(call rwildcard,$(gameboy)/lcd/)
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#include <gameboy/gameboy.hpp>
|
||||
|
||||
#define APU_CPP
|
||||
namespace GameBoy {
|
||||
|
||||
#include "square1/square1.cpp"
|
||||
#include "square2/square2.cpp"
|
||||
#include "wave/wave.cpp"
|
||||
#include "noise/noise.cpp"
|
||||
#include "master/master.cpp"
|
||||
#include "serialization.cpp"
|
||||
APU apu;
|
||||
|
||||
void APU::Main() {
|
||||
apu.main();
|
||||
}
|
||||
|
||||
void APU::main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(sequencer_base == 0) { //512hz
|
||||
if(sequencer_step == 0 || sequencer_step == 2 || sequencer_step == 4 || sequencer_step == 6) { //256hz
|
||||
square1.clock_length();
|
||||
square2.clock_length();
|
||||
wave.clock_length();
|
||||
noise.clock_length();
|
||||
}
|
||||
if(sequencer_step == 2 || sequencer_step == 6) { //128hz
|
||||
square1.clock_sweep();
|
||||
}
|
||||
if(sequencer_step == 7) { //64hz
|
||||
square1.clock_envelope();
|
||||
square2.clock_envelope();
|
||||
noise.clock_envelope();
|
||||
}
|
||||
sequencer_step++;
|
||||
}
|
||||
sequencer_base++;
|
||||
|
||||
square1.run();
|
||||
square2.run();
|
||||
wave.run();
|
||||
noise.run();
|
||||
master.run();
|
||||
|
||||
system.interface->audio_sample(master.center, master.left, master.right);
|
||||
if(++clock >= 0) co_switch(scheduler.active_thread = cpu.thread);
|
||||
}
|
||||
}
|
||||
|
||||
void APU::power() {
|
||||
create(Main, 4194304);
|
||||
for(unsigned n = 0xff10; n <= 0xff3f; n++) bus.mmio[n] = this;
|
||||
|
||||
foreach(n, mmio_data) n = 0x00;
|
||||
sequencer_base = 0;
|
||||
sequencer_step = 0;
|
||||
|
||||
square1.power();
|
||||
square2.power();
|
||||
wave.power();
|
||||
noise.power();
|
||||
master.power();
|
||||
}
|
||||
|
||||
uint8 APU::mmio_read(uint16 addr) {
|
||||
static const uint8 table[48] = {
|
||||
0x80, 0x3f, 0x00, 0xff, 0xbf, //square1
|
||||
0xff, 0x3f, 0x00, 0xff, 0xbf, //square2
|
||||
0x7f, 0xff, 0x9f, 0xff, 0xbf, //wave
|
||||
0xff, 0xff, 0x00, 0x00, 0xbf, //noise
|
||||
0x00, 0x00, 0x70, //master
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //unmapped
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //wave pattern
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //wave pattern
|
||||
};
|
||||
|
||||
if(addr == 0xff26) {
|
||||
uint8 data = master.enable << 7;
|
||||
if(square1.counter && square1.length) data |= 0x01;
|
||||
if(square2.counter && square2.length) data |= 0x02;
|
||||
if( wave.counter && wave.length) data |= 0x04;
|
||||
if( noise.counter && noise.length) data |= 0x08;
|
||||
return data | table[addr - 0xff10];
|
||||
}
|
||||
|
||||
if(addr >= 0xff10 && addr <= 0xff3f) return mmio_data[addr - 0xff10] | table[addr - 0xff10];
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void APU::mmio_write(uint16 addr, uint8 data) {
|
||||
if(addr >= 0xff10 && addr <= 0xff3f) mmio_data[addr - 0xff10] = data;
|
||||
|
||||
if(addr >= 0xff10 && addr <= 0xff14) return square1.write (addr - 0xff10, data);
|
||||
if(addr >= 0xff15 && addr <= 0xff19) return square2.write (addr - 0xff15, data);
|
||||
if(addr >= 0xff1a && addr <= 0xff1e) return wave.write (addr - 0xff1a, data);
|
||||
if(addr >= 0xff1f && addr <= 0xff23) return noise.write (addr - 0xff1f, data);
|
||||
if(addr >= 0xff24 && addr <= 0xff26) return master.write (addr - 0xff24, data);
|
||||
if(addr >= 0xff30 && addr <= 0xff3f) return wave.write_pattern(addr - 0xff30, data);
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
struct APU : Processor, MMIO {
|
||||
#include "square1/square1.hpp"
|
||||
#include "square2/square2.hpp"
|
||||
#include "wave/wave.hpp"
|
||||
#include "noise/noise.hpp"
|
||||
#include "master/master.hpp"
|
||||
|
||||
uint8 mmio_data[48];
|
||||
uint13 sequencer_base;
|
||||
uint3 sequencer_step;
|
||||
|
||||
Square1 square1;
|
||||
Square2 square2;
|
||||
Wave wave;
|
||||
Noise noise;
|
||||
Master master;
|
||||
|
||||
static void Main();
|
||||
void main();
|
||||
void power();
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
void serialize(serializer&);
|
||||
};
|
||||
|
||||
extern APU apu;
|
||||
Executable
+132
@@ -0,0 +1,132 @@
|
||||
#ifdef APU_CPP
|
||||
|
||||
void APU::Master::run() {
|
||||
if(enable == false) {
|
||||
center = 0;
|
||||
left = 0;
|
||||
right = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
signed sample = 0, channels;
|
||||
sample += apu.square1.output;
|
||||
sample += apu.square2.output;
|
||||
sample += apu.wave.output;
|
||||
sample += apu.noise.output;
|
||||
sample >>= 2;
|
||||
center = sclamp<16>(sample);
|
||||
|
||||
if(left_enable == false && right_enable == false) {
|
||||
left = center;
|
||||
right = center;
|
||||
return;
|
||||
}
|
||||
|
||||
sample = 0;
|
||||
channels = 0;
|
||||
if(channel1_left_enable) { sample += apu.square1.output; channels++; }
|
||||
if(channel2_left_enable) { sample += apu.square2.output; channels++; }
|
||||
if(channel3_left_enable) { sample += apu.wave.output; channels++; }
|
||||
if(channel4_left_enable) { sample += apu.noise.output; channels++; }
|
||||
if(channels) sample /= channels;
|
||||
left = sclamp<16>(sample);
|
||||
|
||||
switch(left_volume) {
|
||||
case 0: left >>= 3; break; // 12.5%
|
||||
case 1: left >>= 2; break; // 25.0%
|
||||
case 2: left = (left >> 2) + (left >> 3); break; // 37.5%
|
||||
case 3: left >>= 1; break; // 50.0%
|
||||
case 4: left = (left >> 1) + (left >> 3); break; // 62.5%
|
||||
case 5: left -= (left >> 2); break; // 75.0%
|
||||
case 6: left -= (left >> 3); break; // 87.5%
|
||||
//case 7: break; //100.0%
|
||||
}
|
||||
if(left_enable == false) left = 0;
|
||||
|
||||
sample = 0;
|
||||
channels = 0;
|
||||
if(channel1_right_enable) { sample += apu.square1.output; channels++; }
|
||||
if(channel2_right_enable) { sample += apu.square2.output; channels++; }
|
||||
if(channel3_right_enable) { sample += apu.wave.output; channels++; }
|
||||
if(channel4_right_enable) { sample += apu.noise.output; channels++; }
|
||||
if(channels) sample /= channels;
|
||||
right = sclamp<16>(sample);
|
||||
|
||||
switch(right_volume) {
|
||||
case 0: right >>= 3; break; // 12.5%
|
||||
case 1: right >>= 2; break; // 25.0%
|
||||
case 2: right = (right >> 2) + (right >> 3); break; // 37.5%
|
||||
case 3: right >>= 1; break; // 50.0%
|
||||
case 4: right = (right >> 1) + (right >> 3); break; // 62.5%
|
||||
case 5: right -= (right >> 2); break; // 75.0%
|
||||
case 6: right -= (right >> 3); break; // 87.5%
|
||||
//case 7: break; //100.0%
|
||||
}
|
||||
if(right_enable == false) right = 0;
|
||||
}
|
||||
|
||||
void APU::Master::write(unsigned r, uint8 data) {
|
||||
if(r == 0) {
|
||||
left_enable = data & 0x80;
|
||||
left_volume = (data >> 4) & 7;
|
||||
right_enable = data & 0x08;
|
||||
right_volume = (data >> 0) & 7;
|
||||
}
|
||||
|
||||
if(r == 1) {
|
||||
channel4_left_enable = data & 0x80;
|
||||
channel3_left_enable = data & 0x40;
|
||||
channel2_left_enable = data & 0x20;
|
||||
channel1_left_enable = data & 0x10;
|
||||
channel4_right_enable = data & 0x08;
|
||||
channel3_right_enable = data & 0x04;
|
||||
channel2_right_enable = data & 0x02;
|
||||
channel1_right_enable = data & 0x01;
|
||||
}
|
||||
|
||||
if(r == 2) {
|
||||
enable = data & 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Master::power() {
|
||||
left_enable = 0;
|
||||
left_volume = 0;
|
||||
right_enable = 0;
|
||||
right_volume = 0;
|
||||
channel4_left_enable = 0;
|
||||
channel3_left_enable = 0;
|
||||
channel2_left_enable = 0;
|
||||
channel1_left_enable = 0;
|
||||
channel4_right_enable = 0;
|
||||
channel3_right_enable = 0;
|
||||
channel2_right_enable = 0;
|
||||
channel1_right_enable = 0;
|
||||
enable = 0;
|
||||
|
||||
center = 0;
|
||||
left = 0;
|
||||
right = 0;
|
||||
}
|
||||
|
||||
void APU::Master::serialize(serializer &s) {
|
||||
s.integer(left_enable);
|
||||
s.integer(left_volume);
|
||||
s.integer(right_enable);
|
||||
s.integer(right_volume);
|
||||
s.integer(channel4_left_enable);
|
||||
s.integer(channel3_left_enable);
|
||||
s.integer(channel2_left_enable);
|
||||
s.integer(channel1_left_enable);
|
||||
s.integer(channel4_right_enable);
|
||||
s.integer(channel3_right_enable);
|
||||
s.integer(channel2_right_enable);
|
||||
s.integer(channel1_right_enable);
|
||||
s.integer(enable);
|
||||
|
||||
s.integer(center);
|
||||
s.integer(left);
|
||||
s.integer(right);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
struct Master {
|
||||
bool left_enable;
|
||||
unsigned left_volume;
|
||||
bool right_enable;
|
||||
unsigned right_volume;
|
||||
bool channel4_left_enable;
|
||||
bool channel3_left_enable;
|
||||
bool channel2_left_enable;
|
||||
bool channel1_left_enable;
|
||||
bool channel4_right_enable;
|
||||
bool channel3_right_enable;
|
||||
bool channel2_right_enable;
|
||||
bool channel1_right_enable;
|
||||
bool enable;
|
||||
|
||||
int16 center;
|
||||
int16 left;
|
||||
int16 right;
|
||||
|
||||
void run();
|
||||
void write(unsigned r, uint8 data);
|
||||
void power();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
#ifdef APU_CPP
|
||||
|
||||
void APU::Noise::run() {
|
||||
if(period && --period == 0) {
|
||||
period = divisor << frequency;
|
||||
if(frequency < 14) {
|
||||
bool bit = (lfsr ^ (lfsr >> 1)) & 1;
|
||||
lfsr = (lfsr >> 1) ^ (bit << 14);
|
||||
if(narrow_lfsr) lfsr |= (bit << 6);
|
||||
}
|
||||
}
|
||||
|
||||
uint4 sample = (lfsr & 1) ? 0 : volume;
|
||||
if(counter && length == 0) sample = 0;
|
||||
|
||||
output = (sample * 4369) - 32768;
|
||||
}
|
||||
|
||||
void APU::Noise::clock_length() {
|
||||
if(counter && length) length--;
|
||||
}
|
||||
|
||||
void APU::Noise::clock_envelope() {
|
||||
if(envelope_period && --envelope_period == 0) {
|
||||
envelope_period = envelope_frequency;
|
||||
if(envelope_direction == 0 && volume > 0) volume--;
|
||||
if(envelope_direction == 1 && volume < 15) volume++;
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Noise::write(unsigned r, uint8 data) {
|
||||
if(r == 1) {
|
||||
initial_length = 64 - (data & 0x3f);
|
||||
|
||||
length = initial_length;
|
||||
}
|
||||
|
||||
if(r == 2) {
|
||||
envelope_volume = data >> 4;
|
||||
envelope_direction = data & 0x08;
|
||||
envelope_frequency = data & 0x07;
|
||||
}
|
||||
|
||||
if(r == 3) {
|
||||
frequency = data >> 4;
|
||||
narrow_lfsr = data & 0x08;
|
||||
divisor = (data & 0x07) << 4;
|
||||
if(divisor == 0) divisor = 8;
|
||||
|
||||
period = divisor << frequency;
|
||||
}
|
||||
|
||||
if(r == 4) {
|
||||
bool initialize = data & 0x80;
|
||||
counter = data & 0x40;
|
||||
|
||||
if(initialize) {
|
||||
lfsr = ~0U;
|
||||
length = initial_length;
|
||||
envelope_period = envelope_frequency;
|
||||
volume = envelope_volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Noise::power() {
|
||||
initial_length = 0;
|
||||
envelope_volume = 0;
|
||||
envelope_direction = 0;
|
||||
envelope_frequency = 0;
|
||||
frequency = 0;
|
||||
narrow_lfsr = 0;
|
||||
divisor = 0;
|
||||
counter = 0;
|
||||
|
||||
output = 0;
|
||||
length = 0;
|
||||
envelope_period = 0;
|
||||
volume = 0;
|
||||
period = 0;
|
||||
lfsr = 0;
|
||||
}
|
||||
|
||||
void APU::Noise::serialize(serializer &s) {
|
||||
s.integer(initial_length);
|
||||
s.integer(envelope_volume);
|
||||
s.integer(envelope_direction);
|
||||
s.integer(envelope_frequency);
|
||||
s.integer(frequency);
|
||||
s.integer(narrow_lfsr);
|
||||
s.integer(divisor);
|
||||
s.integer(counter);
|
||||
|
||||
s.integer(output);
|
||||
s.integer(length);
|
||||
s.integer(envelope_period);
|
||||
s.integer(volume);
|
||||
s.integer(period);
|
||||
s.integer(lfsr);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
struct Noise {
|
||||
unsigned initial_length;
|
||||
unsigned envelope_volume;
|
||||
bool envelope_direction;
|
||||
unsigned envelope_frequency;
|
||||
unsigned frequency;
|
||||
bool narrow_lfsr;
|
||||
unsigned divisor;
|
||||
bool counter;
|
||||
|
||||
int16 output;
|
||||
unsigned length;
|
||||
unsigned envelope_period;
|
||||
unsigned volume;
|
||||
unsigned period;
|
||||
uint15 lfsr;
|
||||
|
||||
void run();
|
||||
void clock_length();
|
||||
void clock_envelope();
|
||||
void write(unsigned r, uint8 data);
|
||||
void power();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#ifdef APU_CPP
|
||||
|
||||
void APU::serialize(serializer &s) {
|
||||
s.array(mmio_data);
|
||||
s.integer(sequencer_base);
|
||||
s.integer(sequencer_step);
|
||||
|
||||
square1.serialize(s);
|
||||
square2.serialize(s);
|
||||
wave.serialize(s);
|
||||
noise.serialize(s);
|
||||
master.serialize(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+146
@@ -0,0 +1,146 @@
|
||||
#ifdef APU_CPP
|
||||
|
||||
void APU::Square1::run() {
|
||||
if(period && --period == 0) {
|
||||
period = 4 * (2048 - frequency);
|
||||
phase = (phase + 1) & 7;
|
||||
switch(duty) {
|
||||
case 0: duty_output = (phase == 6); break; //______-_
|
||||
case 1: duty_output = (phase >= 6); break; //______--
|
||||
case 2: duty_output = (phase >= 4); break; //____----
|
||||
case 3: duty_output = (phase <= 5); break; //------__
|
||||
}
|
||||
}
|
||||
|
||||
uint4 sample = (duty_output ? volume : 0);
|
||||
if(counter && length == 0) sample = 0;
|
||||
|
||||
output = (sample * 4369) - 32768;
|
||||
}
|
||||
|
||||
void APU::Square1::sweep() {
|
||||
if(enable == false) return;
|
||||
|
||||
signed offset = frequency_shadow >> sweep_shift;
|
||||
if(sweep_direction) offset = -offset;
|
||||
frequency_shadow += offset;
|
||||
|
||||
if(frequency_shadow < 0) {
|
||||
frequency_shadow = 0;
|
||||
} else if(frequency_shadow > 2047) {
|
||||
frequency_shadow = 2048;
|
||||
enable = false;
|
||||
}
|
||||
|
||||
if(frequency_shadow <= 2047 && sweep_shift) {
|
||||
frequency = frequency_shadow;
|
||||
period = 4 * (2048 - frequency);
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Square1::clock_length() {
|
||||
if(counter && length) length--;
|
||||
}
|
||||
|
||||
void APU::Square1::clock_sweep() {
|
||||
if(sweep_frequency && sweep_period && --sweep_period == 0) {
|
||||
sweep_period = sweep_frequency;
|
||||
sweep();
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Square1::clock_envelope() {
|
||||
if(envelope_period && --envelope_period == 0) {
|
||||
envelope_period = envelope_frequency;
|
||||
if(envelope_direction == 0 && volume > 0) volume--;
|
||||
if(envelope_direction == 1 && volume < 15) volume++;
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Square1::write(unsigned r, uint8 data) {
|
||||
if(r == 0) {
|
||||
sweep_frequency = (data >> 4) & 7;
|
||||
sweep_direction = data & 0x08;
|
||||
sweep_shift = data & 0x07;
|
||||
}
|
||||
|
||||
if(r == 1) {
|
||||
duty = data >> 6;
|
||||
length = data & 0x3f;
|
||||
}
|
||||
|
||||
if(r == 2) {
|
||||
envelope_volume = data >> 4;
|
||||
envelope_direction = data & 0x08;
|
||||
envelope_frequency = data & 0x07;
|
||||
}
|
||||
|
||||
if(r == 3) {
|
||||
frequency = (frequency & 0x0700) | data;
|
||||
}
|
||||
|
||||
if(r == 4) {
|
||||
bool initialize = data & 0x80;
|
||||
counter = data & 0x40;
|
||||
frequency = ((data & 7) << 8) | (frequency & 0x00ff);
|
||||
|
||||
if(initialize) {
|
||||
envelope_period = envelope_frequency;
|
||||
volume = envelope_volume;
|
||||
frequency_shadow = frequency;
|
||||
sweep_period = sweep_frequency;
|
||||
enable = sweep_period || sweep_shift;
|
||||
if(sweep_shift) sweep();
|
||||
}
|
||||
}
|
||||
|
||||
period = 4 * (2048 - frequency);
|
||||
}
|
||||
|
||||
void APU::Square1::power() {
|
||||
sweep_frequency = 0;
|
||||
sweep_direction = 0;
|
||||
sweep_shift = 0;
|
||||
duty = 0;
|
||||
length = 0;
|
||||
envelope_volume = 0;
|
||||
envelope_direction = 0;
|
||||
envelope_frequency = 0;
|
||||
frequency = 0;
|
||||
counter = 0;
|
||||
|
||||
output = 0;
|
||||
duty_output = 0;
|
||||
phase = 0;
|
||||
period = 0;
|
||||
envelope_period = 0;
|
||||
sweep_period = 0;
|
||||
frequency_shadow = 0;
|
||||
enable = 0;
|
||||
volume = 0;
|
||||
}
|
||||
|
||||
void APU::Square1::serialize(serializer &s) {
|
||||
s.integer(sweep_frequency);
|
||||
s.integer(sweep_direction);
|
||||
s.integer(sweep_shift);
|
||||
s.integer(duty);
|
||||
s.integer(length);
|
||||
s.integer(envelope_volume);
|
||||
s.integer(envelope_direction);
|
||||
s.integer(envelope_frequency);
|
||||
s.integer(frequency);
|
||||
s.integer(counter);
|
||||
|
||||
s.integer(output);
|
||||
s.integer(duty_output);
|
||||
s.integer(phase);
|
||||
s.integer(period);
|
||||
s.integer(envelope_period);
|
||||
s.integer(sweep_period);
|
||||
s.integer(frequency_shadow);
|
||||
s.integer(enable);
|
||||
s.integer(volume);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
struct Square1 {
|
||||
unsigned sweep_frequency;
|
||||
unsigned sweep_direction;
|
||||
unsigned sweep_shift;
|
||||
unsigned duty;
|
||||
unsigned length;
|
||||
unsigned envelope_volume;
|
||||
unsigned envelope_direction;
|
||||
unsigned envelope_frequency;
|
||||
unsigned frequency;
|
||||
unsigned counter;
|
||||
|
||||
int16 output;
|
||||
bool duty_output;
|
||||
unsigned phase;
|
||||
unsigned period;
|
||||
unsigned envelope_period;
|
||||
unsigned sweep_period;
|
||||
signed frequency_shadow;
|
||||
bool enable;
|
||||
unsigned volume;
|
||||
|
||||
void run();
|
||||
void sweep();
|
||||
void clock_length();
|
||||
void clock_sweep();
|
||||
void clock_envelope();
|
||||
void write(unsigned r, uint8 data);
|
||||
void power();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#ifdef APU_CPP
|
||||
|
||||
void APU::Square2::run() {
|
||||
if(period && --period == 0) {
|
||||
period = 4 * (2048 - frequency);
|
||||
phase = (phase + 1) & 7;
|
||||
switch(duty) {
|
||||
case 0: duty_output = (phase == 6); break; //______-_
|
||||
case 1: duty_output = (phase >= 6); break; //______--
|
||||
case 2: duty_output = (phase >= 4); break; //____----
|
||||
case 3: duty_output = (phase <= 5); break; //------__
|
||||
}
|
||||
}
|
||||
|
||||
uint4 sample = (duty_output ? volume : 0);
|
||||
if(counter && length == 0) sample = 0;
|
||||
|
||||
output = (sample * 4369) - 32768;
|
||||
}
|
||||
|
||||
void APU::Square2::clock_length() {
|
||||
if(counter && length) length--;
|
||||
}
|
||||
|
||||
void APU::Square2::clock_envelope() {
|
||||
if(envelope_period && --envelope_period == 0) {
|
||||
envelope_period = envelope_frequency;
|
||||
if(envelope_direction == 0 && volume > 0) volume--;
|
||||
if(envelope_direction == 1 && volume < 15) volume++;
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Square2::write(unsigned r, uint8 data) {
|
||||
if(r == 1) {
|
||||
duty = data >> 6;
|
||||
length = data & 0x3f;
|
||||
}
|
||||
|
||||
if(r == 2) {
|
||||
envelope_volume = data >> 4;
|
||||
envelope_direction = data & 0x08;
|
||||
envelope_frequency = data & 0x07;
|
||||
}
|
||||
|
||||
if(r == 3) {
|
||||
frequency = (frequency & 0x0700) | data;
|
||||
}
|
||||
|
||||
if(r == 4) {
|
||||
bool initialize = data & 0x80;
|
||||
counter = data & 0x40;
|
||||
frequency = ((data & 7) << 8) | (frequency & 0x00ff);
|
||||
|
||||
if(initialize) {
|
||||
envelope_period = envelope_frequency;
|
||||
volume = envelope_volume;
|
||||
}
|
||||
}
|
||||
|
||||
period = 4 * (2048 - frequency);
|
||||
}
|
||||
|
||||
void APU::Square2::power() {
|
||||
duty = 0;
|
||||
length = 0;
|
||||
envelope_volume = 0;
|
||||
envelope_direction = 0;
|
||||
envelope_frequency = 0;
|
||||
frequency = 0;
|
||||
counter = 0;
|
||||
|
||||
output = 0;
|
||||
duty_output = 0;
|
||||
phase = 0;
|
||||
period = 0;
|
||||
envelope_period = 0;
|
||||
volume = 0;
|
||||
}
|
||||
|
||||
void APU::Square2::serialize(serializer &s) {
|
||||
s.integer(duty);
|
||||
s.integer(length);
|
||||
s.integer(envelope_volume);
|
||||
s.integer(envelope_direction);
|
||||
s.integer(envelope_frequency);
|
||||
s.integer(frequency);
|
||||
s.integer(counter);
|
||||
|
||||
s.integer(output);
|
||||
s.integer(duty_output);
|
||||
s.integer(phase);
|
||||
s.integer(period);
|
||||
s.integer(envelope_period);
|
||||
s.integer(volume);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
struct Square2 {
|
||||
unsigned duty;
|
||||
unsigned length;
|
||||
unsigned envelope_volume;
|
||||
unsigned envelope_direction;
|
||||
unsigned envelope_frequency;
|
||||
unsigned frequency;
|
||||
unsigned counter;
|
||||
|
||||
int16 output;
|
||||
bool duty_output;
|
||||
unsigned phase;
|
||||
unsigned period;
|
||||
unsigned envelope_period;
|
||||
unsigned volume;
|
||||
|
||||
void run();
|
||||
void clock_length();
|
||||
void clock_envelope();
|
||||
void write(unsigned r, uint8 data);
|
||||
void power();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
Executable
+103
@@ -0,0 +1,103 @@
|
||||
#ifdef APU_CPP
|
||||
|
||||
void APU::Wave::run() {
|
||||
if(period && --period == 0) {
|
||||
period = 2 * (2048 - frequency);
|
||||
pattern_offset = (pattern_offset + 1) & 31;
|
||||
pattern_sample = pattern[pattern_offset];
|
||||
}
|
||||
|
||||
uint4 sample = pattern_sample;
|
||||
if(counter && length == 0) sample = 0;
|
||||
if(enable == false) sample = 0;
|
||||
|
||||
output = (sample * 4369) - 32768;
|
||||
output >>= volume;
|
||||
}
|
||||
|
||||
void APU::Wave::clock_length() {
|
||||
if(counter && length) length--;
|
||||
}
|
||||
|
||||
void APU::Wave::write(unsigned r, uint8 data) {
|
||||
if(r == 0) {
|
||||
dac_enable = data & 0x80;
|
||||
|
||||
if(dac_enable == false) enable = false;
|
||||
}
|
||||
|
||||
if(r == 1) {
|
||||
initial_length = 256 - data;
|
||||
|
||||
length = initial_length;
|
||||
}
|
||||
|
||||
if(r == 2) {
|
||||
switch((data >> 5) & 3) {
|
||||
case 0: volume = 16; break; // 0%
|
||||
case 1: volume = 0; break; //100%
|
||||
case 2: volume = 1; break; // 50%
|
||||
case 3: volume = 2; break; // 25%
|
||||
}
|
||||
}
|
||||
|
||||
if(r == 3) {
|
||||
frequency = (frequency & 0x0700) | data;
|
||||
}
|
||||
|
||||
if(r == 4) {
|
||||
bool initialize = data & 0x80;
|
||||
counter = data & 0x40;
|
||||
frequency = ((data & 7) << 8) | (frequency & 0x00ff);
|
||||
|
||||
if(initialize && dac_enable) {
|
||||
enable = true;
|
||||
pattern_offset = 0;
|
||||
length = initial_length;
|
||||
}
|
||||
}
|
||||
|
||||
period = 2 * (2048 - frequency);
|
||||
}
|
||||
|
||||
void APU::Wave::write_pattern(unsigned p, uint8 data) {
|
||||
p <<= 1;
|
||||
pattern[p + 0] = (data >> 4) & 15;
|
||||
pattern[p + 1] = (data >> 0) & 15;
|
||||
}
|
||||
|
||||
void APU::Wave::power() {
|
||||
dac_enable = 0;
|
||||
initial_length = 0;
|
||||
volume = 0;
|
||||
frequency = 0;
|
||||
counter = 0;
|
||||
|
||||
random_lfsr r;
|
||||
foreach(n, pattern) n = r() & 15;
|
||||
|
||||
output = 0;
|
||||
enable = 0;
|
||||
length = 0;
|
||||
period = 0;
|
||||
pattern_offset = 0;
|
||||
pattern_sample = 0;
|
||||
}
|
||||
|
||||
void APU::Wave::serialize(serializer &s) {
|
||||
s.integer(dac_enable);
|
||||
s.integer(initial_length);
|
||||
s.integer(volume);
|
||||
s.integer(frequency);
|
||||
s.integer(counter);
|
||||
s.array(pattern);
|
||||
|
||||
s.integer(output);
|
||||
s.integer(enable);
|
||||
s.integer(length);
|
||||
s.integer(period);
|
||||
s.integer(pattern_offset);
|
||||
s.integer(pattern_sample);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
struct Wave {
|
||||
bool dac_enable;
|
||||
unsigned initial_length;
|
||||
unsigned volume;
|
||||
unsigned frequency;
|
||||
bool counter;
|
||||
uint8 pattern[32];
|
||||
|
||||
int16 output;
|
||||
bool enable;
|
||||
unsigned length;
|
||||
unsigned period;
|
||||
unsigned pattern_offset;
|
||||
unsigned pattern_sample;
|
||||
|
||||
void run();
|
||||
void clock_length();
|
||||
void write(unsigned r, uint8 data);
|
||||
void write_pattern(unsigned p, uint8 data);
|
||||
void power();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
Executable
+156
@@ -0,0 +1,156 @@
|
||||
#include <gameboy/gameboy.hpp>
|
||||
|
||||
#include <nall/crc32.hpp>
|
||||
|
||||
#define CARTRIDGE_CPP
|
||||
namespace GameBoy {
|
||||
|
||||
#include "mbc0/mbc0.cpp"
|
||||
#include "mbc1/mbc1.cpp"
|
||||
#include "mbc2/mbc2.cpp"
|
||||
#include "mbc3/mbc3.cpp"
|
||||
#include "mbc5/mbc5.cpp"
|
||||
#include "mmm01/mmm01.cpp"
|
||||
#include "huc1/huc1.cpp"
|
||||
#include "huc3/huc3.cpp"
|
||||
#include "serialization.cpp"
|
||||
Cartridge cartridge;
|
||||
|
||||
void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) {
|
||||
if(size == 0) size = 32768;
|
||||
romdata = allocate<uint8>(romsize = size, 0xff);
|
||||
if(data) memcpy(romdata, data, size);
|
||||
|
||||
//uint32_t crc = crc32_calculate(data, size);
|
||||
//print("CRC32 = ", hex<4>(crc), "\n");
|
||||
|
||||
info.mapper = Mapper::Unknown;
|
||||
info.ram = false;
|
||||
info.battery = false;
|
||||
info.rtc = false;
|
||||
info.rumble = false;
|
||||
|
||||
info.romsize = 0;
|
||||
info.ramsize = 0;
|
||||
|
||||
xml_element document = xml_parse(xml);
|
||||
foreach(head, document.element) {
|
||||
if(head.name == "cartridge") {
|
||||
foreach(attr, head.attribute) {
|
||||
if(attr.name == "mapper") {
|
||||
if(attr.content == "none") info.mapper = Mapper::MBC0;
|
||||
if(attr.content == "MBC1") info.mapper = Mapper::MBC1;
|
||||
if(attr.content == "MBC2") info.mapper = Mapper::MBC2;
|
||||
if(attr.content == "MBC3") info.mapper = Mapper::MBC3;
|
||||
if(attr.content == "MBC5") info.mapper = Mapper::MBC5;
|
||||
if(attr.content == "MMM01") info.mapper = Mapper::MMM01;
|
||||
if(attr.content == "HuC1") info.mapper = Mapper::HuC1;
|
||||
if(attr.content == "HuC3") info.mapper = Mapper::HuC3;
|
||||
}
|
||||
|
||||
if(attr.name == "rtc") info.rtc = (attr.content == "true" ? true : false);
|
||||
if(attr.name == "rumble") info.rumble = (attr.content == "true" ? true : false);
|
||||
}
|
||||
|
||||
foreach(elem, head.element) {
|
||||
if(elem.name == "rom") {
|
||||
foreach(attr, elem.attribute) {
|
||||
if(attr.name == "size") info.romsize = hex(attr.content);
|
||||
}
|
||||
}
|
||||
|
||||
if(elem.name == "ram") {
|
||||
info.ram = true;
|
||||
foreach(attr, elem.attribute) {
|
||||
if(attr.name == "size") info.ramsize = hex(attr.content);
|
||||
if(attr.name == "battery") info.battery = (attr.content == "true" ? true : false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(info.mapper) { default:
|
||||
case Mapper::MBC0: mapper = &mbc0; break;
|
||||
case Mapper::MBC1: mapper = &mbc1; break;
|
||||
case Mapper::MBC2: mapper = &mbc2; break;
|
||||
case Mapper::MBC3: mapper = &mbc3; break;
|
||||
case Mapper::MBC5: mapper = &mbc5; break;
|
||||
case Mapper::MMM01: mapper = &mmm01; break;
|
||||
case Mapper::HuC1: mapper = &huc1; break;
|
||||
case Mapper::HuC3: mapper = &huc3; break;
|
||||
}
|
||||
|
||||
ramdata = new uint8_t[ramsize = info.ramsize]();
|
||||
system.load();
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
void Cartridge::unload() {
|
||||
if(loaded == false) return;
|
||||
|
||||
if(romdata) { delete[] romdata; romdata = 0; }
|
||||
if(ramdata) { delete[] ramdata; ramdata = 0; }
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
uint8 Cartridge::rom_read(unsigned addr) {
|
||||
if(addr >= romsize) addr %= romsize;
|
||||
return romdata[addr];
|
||||
}
|
||||
|
||||
void Cartridge::rom_write(unsigned addr, uint8 data) {
|
||||
if(addr >= romsize) addr %= romsize;
|
||||
romdata[addr] = data;
|
||||
}
|
||||
|
||||
uint8 Cartridge::ram_read(unsigned addr) {
|
||||
if(ramsize == 0) return 0x00;
|
||||
if(addr >= ramsize) addr %= ramsize;
|
||||
return ramdata[addr];
|
||||
}
|
||||
|
||||
void Cartridge::ram_write(unsigned addr, uint8 data) {
|
||||
if(ramsize == 0) return;
|
||||
if(addr >= ramsize) addr %= ramsize;
|
||||
ramdata[addr] = data;
|
||||
}
|
||||
|
||||
uint8 Cartridge::mmio_read(uint16 addr) {
|
||||
if(bootrom_enable && within<0x0000, 0x00ff>(addr)) return System::BootROM::sgb[addr];
|
||||
return mapper->mmio_read(addr);
|
||||
}
|
||||
|
||||
void Cartridge::mmio_write(uint16 addr, uint8 data) {
|
||||
if(bootrom_enable && addr == 0xff50) bootrom_enable = false;
|
||||
mapper->mmio_write(addr, data);
|
||||
}
|
||||
|
||||
void Cartridge::power() {
|
||||
bootrom_enable = true;
|
||||
|
||||
mbc0.power();
|
||||
mbc1.power();
|
||||
mbc2.power();
|
||||
mbc3.power();
|
||||
mbc5.power();
|
||||
mmm01.power();
|
||||
huc1.power();
|
||||
huc3.power();
|
||||
|
||||
for(unsigned n = 0x0000; n <= 0x7fff; n++) bus.mmio[n] = this;
|
||||
for(unsigned n = 0xa000; n <= 0xbfff; n++) bus.mmio[n] = this;
|
||||
bus.mmio[0xff50] = this;
|
||||
}
|
||||
|
||||
Cartridge::Cartridge() {
|
||||
loaded = false;
|
||||
romdata = 0;
|
||||
ramdata = 0;
|
||||
}
|
||||
|
||||
Cartridge::~Cartridge() {
|
||||
unload();
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
struct Cartridge : MMIO, property<Cartridge> {
|
||||
#include "mbc0/mbc0.hpp"
|
||||
#include "mbc1/mbc1.hpp"
|
||||
#include "mbc2/mbc2.hpp"
|
||||
#include "mbc3/mbc3.hpp"
|
||||
#include "mbc5/mbc5.hpp"
|
||||
#include "mmm01/mmm01.hpp"
|
||||
#include "huc1/huc1.hpp"
|
||||
#include "huc3/huc3.hpp"
|
||||
|
||||
enum Mapper : unsigned {
|
||||
MBC0,
|
||||
MBC1,
|
||||
MBC2,
|
||||
MBC3,
|
||||
MBC5,
|
||||
MMM01,
|
||||
HuC1,
|
||||
HuC3,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
struct Information {
|
||||
string xml;
|
||||
|
||||
Mapper mapper;
|
||||
bool ram;
|
||||
bool battery;
|
||||
bool rtc;
|
||||
bool rumble;
|
||||
|
||||
unsigned romsize;
|
||||
unsigned ramsize;
|
||||
} info;
|
||||
|
||||
readonly<bool> loaded;
|
||||
|
||||
uint8_t *romdata;
|
||||
unsigned romsize;
|
||||
|
||||
uint8_t *ramdata;
|
||||
unsigned ramsize;
|
||||
|
||||
MMIO *mapper;
|
||||
bool bootrom_enable;
|
||||
|
||||
void load(const string &xml, const uint8_t *data, unsigned size);
|
||||
void unload();
|
||||
|
||||
uint8 rom_read(unsigned addr);
|
||||
void rom_write(unsigned addr, uint8 data);
|
||||
uint8 ram_read(unsigned addr);
|
||||
void ram_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
void power();
|
||||
|
||||
void serialize(serializer&);
|
||||
Cartridge();
|
||||
~Cartridge();
|
||||
};
|
||||
|
||||
extern Cartridge cartridge;
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
uint8 Cartridge::HuC1::mmio_read(uint16 addr) {
|
||||
if(within<0x0000, 0x3fff>(addr)) {
|
||||
return cartridge.rom_read(addr);
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x7fff>(addr)) {
|
||||
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void Cartridge::HuC1::mmio_write(uint16 addr, uint8 data) {
|
||||
if(within<0x0000, 0x1fff>(addr)) {
|
||||
ram_enable = (data & 0x0f) == 0x0a;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x2000, 0x3fff>(addr)) {
|
||||
rom_select = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x5fff>(addr)) {
|
||||
ram_select = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x6000, 0x7fff>(addr)) {
|
||||
//unknown purpose
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::HuC1::power() {
|
||||
ram_enable = false;
|
||||
rom_select = 0x01;
|
||||
ram_select = 0x00;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
struct HuC1 : MMIO {
|
||||
bool ram_enable; //0000-1fff
|
||||
uint8 rom_select; //2000-3fff
|
||||
uint8 ram_select; //4000-5fff
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
void power();
|
||||
} huc1;
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
uint8 Cartridge::HuC3::mmio_read(uint16 addr) {
|
||||
if(within<0x0000, 0x3fff>(addr)) {
|
||||
return cartridge.rom_read(addr);
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x7fff>(addr)) {
|
||||
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void Cartridge::HuC3::mmio_write(uint16 addr, uint8 data) {
|
||||
if(within<0x0000, 0x1fff>(addr)) {
|
||||
ram_enable = (data & 0x0f) == 0x0a;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x2000, 0x3fff>(addr)) {
|
||||
rom_select = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x5fff>(addr)) {
|
||||
ram_select = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x6000, 0x7fff>(addr)) {
|
||||
//unknown purpose
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::HuC3::power() {
|
||||
ram_enable = false;
|
||||
rom_select = 0x01;
|
||||
ram_select = 0x00;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
struct HuC3 : MMIO {
|
||||
bool ram_enable; //0000-1fff
|
||||
uint8 rom_select; //2000-3fff
|
||||
uint8 ram_select; //4000-5fff
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
void power();
|
||||
} huc3;
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
uint8 Cartridge::MBC0::mmio_read(uint16 addr) {
|
||||
if(within<0x0000, 0x7fff>(addr)) {
|
||||
return cartridge.rom_read(addr);
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
return cartridge.ram_read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void Cartridge::MBC0::mmio_write(uint16 addr, uint8 data) {
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
cartridge.ram_write(addr & 0x1fff, data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::MBC0::power() {
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
struct MBC0 : MMIO {
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
void power();
|
||||
} mbc0;
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
uint8 Cartridge::MBC1::mmio_read(uint16 addr) {
|
||||
if(within<0x0000, 0x3fff>(addr)) {
|
||||
return cartridge.rom_read(addr);
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x7fff>(addr)) {
|
||||
if(mode_select == 0) {
|
||||
return cartridge.rom_read((ram_select << 19) | (rom_select << 14) | (addr & 0x3fff));
|
||||
} else {
|
||||
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
|
||||
}
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) {
|
||||
if(mode_select == 0) {
|
||||
return cartridge.ram_read(addr & 0x1fff);
|
||||
} else {
|
||||
return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
|
||||
}
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void Cartridge::MBC1::mmio_write(uint16 addr, uint8 data) {
|
||||
if(within<0x0000, 0x1fff>(addr)) {
|
||||
ram_enable = (data & 0x0f) == 0x0a;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x2000, 0x3fff>(addr)) {
|
||||
rom_select = (data & 0x1f) + ((data & 0x1f) == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x5fff>(addr)) {
|
||||
ram_select = data & 0x03;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x6000, 0x7fff>(addr)) {
|
||||
mode_select = data & 0x01;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) {
|
||||
if(mode_select == 0) {
|
||||
cartridge.ram_write(addr & 0x1fff, data);
|
||||
} else {
|
||||
cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::MBC1::power() {
|
||||
ram_enable = false;
|
||||
rom_select = 0x01;
|
||||
ram_select = 0x00;
|
||||
mode_select = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
struct MBC1 : MMIO {
|
||||
bool ram_enable; //0000-1fff
|
||||
uint8 rom_select; //2000-3fff
|
||||
uint8 ram_select; //4000-5fff
|
||||
bool mode_select; //6000-7fff
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
void power();
|
||||
} mbc1;
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
uint8 Cartridge::MBC2::mmio_read(uint16 addr) {
|
||||
if(within<0x0000, 0x3fff>(addr)) {
|
||||
return cartridge.rom_read(addr);
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x7fff>(addr)) {
|
||||
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xa1ff>(addr)) {
|
||||
if(ram_enable) return cartridge.ram_read(addr & 0x1ff);
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void Cartridge::MBC2::mmio_write(uint16 addr, uint8 data) {
|
||||
if(within<0x0000, 0x1fff>(addr)) {
|
||||
if(!(addr & 0x0100)) ram_enable = (data & 0x0f) == 0x0a;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x2000, 0x3fff>(addr)) {
|
||||
if( (addr & 0x0100)) rom_select = (data & 0x0f) + ((data & 0x0f) == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xa1ff>(addr)) {
|
||||
if(ram_enable) cartridge.ram_write(addr & 0x1ff, data & 0x0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::MBC2::power() {
|
||||
ram_enable = false;
|
||||
rom_select = 0x01;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
struct MBC2 : MMIO {
|
||||
bool ram_enable; //0000-1fff
|
||||
uint8 rom_select; //2000-3fff
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
void power();
|
||||
} mbc2;
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
void Cartridge::MBC3::second() {
|
||||
if(rtc_halt == false) {
|
||||
if(++rtc_second >= 60) {
|
||||
rtc_second = 0;
|
||||
if(++rtc_minute >= 60) {
|
||||
rtc_minute = 0;
|
||||
if(++rtc_hour >= 24) {
|
||||
rtc_hour = 0;
|
||||
if(++rtc_day >= 512) {
|
||||
rtc_day = 0;
|
||||
rtc_day_carry = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 Cartridge::MBC3::mmio_read(uint16 addr) {
|
||||
if(within<0x0000, 0x3fff>(addr)) {
|
||||
return cartridge.rom_read(addr);
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x7fff>(addr)) {
|
||||
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) {
|
||||
if(ram_select >= 0x00 && ram_select <= 0x03) {
|
||||
return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
|
||||
}
|
||||
if(ram_select == 0x08) return rtc_latch_second;
|
||||
if(ram_select == 0x09) return rtc_latch_minute;
|
||||
if(ram_select == 0x0a) return rtc_latch_hour;
|
||||
if(ram_select == 0x0b) return rtc_latch_day;
|
||||
if(ram_select == 0x0c) return (rtc_latch_day_carry << 7) | (rtc_latch_day >> 8);
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void Cartridge::MBC3::mmio_write(uint16 addr, uint8 data) {
|
||||
if(within<0x0000, 0x1fff>(addr)) {
|
||||
ram_enable = (data & 0x0f) == 0x0a;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x2000, 0x3fff>(addr)) {
|
||||
rom_select = (data & 0x7f) + ((data & 0x7f) == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x5fff>(addr)) {
|
||||
ram_select = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x6000, 0x7fff>(addr)) {
|
||||
if(rtc_latch == 0 && data == 1) {
|
||||
rtc_latch_second = rtc_second;
|
||||
rtc_latch_minute = rtc_minute;
|
||||
rtc_latch_hour = rtc_hour;
|
||||
rtc_latch_day = rtc_day;
|
||||
rtc_latch_day_carry = rtc_day_carry;
|
||||
}
|
||||
rtc_latch = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) {
|
||||
if(ram_select >= 0x00 && ram_select <= 0x03) {
|
||||
cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
|
||||
} else if(ram_select == 0x08) {
|
||||
if(data >= 60) data = 0;
|
||||
rtc_second = data;
|
||||
} else if(ram_select == 0x09) {
|
||||
if(data >= 60) data = 0;
|
||||
rtc_minute = data;
|
||||
} else if(ram_select == 0x0a) {
|
||||
if(data >= 24) data = 0;
|
||||
rtc_hour = data;
|
||||
} else if(ram_select == 0x0b) {
|
||||
rtc_day = (rtc_day & 0x0100) | data;
|
||||
} else if(ram_select == 0x0c) {
|
||||
rtc_day = ((data & 1) << 8) | (rtc_day & 0xff);
|
||||
rtc_halt = data & 0x40;
|
||||
rtc_day_carry = data & 0x80;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::MBC3::power() {
|
||||
ram_enable = false;
|
||||
rom_select = 0x01;
|
||||
ram_select = 0x00;
|
||||
rtc_latch = 0;
|
||||
|
||||
rtc_halt = true;
|
||||
rtc_second = 0;
|
||||
rtc_minute = 0;
|
||||
rtc_hour = 0;
|
||||
rtc_day = 0;
|
||||
rtc_day_carry = false;
|
||||
|
||||
rtc_latch_second = 0;
|
||||
rtc_latch_minute = 0;
|
||||
rtc_latch_hour = 0;
|
||||
rtc_latch_day = 0;
|
||||
rtc_latch_day_carry = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
struct MBC3 : MMIO {
|
||||
bool ram_enable; //0000-1fff
|
||||
uint8 rom_select; //2000-3fff
|
||||
uint8 ram_select; //4000-5fff
|
||||
bool rtc_latch; //6000-7fff
|
||||
|
||||
bool rtc_halt;
|
||||
unsigned rtc_second;
|
||||
unsigned rtc_minute;
|
||||
unsigned rtc_hour;
|
||||
unsigned rtc_day;
|
||||
bool rtc_day_carry;
|
||||
|
||||
unsigned rtc_latch_second;
|
||||
unsigned rtc_latch_minute;
|
||||
unsigned rtc_latch_hour;
|
||||
unsigned rtc_latch_day;
|
||||
unsigned rtc_latch_day_carry;
|
||||
|
||||
void second();
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
void power();
|
||||
} mbc3;
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
uint8 Cartridge::MBC5::mmio_read(uint16 addr) {
|
||||
if(within<0x0000, 0x3fff>(addr)) {
|
||||
return cartridge.rom_read(addr);
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x7fff>(addr)) {
|
||||
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff));
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void Cartridge::MBC5::mmio_write(uint16 addr, uint8 data) {
|
||||
if(within<0x0000, 0x1fff>(addr)) {
|
||||
ram_enable = (data & 0x0f) == 0x0a;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x2000, 0x2fff>(addr)) {
|
||||
rom_select = (rom_select & 0x0100) | data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x3000, 0x3fff>(addr)) {
|
||||
rom_select = ((data & 1) << 8) | (rom_select & 0x00ff);
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x5fff>(addr)) {
|
||||
ram_select = data & 0x0f;
|
||||
return;
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::MBC5::power() {
|
||||
ram_enable = false;
|
||||
rom_select = 0x001;
|
||||
ram_select = 0x00;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
struct MBC5 : MMIO {
|
||||
bool ram_enable; //0000-1fff
|
||||
uint16 rom_select; //2000-2fff + 3000-3fff
|
||||
uint8 ram_select; //4000-5fff
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
void power();
|
||||
} mbc5;
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
uint8 Cartridge::MMM01::mmio_read(uint16 addr) {
|
||||
if(within<0x0000, 0x7fff>(addr)) {
|
||||
if(rom_mode == 0) return cartridge.rom_read(addr);
|
||||
}
|
||||
|
||||
if(within<0x0000, 0x3fff>(addr)) {
|
||||
return cartridge.rom_read(0x8000 + (rom_base << 14) + (addr & 0x3fff));
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x7fff>(addr)) {
|
||||
return cartridge.rom_read(0x8000 + (rom_base << 14) + (rom_select << 14) + (addr & 0x3fff));
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) return cartridge.ram_read((ram_select << 13) + (addr & 0x1fff));
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void Cartridge::MMM01::mmio_write(uint16 addr, uint8 data) {
|
||||
if(within<0x0000, 0x1fff>(addr)) {
|
||||
if(rom_mode == 0) {
|
||||
rom_mode = 1;
|
||||
} else {
|
||||
ram_enable = (data & 0x0f) == 0x0a;
|
||||
}
|
||||
}
|
||||
|
||||
if(within<0x2000, 0x3fff>(addr)) {
|
||||
if(rom_mode == 0) {
|
||||
rom_base = data & 0x3f;
|
||||
} else {
|
||||
rom_select = data;
|
||||
}
|
||||
}
|
||||
|
||||
if(within<0x4000, 0x5fff>(addr)) {
|
||||
if(rom_mode == 1) {
|
||||
ram_select = data;
|
||||
}
|
||||
}
|
||||
|
||||
if(within<0x6000, 0x7fff>(addr)) {
|
||||
//unknown purpose
|
||||
}
|
||||
|
||||
if(within<0xa000, 0xbfff>(addr)) {
|
||||
if(ram_enable) cartridge.ram_write((ram_select << 13) + (addr & 0x1fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::MMM01::power() {
|
||||
rom_mode = 0;
|
||||
rom_base = 0x00;
|
||||
|
||||
ram_enable = false;
|
||||
rom_select = 0x01;
|
||||
ram_select = 0x00;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
struct MMM01 : MMIO {
|
||||
bool rom_mode;
|
||||
uint8 rom_base;
|
||||
|
||||
bool ram_enable;
|
||||
uint8 rom_select;
|
||||
uint8 ram_select;
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
void power();
|
||||
} mmm01;
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
void Cartridge::serialize(serializer &s) {
|
||||
if(info.battery) s.array(ramdata, ramsize);
|
||||
s.integer(bootrom_enable);
|
||||
|
||||
s.integer(mbc1.ram_enable);
|
||||
s.integer(mbc1.rom_select);
|
||||
s.integer(mbc1.ram_select);
|
||||
s.integer(mbc1.mode_select);
|
||||
|
||||
s.integer(mbc2.ram_enable);
|
||||
s.integer(mbc2.rom_select);
|
||||
|
||||
s.integer(mbc3.ram_enable);
|
||||
s.integer(mbc3.rom_select);
|
||||
s.integer(mbc3.ram_select);
|
||||
s.integer(mbc3.rtc_latch);
|
||||
|
||||
s.integer(mbc3.rtc_halt);
|
||||
s.integer(mbc3.rtc_second);
|
||||
s.integer(mbc3.rtc_minute);
|
||||
s.integer(mbc3.rtc_hour);
|
||||
s.integer(mbc3.rtc_day);
|
||||
s.integer(mbc3.rtc_day_carry);
|
||||
|
||||
s.integer(mbc3.rtc_latch_second);
|
||||
s.integer(mbc3.rtc_latch_minute);
|
||||
s.integer(mbc3.rtc_latch_hour);
|
||||
s.integer(mbc3.rtc_latch_day);
|
||||
s.integer(mbc3.rtc_latch_day_carry);
|
||||
|
||||
s.integer(mbc5.ram_enable);
|
||||
s.integer(mbc5.rom_select);
|
||||
s.integer(mbc5.ram_select);
|
||||
|
||||
s.integer(mmm01.rom_mode);
|
||||
s.integer(mmm01.rom_base);
|
||||
|
||||
s.integer(mmm01.ram_enable);
|
||||
s.integer(mmm01.rom_select);
|
||||
s.integer(mmm01.ram_select);
|
||||
|
||||
s.integer(huc1.ram_enable);
|
||||
s.integer(huc1.rom_select);
|
||||
s.integer(huc1.ram_select);
|
||||
|
||||
s.integer(huc3.ram_enable);
|
||||
s.integer(huc3.rom_select);
|
||||
s.integer(huc3.ram_select);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+674
@@ -0,0 +1,674 @@
|
||||
#ifdef CPU_CPP
|
||||
|
||||
#include "table.cpp"
|
||||
#include "disassembler.cpp"
|
||||
|
||||
void CPU::op_xx() {
|
||||
}
|
||||
|
||||
void CPU::op_cb() {
|
||||
uint8 opcode = op_read(r[PC]++);
|
||||
(this->*opcode_table_cb[opcode])();
|
||||
}
|
||||
|
||||
//8-bit load commands
|
||||
|
||||
template<unsigned x, unsigned y> void CPU::op_ld_r_r() {
|
||||
r[x] = r[y];
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_ld_r_n() {
|
||||
r[x] = op_read(r[PC]++);
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_ld_r_hl() {
|
||||
r[x] = op_read(r[HL]);
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_ld_hl_r() {
|
||||
op_write(r[HL], r[x]);
|
||||
}
|
||||
|
||||
void CPU::op_ld_hl_n() {
|
||||
op_write(r[HL], op_read(r[PC]++));
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_ld_a_rr() {
|
||||
r[A] = op_read(r[x]);
|
||||
}
|
||||
|
||||
void CPU::op_ld_a_nn() {
|
||||
uint8 lo = op_read(r[PC]++);
|
||||
uint8 hi = op_read(r[PC]++);
|
||||
r[A] = op_read((hi << 8) | (lo << 0));
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_ld_rr_a() {
|
||||
op_write(r[x], r[A]);
|
||||
}
|
||||
|
||||
void CPU::op_ld_nn_a() {
|
||||
uint8 lo = op_read(r[PC]++);
|
||||
uint8 hi = op_read(r[PC]++);
|
||||
op_write((hi << 8) | (lo << 0), r[A]);
|
||||
}
|
||||
|
||||
void CPU::op_ld_a_ffn() {
|
||||
r[A] = op_read(0xff00 + op_read(r[PC]++));
|
||||
}
|
||||
|
||||
void CPU::op_ld_ffn_a() {
|
||||
op_write(0xff00 + op_read(r[PC]++), r[A]);
|
||||
}
|
||||
|
||||
void CPU::op_ld_a_ffc() {
|
||||
r[A] = op_read(0xff00 + r[C]);
|
||||
}
|
||||
|
||||
void CPU::op_ld_ffc_a() {
|
||||
op_write(0xff00 + r[C], r[A]);
|
||||
}
|
||||
|
||||
void CPU::op_ldi_hl_a() {
|
||||
op_write(r[HL], r[A]);
|
||||
r[HL]++;
|
||||
}
|
||||
|
||||
void CPU::op_ldi_a_hl() {
|
||||
r[A] = op_read(r[HL]);
|
||||
r[HL]++;
|
||||
}
|
||||
|
||||
void CPU::op_ldd_hl_a() {
|
||||
op_write(r[HL], r[A]);
|
||||
r[HL]--;
|
||||
}
|
||||
|
||||
void CPU::op_ldd_a_hl() {
|
||||
r[A] = op_read(r[HL]);
|
||||
r[HL]--;
|
||||
}
|
||||
|
||||
//16-bit load commands
|
||||
|
||||
template<unsigned x> void CPU::op_ld_rr_nn() {
|
||||
r[x] = op_read(r[PC]++) << 0;
|
||||
r[x] |= op_read(r[PC]++) << 8;
|
||||
}
|
||||
|
||||
void CPU::op_ld_nn_sp() {
|
||||
uint16 addr = op_read(r[PC]++) << 0;
|
||||
addr |= op_read(r[PC]++) << 8;
|
||||
op_write(addr + 0, r[SP] >> 0);
|
||||
op_write(addr + 1, r[SP] >> 8);
|
||||
}
|
||||
|
||||
void CPU::op_ld_sp_hl() {
|
||||
r[SP] = r[HL];
|
||||
op_io();
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_push_rr() {
|
||||
op_write(--r[SP], r[x] >> 8);
|
||||
op_write(--r[SP], r[x] >> 0);
|
||||
op_io();
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_pop_rr() {
|
||||
r[x] = op_read(r[SP]++) << 0;
|
||||
r[x] |= op_read(r[SP]++) << 8;
|
||||
}
|
||||
|
||||
//8-bit arithmetic commands
|
||||
|
||||
void CPU::opi_add_a(uint8 x) {
|
||||
uint16 rh = r[A] + x;
|
||||
uint16 rl = (r[A] & 0x0f) + (x & 0x0f);
|
||||
r[A] = rh;
|
||||
r.f.z = (uint8)rh == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = rl > 0x0f;
|
||||
r.f.c = rh > 0xff;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_add_a_r() { opi_add_a(r[x]); }
|
||||
void CPU::op_add_a_n() { opi_add_a(op_read(r[PC]++)); }
|
||||
void CPU::op_add_a_hl() { opi_add_a(op_read(r[HL])); }
|
||||
|
||||
void CPU::opi_adc_a(uint8 x) {
|
||||
uint16 rh = r[A] + x + r.f.c;
|
||||
uint16 rl = (r[A] & 0x0f) + (x & 0x0f) + r.f.c;
|
||||
r[A] = rh;
|
||||
r.f.z = (uint8)rh == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = rl > 0x0f;
|
||||
r.f.c = rh > 0xff;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_adc_a_r() { opi_adc_a(r[x]); }
|
||||
void CPU::op_adc_a_n() { opi_adc_a(op_read(r[PC]++)); }
|
||||
void CPU::op_adc_a_hl() { opi_adc_a(op_read(r[HL])); }
|
||||
|
||||
void CPU::opi_sub_a(uint8 x) {
|
||||
uint16 rh = r[A] - x;
|
||||
uint16 rl = (r[A] & 0x0f) - (x & 0x0f);
|
||||
r[A] = rh;
|
||||
r.f.z = (uint8)rh == 0;
|
||||
r.f.n = 1;
|
||||
r.f.h = rl > 0x0f;
|
||||
r.f.c = rh > 0xff;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_sub_a_r() { opi_sub_a(r[x]); }
|
||||
void CPU::op_sub_a_n() { opi_sub_a(op_read(r[PC]++)); }
|
||||
void CPU::op_sub_a_hl() { opi_sub_a(op_read(r[HL])); }
|
||||
|
||||
void CPU::opi_sbc_a(uint8 x) {
|
||||
uint16 rh = r[A] - x - r.f.c;
|
||||
uint16 rl = (r[A] & 0x0f) - (x & 0x0f) - r.f.c;
|
||||
r[A] = rh;
|
||||
r.f.z = (uint8)rh == 0;
|
||||
r.f.n = 1;
|
||||
r.f.h = rl > 0x0f;
|
||||
r.f.c = rh > 0xff;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_sbc_a_r() { opi_sbc_a(r[x]); }
|
||||
void CPU::op_sbc_a_n() { opi_sbc_a(op_read(r[PC]++)); }
|
||||
void CPU::op_sbc_a_hl() { opi_sbc_a(op_read(r[HL])); }
|
||||
|
||||
void CPU::opi_and_a(uint8 x) {
|
||||
r[A] &= x;
|
||||
r.f.z = r[A] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 1;
|
||||
r.f.c = 0;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_and_a_r() { opi_and_a(r[x]); }
|
||||
void CPU::op_and_a_n() { opi_and_a(op_read(r[PC]++)); }
|
||||
void CPU::op_and_a_hl() { opi_and_a(op_read(r[HL])); }
|
||||
|
||||
void CPU::opi_xor_a(uint8 x) {
|
||||
r[A] ^= x;
|
||||
r.f.z = r[A] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = 0;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_xor_a_r() { opi_xor_a(r[x]); }
|
||||
void CPU::op_xor_a_n() { opi_xor_a(op_read(r[PC]++)); }
|
||||
void CPU::op_xor_a_hl() { opi_xor_a(op_read(r[HL])); }
|
||||
|
||||
void CPU::opi_or_a(uint8 x) {
|
||||
r[A] |= x;
|
||||
r.f.z = r[A] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = 0;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_or_a_r() { opi_or_a(r[x]); }
|
||||
void CPU::op_or_a_n() { opi_or_a(op_read(r[PC]++)); }
|
||||
void CPU::op_or_a_hl() { opi_or_a(op_read(r[HL])); }
|
||||
|
||||
void CPU::opi_cp_a(uint8 x) {
|
||||
uint16 rh = r[A] - x;
|
||||
uint16 rl = (r[A] & 0x0f) - (x & 0x0f);
|
||||
r.f.z = (uint8)rh == 0;
|
||||
r.f.n = 1;
|
||||
r.f.h = rl > 0x0f;
|
||||
r.f.c = rh > 0xff;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_cp_a_r() { opi_cp_a(r[x]); }
|
||||
void CPU::op_cp_a_n() { opi_cp_a(op_read(r[PC]++)); }
|
||||
void CPU::op_cp_a_hl() { opi_cp_a(op_read(r[HL])); }
|
||||
|
||||
template<unsigned x> void CPU::op_inc_r() {
|
||||
r[x]++;
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = (r[x] & 0x0f) == 0x00;
|
||||
}
|
||||
|
||||
void CPU::op_inc_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
op_write(r[HL], ++n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = (n & 0x0f) == 0x00;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_dec_r() {
|
||||
r[x]--;
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 1;
|
||||
r.f.h = (r[x] & 0x0f) == 0x0f;
|
||||
}
|
||||
|
||||
void CPU::op_dec_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
op_write(r[HL], --n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 1;
|
||||
r.f.h = (n & 0x0f) == 0x0f;
|
||||
}
|
||||
|
||||
void CPU::op_daa() {
|
||||
uint16 a = r[A];
|
||||
if(r.f.n == 0) {
|
||||
if(r.f.h || (a & 0x0f) > 0x09) a += 0x06;
|
||||
if(r.f.c || (a ) > 0x9f) a += 0x60;
|
||||
} else {
|
||||
if(r.f.h) {
|
||||
a -= 0x06;
|
||||
if(r.f.c == 0) a &= 0xff;
|
||||
}
|
||||
if(r.f.c) a -= 0x60;
|
||||
}
|
||||
r[A] = a;
|
||||
r.f.z = r[A] == 0;
|
||||
r.f.h = 0;
|
||||
r.f.c |= a & 0x100;
|
||||
}
|
||||
|
||||
void CPU::op_cpl() {
|
||||
r[A] ^= 0xff;
|
||||
r.f.n = 1;
|
||||
r.f.h = 1;
|
||||
}
|
||||
|
||||
//16-bit arithmetic commands
|
||||
|
||||
template<unsigned x> void CPU::op_add_hl_rr() {
|
||||
op_io();
|
||||
uint32 rb = (r[HL] + r[x]);
|
||||
uint32 rn = (r[HL] & 0xfff) + (r[x] & 0xfff);
|
||||
r[HL] = rb;
|
||||
r.f.n = 0;
|
||||
r.f.h = rn > 0x0fff;
|
||||
r.f.c = rb > 0xffff;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_inc_rr() {
|
||||
op_io();
|
||||
r[x]++;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_dec_rr() {
|
||||
op_io();
|
||||
r[x]--;
|
||||
}
|
||||
|
||||
void CPU::op_add_sp_n() {
|
||||
op_io();
|
||||
op_io();
|
||||
signed n = (int8)op_read(r[PC]++);
|
||||
r.f.z = 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f;
|
||||
r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff;
|
||||
r[SP] += n;
|
||||
}
|
||||
|
||||
void CPU::op_ld_hl_sp_n() {
|
||||
op_io();
|
||||
signed n = (int8)op_read(r[PC]++);
|
||||
r.f.z = 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f;
|
||||
r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff;
|
||||
r[HL] = r[SP] + n;
|
||||
}
|
||||
|
||||
//rotate/shift commands
|
||||
|
||||
void CPU::op_rlca() {
|
||||
r[A] = (r[A] << 1) | (r[A] >> 7);
|
||||
r.f.z = 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = r[A] & 0x01;
|
||||
}
|
||||
|
||||
void CPU::op_rla() {
|
||||
bool c = r[A] & 0x80;
|
||||
r[A] = (r[A] << 1) | (r.f.c << 0);
|
||||
r.f.z = 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
void CPU::op_rrca() {
|
||||
r[A] = (r[A] >> 1) | (r[A] << 7);
|
||||
r.f.z = 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = r[A] & 0x80;
|
||||
}
|
||||
|
||||
void CPU::op_rra() {
|
||||
bool c = r[A] & 0x01;
|
||||
r[A] = (r[A] >> 1) | (r.f.c << 7);
|
||||
r.f.z = 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_rlc_r() {
|
||||
r[x] = (r[x] << 1) | (r[x] >> 7);
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = r[x] & 0x01;
|
||||
}
|
||||
|
||||
void CPU::op_rlc_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
n = (n << 1) | (n >> 7);
|
||||
op_write(r[HL], n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = n & 0x01;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_rl_r() {
|
||||
bool c = r[x] & 0x80;
|
||||
r[x] = (r[x] << 1) | (r.f.c << 0);
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
void CPU::op_rl_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
bool c = n & 0x80;
|
||||
n = (n << 1) | (r.f.c << 0);
|
||||
op_write(r[HL], n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_rrc_r() {
|
||||
r[x] = (r[x] >> 1) | (r[x] << 7);
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = r[x] & 0x80;
|
||||
}
|
||||
|
||||
void CPU::op_rrc_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
n = (n >> 1) | (n << 7);
|
||||
op_write(r[HL], n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = n & 0x80;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_rr_r() {
|
||||
bool c = r[x] & 0x01;
|
||||
r[x] = (r[x] >> 1) | (r.f.c << 7);
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
void CPU::op_rr_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
bool c = n & 0x01;
|
||||
n = (n >> 1) | (r.f.c << 7);
|
||||
op_write(r[HL], n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_sla_r() {
|
||||
bool c = r[x] & 0x80;
|
||||
r[x] <<= 1;
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
void CPU::op_sla_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
bool c = n & 0x80;
|
||||
n <<= 1;
|
||||
op_write(r[HL], n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_swap_r() {
|
||||
r[x] = (r[x] << 4) | (r[x] >> 4);
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = 0;
|
||||
}
|
||||
|
||||
void CPU::op_swap_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
n = (n << 4) | (n >> 4);
|
||||
op_write(r[HL], n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = 0;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_sra_r() {
|
||||
bool c = r[x] & 0x01;
|
||||
r[x] = (int8)r[x] >> 1;
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
void CPU::op_sra_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
bool c = n & 0x01;
|
||||
n = (int8)n >> 1;
|
||||
op_write(r[HL], n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
template<unsigned x> void CPU::op_srl_r() {
|
||||
bool c = r[x] & 0x01;
|
||||
r[x] >>= 1;
|
||||
r.f.z = r[x] == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
void CPU::op_srl_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
bool c = n & 0x01;
|
||||
n >>= 1;
|
||||
op_write(r[HL], n);
|
||||
r.f.z = n == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = c;
|
||||
}
|
||||
|
||||
//single-bit commands
|
||||
|
||||
template<unsigned b, unsigned x> void CPU::op_bit_n_r() {
|
||||
r.f.z = (r[x] & (1 << b)) == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 1;
|
||||
}
|
||||
|
||||
template<unsigned b> void CPU::op_bit_n_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
r.f.z = (n & (1 << b)) == 0;
|
||||
r.f.n = 0;
|
||||
r.f.h = 1;
|
||||
}
|
||||
|
||||
template<unsigned b, unsigned x> void CPU::op_set_n_r() {
|
||||
r[x] |= 1 << b;
|
||||
}
|
||||
|
||||
template<unsigned b> void CPU::op_set_n_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
n |= 1 << b;
|
||||
op_write(r[HL], n);
|
||||
}
|
||||
|
||||
template<unsigned b, unsigned x> void CPU::op_res_n_r() {
|
||||
r[x] &= ~(1 << b);
|
||||
}
|
||||
|
||||
template<unsigned b> void CPU::op_res_n_hl() {
|
||||
uint8 n = op_read(r[HL]);
|
||||
n &= ~(1 << b);
|
||||
op_write(r[HL], n);
|
||||
}
|
||||
|
||||
//control commands
|
||||
|
||||
void CPU::op_ccf() {
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = !r.f.c;
|
||||
}
|
||||
|
||||
void CPU::op_scf() {
|
||||
r.f.n = 0;
|
||||
r.f.h = 0;
|
||||
r.f.c = 1;
|
||||
}
|
||||
|
||||
void CPU::op_nop() {
|
||||
}
|
||||
|
||||
void CPU::op_halt() {
|
||||
status.halt = true;
|
||||
while(status.halt == true) op_io();
|
||||
}
|
||||
|
||||
void CPU::op_stop() {
|
||||
status.stop = true;
|
||||
while(status.stop == true) op_io();
|
||||
}
|
||||
|
||||
void CPU::op_di() {
|
||||
status.ime = 0;
|
||||
}
|
||||
|
||||
void CPU::op_ei() {
|
||||
status.ime = 1;
|
||||
}
|
||||
|
||||
//jump commands
|
||||
|
||||
void CPU::op_jp_nn() {
|
||||
uint8 lo = op_read(r[PC]++);
|
||||
uint8 hi = op_read(r[PC]++);
|
||||
r[PC] = (hi << 8) | (lo << 0);
|
||||
op_io();
|
||||
}
|
||||
|
||||
void CPU::op_jp_hl() {
|
||||
r[PC] = r[HL];
|
||||
}
|
||||
|
||||
template<unsigned x, bool y> void CPU::op_jp_f_nn() {
|
||||
uint8 lo = op_read(r[PC]++);
|
||||
uint8 hi = op_read(r[PC]++);
|
||||
if(r.f[x] == y) {
|
||||
r[PC] = (hi << 8) | (lo << 0);
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::op_jr_n() {
|
||||
int8 n = op_read(r[PC]++);
|
||||
r[PC] += n;
|
||||
op_io();
|
||||
}
|
||||
|
||||
template<unsigned x, bool y> void CPU::op_jr_f_n() {
|
||||
int8 n = op_read(r[PC]++);
|
||||
if(r.f[x] == y) {
|
||||
r[PC] += n;
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::op_call_nn() {
|
||||
uint8 lo = op_read(r[PC]++);
|
||||
uint8 hi = op_read(r[PC]++);
|
||||
op_write(--r[SP], r[PC] >> 8);
|
||||
op_write(--r[SP], r[PC] >> 0);
|
||||
r[PC] = (hi << 8) | (lo << 0);
|
||||
op_io();
|
||||
}
|
||||
|
||||
template<unsigned x, bool y> void CPU::op_call_f_nn() {
|
||||
uint8 lo = op_read(r[PC]++);
|
||||
uint8 hi = op_read(r[PC]++);
|
||||
if(r.f[x] == y) {
|
||||
op_write(--r[SP], r[PC] >> 8);
|
||||
op_write(--r[SP], r[PC] >> 0);
|
||||
r[PC] = (hi << 8) | (lo << 0);
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::op_ret() {
|
||||
uint8 lo = op_read(r[SP]++);
|
||||
uint8 hi = op_read(r[SP]++);
|
||||
r[PC] = (hi << 8) | (lo << 0);
|
||||
op_io();
|
||||
}
|
||||
|
||||
template<unsigned x, bool y> void CPU::op_ret_f() {
|
||||
op_io();
|
||||
if(r.f[x] == y) {
|
||||
uint8 lo = op_read(r[SP]++);
|
||||
uint8 hi = op_read(r[SP]++);
|
||||
r[PC] = (hi << 8) | (lo << 0);
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::op_reti() {
|
||||
uint8 lo = op_read(r[SP]++);
|
||||
uint8 hi = op_read(r[SP]++);
|
||||
r[PC] = (hi << 8) | (lo << 0);
|
||||
op_io();
|
||||
status.ime = 1;
|
||||
}
|
||||
|
||||
template<unsigned n> void CPU::op_rst_n() {
|
||||
op_write(--r[SP], r[PC] >> 8);
|
||||
op_write(--r[SP], r[PC] >> 0);
|
||||
r[PC] = n;
|
||||
op_io();
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+145
@@ -0,0 +1,145 @@
|
||||
#include "registers.hpp"
|
||||
void (CPU::*opcode_table[256])();
|
||||
void (CPU::*opcode_table_cb[256])();
|
||||
void initialize_opcode_table();
|
||||
|
||||
void op_xx();
|
||||
void op_cb();
|
||||
|
||||
//8-bit load commands
|
||||
template<unsigned x, unsigned y> void op_ld_r_r();
|
||||
template<unsigned x> void op_ld_r_n();
|
||||
template<unsigned x> void op_ld_r_hl();
|
||||
template<unsigned x> void op_ld_hl_r();
|
||||
void op_ld_hl_n();
|
||||
template<unsigned x> void op_ld_a_rr();
|
||||
void op_ld_a_nn();
|
||||
template<unsigned x> void op_ld_rr_a();
|
||||
void op_ld_nn_a();
|
||||
void op_ld_a_ffn();
|
||||
void op_ld_ffn_a();
|
||||
void op_ld_a_ffc();
|
||||
void op_ld_ffc_a();
|
||||
void op_ldi_hl_a();
|
||||
void op_ldi_a_hl();
|
||||
void op_ldd_hl_a();
|
||||
void op_ldd_a_hl();
|
||||
|
||||
//16-bit load commands
|
||||
template<unsigned x> void op_ld_rr_nn();
|
||||
void op_ld_nn_sp();
|
||||
void op_ld_sp_hl();
|
||||
template<unsigned x> void op_push_rr();
|
||||
template<unsigned x> void op_pop_rr();
|
||||
|
||||
//8-bit arithmetic commands
|
||||
void opi_add_a(uint8 x);
|
||||
template<unsigned x> void op_add_a_r();
|
||||
void op_add_a_n();
|
||||
void op_add_a_hl();
|
||||
|
||||
void opi_adc_a(uint8 x);
|
||||
template<unsigned x> void op_adc_a_r();
|
||||
void op_adc_a_n();
|
||||
void op_adc_a_hl();
|
||||
|
||||
void opi_sub_a(uint8 x);
|
||||
template<unsigned x> void op_sub_a_r();
|
||||
void op_sub_a_n();
|
||||
void op_sub_a_hl();
|
||||
|
||||
void opi_sbc_a(uint8 x);
|
||||
template<unsigned x> void op_sbc_a_r();
|
||||
void op_sbc_a_n();
|
||||
void op_sbc_a_hl();
|
||||
|
||||
void opi_and_a(uint8 x);
|
||||
template<unsigned x> void op_and_a_r();
|
||||
void op_and_a_n();
|
||||
void op_and_a_hl();
|
||||
|
||||
void opi_xor_a(uint8 x);
|
||||
template<unsigned x> void op_xor_a_r();
|
||||
void op_xor_a_n();
|
||||
void op_xor_a_hl();
|
||||
|
||||
void opi_or_a(uint8 x);
|
||||
template<unsigned x> void op_or_a_r();
|
||||
void op_or_a_n();
|
||||
void op_or_a_hl();
|
||||
|
||||
void opi_cp_a(uint8 x);
|
||||
template<unsigned x> void op_cp_a_r();
|
||||
void op_cp_a_n();
|
||||
void op_cp_a_hl();
|
||||
|
||||
template<unsigned x> void op_inc_r();
|
||||
void op_inc_hl();
|
||||
template<unsigned x> void op_dec_r();
|
||||
void op_dec_hl();
|
||||
void op_daa();
|
||||
void op_cpl();
|
||||
|
||||
//16-bit arithmetic commands
|
||||
template<unsigned x> void op_add_hl_rr();
|
||||
template<unsigned x> void op_inc_rr();
|
||||
template<unsigned x> void op_dec_rr();
|
||||
void op_add_sp_n();
|
||||
void op_ld_hl_sp_n();
|
||||
|
||||
//rotate/shift commands
|
||||
void op_rlca();
|
||||
void op_rla();
|
||||
void op_rrca();
|
||||
void op_rra();
|
||||
template<unsigned x> void op_rlc_r();
|
||||
void op_rlc_hl();
|
||||
template<unsigned x> void op_rl_r();
|
||||
void op_rl_hl();
|
||||
template<unsigned x> void op_rrc_r();
|
||||
void op_rrc_hl();
|
||||
template<unsigned x> void op_rr_r();
|
||||
void op_rr_hl();
|
||||
template<unsigned x> void op_sla_r();
|
||||
void op_sla_hl();
|
||||
template<unsigned x> void op_swap_r();
|
||||
void op_swap_hl();
|
||||
template<unsigned x> void op_sra_r();
|
||||
void op_sra_hl();
|
||||
template<unsigned x> void op_srl_r();
|
||||
void op_srl_hl();
|
||||
|
||||
//single-bit commands
|
||||
template<unsigned b, unsigned x> void op_bit_n_r();
|
||||
template<unsigned b> void op_bit_n_hl();
|
||||
template<unsigned b, unsigned x> void op_set_n_r();
|
||||
template<unsigned b> void op_set_n_hl();
|
||||
template<unsigned b, unsigned x> void op_res_n_r();
|
||||
template<unsigned b> void op_res_n_hl();
|
||||
|
||||
//control commands
|
||||
void op_ccf();
|
||||
void op_scf();
|
||||
void op_nop();
|
||||
void op_halt();
|
||||
void op_stop();
|
||||
void op_di();
|
||||
void op_ei();
|
||||
|
||||
//jump commands
|
||||
void op_jp_nn();
|
||||
void op_jp_hl();
|
||||
template<unsigned x, bool y> void op_jp_f_nn();
|
||||
void op_jr_n();
|
||||
template<unsigned x, bool y> void op_jr_f_n();
|
||||
void op_call_nn();
|
||||
template<unsigned x, bool y> void op_call_f_nn();
|
||||
void op_ret();
|
||||
template<unsigned x, bool y> void op_ret_f();
|
||||
void op_reti();
|
||||
template<unsigned n> void op_rst_n();
|
||||
|
||||
//disassembler.cpp
|
||||
string disassemble(uint16 pc);
|
||||
string disassemble_opcode(uint16 pc);
|
||||
string disassemble_opcode_cb(uint16 pc);
|
||||
Executable
+560
@@ -0,0 +1,560 @@
|
||||
#ifdef CPU_CPP
|
||||
|
||||
string CPU::disassemble(uint16 pc) {
|
||||
char output[80];
|
||||
memset(output, ' ', sizeof output);
|
||||
output[79] = 0;
|
||||
|
||||
string opcode = disassemble_opcode(pc);
|
||||
string registers = {
|
||||
" AF:", hex<4>(r[AF]),
|
||||
" BC:", hex<4>(r[BC]),
|
||||
" DE:", hex<4>(r[DE]),
|
||||
" HL:", hex<4>(r[HL]),
|
||||
" SP:", hex<4>(r[SP])
|
||||
};
|
||||
|
||||
memcpy(output + 0, hex<4>(pc), 4);
|
||||
memcpy(output + 6, opcode, opcode.length());
|
||||
memcpy(output + 23, registers, registers.length());
|
||||
output[63] = 0;
|
||||
return output;
|
||||
}
|
||||
|
||||
string CPU::disassemble_opcode(uint16 pc) {
|
||||
uint8 opcode = bus.read(pc);
|
||||
uint8 p0 = bus.read(pc + 1);
|
||||
uint8 p1 = bus.read(pc + 2);
|
||||
uint8 p2 = bus.read(pc + 3);
|
||||
|
||||
switch(opcode) {
|
||||
case 0x00: return { "nop" };
|
||||
case 0x01: return { "ld bc,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0x02: return { "ld (bc),a" };
|
||||
case 0x03: return { "inc bc" };
|
||||
case 0x04: return { "inc b" };
|
||||
case 0x05: return { "dec b" };
|
||||
case 0x06: return { "ld b,$", hex<2>(p0) };
|
||||
case 0x07: return { "rlc a" };
|
||||
case 0x08: return { "ld ($", hex<2>(p1), hex<2>(p0), "),sp" };
|
||||
case 0x09: return { "add hl,bc" };
|
||||
case 0x0a: return { "ld a,(bc)" };
|
||||
case 0x0b: return { "dec bc" };
|
||||
case 0x0c: return { "inc c" };
|
||||
case 0x0d: return { "dec c" };
|
||||
case 0x0e: return { "ld c,$", hex<2>(p0) };
|
||||
case 0x0f: return { "rrc a" };
|
||||
case 0x10: return { "stop" };
|
||||
case 0x11: return { "ld de,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0x12: return { "ld (de),a" };
|
||||
case 0x13: return { "inc de" };
|
||||
case 0x14: return { "inc d" };
|
||||
case 0x15: return { "dec d" };
|
||||
case 0x16: return { "ld d,$", hex<2>(p0) };
|
||||
case 0x17: return { "rl a" };
|
||||
case 0x18: return { "jr $", hex<4>(r[PC] + 2 + (int8)p0) };
|
||||
case 0x19: return { "add hl,de" };
|
||||
case 0x1a: return { "ld a,(de)" };
|
||||
case 0x1b: return { "dec de" };
|
||||
case 0x1c: return { "inc e" };
|
||||
case 0x1d: return { "dec e" };
|
||||
case 0x1e: return { "ld e,$", hex<2>(p0) };
|
||||
case 0x1f: return { "rr a" };
|
||||
case 0x20: return { "jr nz,$", hex<4>(r[PC] + 2 + (int8)p0) };
|
||||
case 0x21: return { "ld hl,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0x22: return { "ldi (hl),a" };
|
||||
case 0x23: return { "inc hl" };
|
||||
case 0x24: return { "inc h" };
|
||||
case 0x25: return { "dec h" };
|
||||
case 0x26: return { "ld h,$", hex<2>(p0) };
|
||||
case 0x27: return { "daa" };
|
||||
case 0x28: return { "jr z,$", hex<4>(r[PC] + 2 + (int8)p0) };
|
||||
case 0x29: return { "add hl,hl" };
|
||||
case 0x2a: return { "ldi a,(hl)" };
|
||||
case 0x2b: return { "dec hl" };
|
||||
case 0x2c: return { "inc l" };
|
||||
case 0x2d: return { "dec l" };
|
||||
case 0x2e: return { "ld l,$", hex<2>(p0) };
|
||||
case 0x2f: return { "cpl" };
|
||||
case 0x30: return { "jr nc,$", hex<4>(r[PC] + 2 + (int8)p0) };
|
||||
case 0x31: return { "ld sp,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0x32: return { "ldd (hl),a" };
|
||||
case 0x33: return { "inc sp" };
|
||||
case 0x34: return { "inc (hl)" };
|
||||
case 0x35: return { "dec (hl)" };
|
||||
case 0x36: return { "ld (hl),$", hex<2>(p0) };
|
||||
case 0x37: return { "scf" };
|
||||
case 0x38: return { "jr c,$", hex<4>(r[PC] + 2 + (int8)p0) };
|
||||
case 0x39: return { "add hl,sp" };
|
||||
case 0x3a: return { "ldd a,(hl)" };
|
||||
case 0x3b: return { "dec sp" };
|
||||
case 0x3c: return { "inc a" };
|
||||
case 0x3d: return { "dec a" };
|
||||
case 0x3e: return { "ld a,$", hex<2>(p0) };
|
||||
case 0x3f: return { "ccf" };
|
||||
case 0x40: return { "ld b,b" };
|
||||
case 0x41: return { "ld b,c" };
|
||||
case 0x42: return { "ld b,d" };
|
||||
case 0x43: return { "ld b,e" };
|
||||
case 0x44: return { "ld b,h" };
|
||||
case 0x45: return { "ld b,l" };
|
||||
case 0x46: return { "ld b,(hl)" };
|
||||
case 0x47: return { "ld b,a" };
|
||||
case 0x48: return { "ld c,b" };
|
||||
case 0x49: return { "ld c,c" };
|
||||
case 0x4a: return { "ld c,d" };
|
||||
case 0x4b: return { "ld c,e" };
|
||||
case 0x4c: return { "ld c,h" };
|
||||
case 0x4d: return { "ld c,l" };
|
||||
case 0x4e: return { "ld c,(hl)" };
|
||||
case 0x4f: return { "ld c,a" };
|
||||
case 0x50: return { "ld d,b" };
|
||||
case 0x51: return { "ld d,c" };
|
||||
case 0x52: return { "ld d,d" };
|
||||
case 0x53: return { "ld d,e" };
|
||||
case 0x54: return { "ld d,h" };
|
||||
case 0x55: return { "ld d,l" };
|
||||
case 0x56: return { "ld d,(hl)" };
|
||||
case 0x57: return { "ld d,a" };
|
||||
case 0x58: return { "ld e,b" };
|
||||
case 0x59: return { "ld e,c" };
|
||||
case 0x5a: return { "ld e,d" };
|
||||
case 0x5b: return { "ld e,e" };
|
||||
case 0x5c: return { "ld e,h" };
|
||||
case 0x5d: return { "ld e,l" };
|
||||
case 0x5e: return { "ld e,(hl)" };
|
||||
case 0x5f: return { "ld e,a" };
|
||||
case 0x60: return { "ld h,b" };
|
||||
case 0x61: return { "ld h,c" };
|
||||
case 0x62: return { "ld h,d" };
|
||||
case 0x63: return { "ld h,e" };
|
||||
case 0x64: return { "ld h,h" };
|
||||
case 0x65: return { "ld h,l" };
|
||||
case 0x66: return { "ld h,(hl)" };
|
||||
case 0x67: return { "ld h,a" };
|
||||
case 0x68: return { "ld l,b" };
|
||||
case 0x69: return { "ld l,c" };
|
||||
case 0x6a: return { "ld l,d" };
|
||||
case 0x6b: return { "ld l,e" };
|
||||
case 0x6c: return { "ld l,h" };
|
||||
case 0x6d: return { "ld l,l" };
|
||||
case 0x6e: return { "ld l,(hl)" };
|
||||
case 0x6f: return { "ld l,a" };
|
||||
case 0x70: return { "ld (hl),b" };
|
||||
case 0x71: return { "ld (hl),c" };
|
||||
case 0x72: return { "ld (hl),d" };
|
||||
case 0x73: return { "ld (hl),e" };
|
||||
case 0x74: return { "ld (hl),h" };
|
||||
case 0x75: return { "ld (hl),l" };
|
||||
case 0x76: return { "halt" };
|
||||
case 0x77: return { "ld (hl),a" };
|
||||
case 0x78: return { "ld a,b" };
|
||||
case 0x79: return { "ld a,c" };
|
||||
case 0x7a: return { "ld a,d" };
|
||||
case 0x7b: return { "ld a,e" };
|
||||
case 0x7c: return { "ld a,h" };
|
||||
case 0x7d: return { "ld a,l" };
|
||||
case 0x7e: return { "ld a,(hl)" };
|
||||
case 0x7f: return { "ld a,a" };
|
||||
case 0x80: return { "add a,b" };
|
||||
case 0x81: return { "add a,c" };
|
||||
case 0x82: return { "add a,d" };
|
||||
case 0x83: return { "add a,e" };
|
||||
case 0x84: return { "add a,h" };
|
||||
case 0x85: return { "add a,l" };
|
||||
case 0x86: return { "add a,(hl)" };
|
||||
case 0x87: return { "add a,a" };
|
||||
case 0x88: return { "adc a,b" };
|
||||
case 0x89: return { "adc a,c" };
|
||||
case 0x8a: return { "adc a,d" };
|
||||
case 0x8b: return { "adc a,e" };
|
||||
case 0x8c: return { "adc a,h" };
|
||||
case 0x8d: return { "adc a,l" };
|
||||
case 0x8e: return { "adc a,(hl)" };
|
||||
case 0x8f: return { "adc a,a" };
|
||||
case 0x90: return { "sub a,b" };
|
||||
case 0x91: return { "sub a,c" };
|
||||
case 0x92: return { "sub a,d" };
|
||||
case 0x93: return { "sub a,e" };
|
||||
case 0x94: return { "sub a,h" };
|
||||
case 0x95: return { "sub a,l" };
|
||||
case 0x96: return { "sub a,(hl)" };
|
||||
case 0x97: return { "sub a,a" };
|
||||
case 0x98: return { "sbc a,b" };
|
||||
case 0x99: return { "sbc a,c" };
|
||||
case 0x9a: return { "sbc a,d" };
|
||||
case 0x9b: return { "sbc a,e" };
|
||||
case 0x9c: return { "sbc a,h" };
|
||||
case 0x9d: return { "sbc a,l" };
|
||||
case 0x9e: return { "sbc a,(hl)" };
|
||||
case 0x9f: return { "sbc a,a" };
|
||||
case 0xa0: return { "and a,b" };
|
||||
case 0xa1: return { "and a,c" };
|
||||
case 0xa2: return { "and a,d" };
|
||||
case 0xa3: return { "and a,e" };
|
||||
case 0xa4: return { "and a,h" };
|
||||
case 0xa5: return { "and a,l" };
|
||||
case 0xa6: return { "and a,(hl)" };
|
||||
case 0xa7: return { "and a,a" };
|
||||
case 0xa8: return { "xor a,b" };
|
||||
case 0xa9: return { "xor a,c" };
|
||||
case 0xaa: return { "xor a,d" };
|
||||
case 0xab: return { "xor a,e" };
|
||||
case 0xac: return { "xor a,h" };
|
||||
case 0xad: return { "xor a,l" };
|
||||
case 0xae: return { "xor a,(hl)" };
|
||||
case 0xaf: return { "xor a,a" };
|
||||
case 0xb0: return { "or a,b" };
|
||||
case 0xb1: return { "or a,c" };
|
||||
case 0xb2: return { "or a,d" };
|
||||
case 0xb3: return { "or a,e" };
|
||||
case 0xb4: return { "or a,h" };
|
||||
case 0xb5: return { "or a,l" };
|
||||
case 0xb6: return { "or a,(hl)" };
|
||||
case 0xb7: return { "or a,a" };
|
||||
case 0xb8: return { "cp a,b" };
|
||||
case 0xb9: return { "cp a,c" };
|
||||
case 0xba: return { "cp a,d" };
|
||||
case 0xbb: return { "cp a,e" };
|
||||
case 0xbc: return { "cp a,h" };
|
||||
case 0xbd: return { "cp a,l" };
|
||||
case 0xbe: return { "cp a,(hl)" };
|
||||
case 0xbf: return { "cp a,a" };
|
||||
case 0xc0: return { "ret nz" };
|
||||
case 0xc1: return { "pop bc" };
|
||||
case 0xc2: return { "jp nz,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xc3: return { "jp $", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xc4: return { "call nz,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xc5: return { "push bc" };
|
||||
case 0xc6: return { "add a,$", hex<2>(p0) };
|
||||
case 0xc7: return { "rst $0000" };
|
||||
case 0xc8: return { "ret z" };
|
||||
case 0xc9: return { "ret" };
|
||||
case 0xca: return { "jp z,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xcb: return disassemble_opcode_cb(pc + 1);
|
||||
case 0xcc: return { "call z,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xcd: return { "call $", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xce: return { "adc a,$", hex<2>(p0) };
|
||||
case 0xcf: return { "rst $0008" };
|
||||
case 0xd0: return { "ret nc" };
|
||||
case 0xd1: return { "pop de" };
|
||||
case 0xd2: return { "jp nc,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xd3: return { "xx" };
|
||||
case 0xd4: return { "call nc,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xd5: return { "push de" };
|
||||
case 0xd6: return { "sub a,$", hex<2>(p0) };
|
||||
case 0xd7: return { "rst $0010" };
|
||||
case 0xd8: return { "ret c" };
|
||||
case 0xd9: return { "reti" };
|
||||
case 0xda: return { "jp c,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xdb: return { "xx" };
|
||||
case 0xdc: return { "call c,$", hex<2>(p1), hex<2>(p0) };
|
||||
case 0xdd: return { "xx" };
|
||||
case 0xde: return { "sbc a,$", hex<2>(p0) };
|
||||
case 0xdf: return { "rst $0018" };
|
||||
case 0xe0: return { "ld ($ff", hex<2>(p0), "),a" };
|
||||
case 0xe1: return { "pop hl" };
|
||||
case 0xe2: return { "ld ($ff00+c),a" };
|
||||
case 0xe3: return { "xx" };
|
||||
case 0xe4: return { "xx" };
|
||||
case 0xe5: return { "push hl" };
|
||||
case 0xe6: return { "and a,$", hex<2>(p0) };
|
||||
case 0xe7: return { "rst $0020" };
|
||||
case 0xe8: return { "add sp,$", hex<4>((int8)p0) };
|
||||
case 0xe9: return { "jp hl" };
|
||||
case 0xea: return { "ld ($", hex<2>(p1), hex<2>(p0), "),a" };
|
||||
case 0xeb: return { "xx" };
|
||||
case 0xec: return { "xx" };
|
||||
case 0xed: return { "xx" };
|
||||
case 0xee: return { "xor a,$", hex<2>(p0) };
|
||||
case 0xef: return { "rst $0028" };
|
||||
case 0xf0: return { "ld a,($ff", hex<2>(p0), ")" };
|
||||
case 0xf1: return { "pop af" };
|
||||
case 0xf2: return { "ld a,($ff00+c)" };
|
||||
case 0xf3: return { "di" };
|
||||
case 0xf4: return { "xx" };
|
||||
case 0xf5: return { "push af" };
|
||||
case 0xf6: return { "or a,$", hex<2>(p0) };
|
||||
case 0xf7: return { "rst $0030" };
|
||||
case 0xf8: return { "ld hl,sp+$", hex<4>((int8)p0) };
|
||||
case 0xf9: return { "ld sp,hl" };
|
||||
case 0xfa: return { "ld a,($", hex<2>(p1), hex<2>(p0), ")" };
|
||||
case 0xfb: return { "ei" };
|
||||
case 0xfc: return { "xx" };
|
||||
case 0xfd: return { "xx" };
|
||||
case 0xfe: return { "cp a,$", hex<2>(p0) };
|
||||
case 0xff: return { "rst $0038" };
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
string CPU::disassemble_opcode_cb(uint16 pc) {
|
||||
uint8 opcode = bus.read(pc);
|
||||
uint8 p0 = bus.read(pc + 1);
|
||||
uint8 p1 = bus.read(pc + 2);
|
||||
uint8 p2 = bus.read(pc + 3);
|
||||
|
||||
switch(opcode) {
|
||||
case 0x00: return { "rlc b" };
|
||||
case 0x01: return { "rlc c" };
|
||||
case 0x02: return { "rlc d" };
|
||||
case 0x03: return { "rlc e" };
|
||||
case 0x04: return { "rlc h" };
|
||||
case 0x05: return { "rlc l" };
|
||||
case 0x06: return { "rlc (hl)" };
|
||||
case 0x07: return { "rlc a" };
|
||||
case 0x08: return { "rrc b" };
|
||||
case 0x09: return { "rrc c" };
|
||||
case 0x0a: return { "rrc d" };
|
||||
case 0x0b: return { "rrc e" };
|
||||
case 0x0c: return { "rrc h" };
|
||||
case 0x0d: return { "rrc l" };
|
||||
case 0x0e: return { "rrc (hl)" };
|
||||
case 0x0f: return { "rrc a" };
|
||||
case 0x10: return { "rl b" };
|
||||
case 0x11: return { "rl c" };
|
||||
case 0x12: return { "rl d" };
|
||||
case 0x13: return { "rl e" };
|
||||
case 0x14: return { "rl h" };
|
||||
case 0x15: return { "rl l" };
|
||||
case 0x16: return { "rl (hl)" };
|
||||
case 0x17: return { "rl a" };
|
||||
case 0x18: return { "rr b" };
|
||||
case 0x19: return { "rr c" };
|
||||
case 0x1a: return { "rr d" };
|
||||
case 0x1b: return { "rr e" };
|
||||
case 0x1c: return { "rr h" };
|
||||
case 0x1d: return { "rr l" };
|
||||
case 0x1e: return { "rr (hl)" };
|
||||
case 0x1f: return { "rr a" };
|
||||
case 0x20: return { "sla b" };
|
||||
case 0x21: return { "sla c" };
|
||||
case 0x22: return { "sla d" };
|
||||
case 0x23: return { "sla e" };
|
||||
case 0x24: return { "sla h" };
|
||||
case 0x25: return { "sla l" };
|
||||
case 0x26: return { "sla (hl)" };
|
||||
case 0x27: return { "sla a" };
|
||||
case 0x28: return { "sra b" };
|
||||
case 0x29: return { "sra c" };
|
||||
case 0x2a: return { "sra d" };
|
||||
case 0x2b: return { "sra e" };
|
||||
case 0x2c: return { "sra h" };
|
||||
case 0x2d: return { "sra l" };
|
||||
case 0x2e: return { "sra (hl)" };
|
||||
case 0x2f: return { "sra a" };
|
||||
case 0x30: return { "swap b" };
|
||||
case 0x31: return { "swap c" };
|
||||
case 0x32: return { "swap d" };
|
||||
case 0x33: return { "swap e" };
|
||||
case 0x34: return { "swap h" };
|
||||
case 0x35: return { "swap l" };
|
||||
case 0x36: return { "swap (hl)" };
|
||||
case 0x37: return { "swap a" };
|
||||
case 0x38: return { "srl b" };
|
||||
case 0x39: return { "srl c" };
|
||||
case 0x3a: return { "srl d" };
|
||||
case 0x3b: return { "srl e" };
|
||||
case 0x3c: return { "srl h" };
|
||||
case 0x3d: return { "srl l" };
|
||||
case 0x3e: return { "srl (hl)" };
|
||||
case 0x3f: return { "srl a" };
|
||||
case 0x40: return { "bit 0,b" };
|
||||
case 0x41: return { "bit 0,c" };
|
||||
case 0x42: return { "bit 0,d" };
|
||||
case 0x43: return { "bit 0,e" };
|
||||
case 0x44: return { "bit 0,h" };
|
||||
case 0x45: return { "bit 0,l" };
|
||||
case 0x46: return { "bit 0,(hl)" };
|
||||
case 0x47: return { "bit 0,a" };
|
||||
case 0x48: return { "bit 1,b" };
|
||||
case 0x49: return { "bit 1,c" };
|
||||
case 0x4a: return { "bit 1,d" };
|
||||
case 0x4b: return { "bit 1,e" };
|
||||
case 0x4c: return { "bit 1,h" };
|
||||
case 0x4d: return { "bit 1,l" };
|
||||
case 0x4e: return { "bit 1,(hl)" };
|
||||
case 0x4f: return { "bit 1,a" };
|
||||
case 0x50: return { "bit 2,b" };
|
||||
case 0x51: return { "bit 2,c" };
|
||||
case 0x52: return { "bit 2,d" };
|
||||
case 0x53: return { "bit 2,e" };
|
||||
case 0x54: return { "bit 2,h" };
|
||||
case 0x55: return { "bit 2,l" };
|
||||
case 0x56: return { "bit 2,(hl)" };
|
||||
case 0x57: return { "bit 2,a" };
|
||||
case 0x58: return { "bit 3,b" };
|
||||
case 0x59: return { "bit 3,c" };
|
||||
case 0x5a: return { "bit 3,d" };
|
||||
case 0x5b: return { "bit 3,e" };
|
||||
case 0x5c: return { "bit 3,h" };
|
||||
case 0x5d: return { "bit 3,l" };
|
||||
case 0x5e: return { "bit 3,(hl)" };
|
||||
case 0x5f: return { "bit 3,a" };
|
||||
case 0x60: return { "bit 4,b" };
|
||||
case 0x61: return { "bit 4,c" };
|
||||
case 0x62: return { "bit 4,d" };
|
||||
case 0x63: return { "bit 4,e" };
|
||||
case 0x64: return { "bit 4,h" };
|
||||
case 0x65: return { "bit 4,l" };
|
||||
case 0x66: return { "bit 4,(hl)" };
|
||||
case 0x67: return { "bit 4,a" };
|
||||
case 0x68: return { "bit 5,b" };
|
||||
case 0x69: return { "bit 5,c" };
|
||||
case 0x6a: return { "bit 5,d" };
|
||||
case 0x6b: return { "bit 5,e" };
|
||||
case 0x6c: return { "bit 5,h" };
|
||||
case 0x6d: return { "bit 5,l" };
|
||||
case 0x6e: return { "bit 5,(hl)" };
|
||||
case 0x6f: return { "bit 5,a" };
|
||||
case 0x70: return { "bit 6,b" };
|
||||
case 0x71: return { "bit 6,c" };
|
||||
case 0x72: return { "bit 6,d" };
|
||||
case 0x73: return { "bit 6,e" };
|
||||
case 0x74: return { "bit 6,h" };
|
||||
case 0x75: return { "bit 6,l" };
|
||||
case 0x76: return { "bit 6,(hl)" };
|
||||
case 0x77: return { "bit 6,a" };
|
||||
case 0x78: return { "bit 7,b" };
|
||||
case 0x79: return { "bit 7,c" };
|
||||
case 0x7a: return { "bit 7,d" };
|
||||
case 0x7b: return { "bit 7,e" };
|
||||
case 0x7c: return { "bit 7,h" };
|
||||
case 0x7d: return { "bit 7,l" };
|
||||
case 0x7e: return { "bit 7,(hl)" };
|
||||
case 0x7f: return { "bit 7,a" };
|
||||
case 0x80: return { "res 0,b" };
|
||||
case 0x81: return { "res 0,c" };
|
||||
case 0x82: return { "res 0,d" };
|
||||
case 0x83: return { "res 0,e" };
|
||||
case 0x84: return { "res 0,h" };
|
||||
case 0x85: return { "res 0,l" };
|
||||
case 0x86: return { "res 0,(hl)" };
|
||||
case 0x87: return { "res 0,a" };
|
||||
case 0x88: return { "res 1,b" };
|
||||
case 0x89: return { "res 1,c" };
|
||||
case 0x8a: return { "res 1,d" };
|
||||
case 0x8b: return { "res 1,e" };
|
||||
case 0x8c: return { "res 1,h" };
|
||||
case 0x8d: return { "res 1,l" };
|
||||
case 0x8e: return { "res 1,(hl)" };
|
||||
case 0x8f: return { "res 1,a" };
|
||||
case 0x90: return { "res 2,b" };
|
||||
case 0x91: return { "res 2,c" };
|
||||
case 0x92: return { "res 2,d" };
|
||||
case 0x93: return { "res 2,e" };
|
||||
case 0x94: return { "res 2,h" };
|
||||
case 0x95: return { "res 2,l" };
|
||||
case 0x96: return { "res 2,(hl)" };
|
||||
case 0x97: return { "res 2,a" };
|
||||
case 0x98: return { "res 3,b" };
|
||||
case 0x99: return { "res 3,c" };
|
||||
case 0x9a: return { "res 3,d" };
|
||||
case 0x9b: return { "res 3,e" };
|
||||
case 0x9c: return { "res 3,h" };
|
||||
case 0x9d: return { "res 3,l" };
|
||||
case 0x9e: return { "res 3,(hl)" };
|
||||
case 0x9f: return { "res 3,a" };
|
||||
case 0xa0: return { "res 4,b" };
|
||||
case 0xa1: return { "res 4,c" };
|
||||
case 0xa2: return { "res 4,d" };
|
||||
case 0xa3: return { "res 4,e" };
|
||||
case 0xa4: return { "res 4,h" };
|
||||
case 0xa5: return { "res 4,l" };
|
||||
case 0xa6: return { "res 4,(hl)" };
|
||||
case 0xa7: return { "res 4,a" };
|
||||
case 0xa8: return { "res 5,b" };
|
||||
case 0xa9: return { "res 5,c" };
|
||||
case 0xaa: return { "res 5,d" };
|
||||
case 0xab: return { "res 5,e" };
|
||||
case 0xac: return { "res 5,h" };
|
||||
case 0xad: return { "res 5,l" };
|
||||
case 0xae: return { "res 5,(hl)" };
|
||||
case 0xaf: return { "res 5,a" };
|
||||
case 0xb0: return { "res 6,b" };
|
||||
case 0xb1: return { "res 6,c" };
|
||||
case 0xb2: return { "res 6,d" };
|
||||
case 0xb3: return { "res 6,e" };
|
||||
case 0xb4: return { "res 6,h" };
|
||||
case 0xb5: return { "res 6,l" };
|
||||
case 0xb6: return { "res 6,(hl)" };
|
||||
case 0xb7: return { "res 6,a" };
|
||||
case 0xb8: return { "res 7,b" };
|
||||
case 0xb9: return { "res 7,c" };
|
||||
case 0xba: return { "res 7,d" };
|
||||
case 0xbb: return { "res 7,e" };
|
||||
case 0xbc: return { "res 7,h" };
|
||||
case 0xbd: return { "res 7,l" };
|
||||
case 0xbe: return { "res 7,(hl)" };
|
||||
case 0xbf: return { "res 7,a" };
|
||||
case 0xc0: return { "set 0,b" };
|
||||
case 0xc1: return { "set 0,c" };
|
||||
case 0xc2: return { "set 0,d" };
|
||||
case 0xc3: return { "set 0,e" };
|
||||
case 0xc4: return { "set 0,h" };
|
||||
case 0xc5: return { "set 0,l" };
|
||||
case 0xc6: return { "set 0,(hl)" };
|
||||
case 0xc7: return { "set 0,a" };
|
||||
case 0xc8: return { "set 1,b" };
|
||||
case 0xc9: return { "set 1,c" };
|
||||
case 0xca: return { "set 1,d" };
|
||||
case 0xcb: return { "set 1,e" };
|
||||
case 0xcc: return { "set 1,h" };
|
||||
case 0xcd: return { "set 1,l" };
|
||||
case 0xce: return { "set 1,(hl)" };
|
||||
case 0xcf: return { "set 1,a" };
|
||||
case 0xd0: return { "set 2,b" };
|
||||
case 0xd1: return { "set 2,c" };
|
||||
case 0xd2: return { "set 2,d" };
|
||||
case 0xd3: return { "set 2,e" };
|
||||
case 0xd4: return { "set 2,h" };
|
||||
case 0xd5: return { "set 2,l" };
|
||||
case 0xd6: return { "set 2,(hl)" };
|
||||
case 0xd7: return { "set 2,a" };
|
||||
case 0xd8: return { "set 3,b" };
|
||||
case 0xd9: return { "set 3,c" };
|
||||
case 0xda: return { "set 3,d" };
|
||||
case 0xdb: return { "set 3,e" };
|
||||
case 0xdc: return { "set 3,h" };
|
||||
case 0xdd: return { "set 3,l" };
|
||||
case 0xde: return { "set 3,(hl)" };
|
||||
case 0xdf: return { "set 3,a" };
|
||||
case 0xe0: return { "set 4,b" };
|
||||
case 0xe1: return { "set 4,c" };
|
||||
case 0xe2: return { "set 4,d" };
|
||||
case 0xe3: return { "set 4,e" };
|
||||
case 0xe4: return { "set 4,h" };
|
||||
case 0xe5: return { "set 4,l" };
|
||||
case 0xe6: return { "set 4,(hl)" };
|
||||
case 0xe7: return { "set 4,a" };
|
||||
case 0xe8: return { "set 5,b" };
|
||||
case 0xe9: return { "set 5,c" };
|
||||
case 0xea: return { "set 5,d" };
|
||||
case 0xeb: return { "set 5,e" };
|
||||
case 0xec: return { "set 5,h" };
|
||||
case 0xed: return { "set 5,l" };
|
||||
case 0xee: return { "set 5,(hl)" };
|
||||
case 0xef: return { "set 5,a" };
|
||||
case 0xf0: return { "set 6,b" };
|
||||
case 0xf1: return { "set 6,c" };
|
||||
case 0xf2: return { "set 6,d" };
|
||||
case 0xf3: return { "set 6,e" };
|
||||
case 0xf4: return { "set 6,h" };
|
||||
case 0xf5: return { "set 6,l" };
|
||||
case 0xf6: return { "set 6,(hl)" };
|
||||
case 0xf7: return { "set 6,a" };
|
||||
case 0xf8: return { "set 7,b" };
|
||||
case 0xf9: return { "set 7,c" };
|
||||
case 0xfa: return { "set 7,d" };
|
||||
case 0xfb: return { "set 7,e" };
|
||||
case 0xfc: return { "set 7,h" };
|
||||
case 0xfd: return { "set 7,l" };
|
||||
case 0xfe: return { "set 7,(hl)" };
|
||||
case 0xff: return { "set 7,a" };
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+101
@@ -0,0 +1,101 @@
|
||||
enum {
|
||||
A, F, AF,
|
||||
B, C, BC,
|
||||
D, E, DE,
|
||||
H, L, HL,
|
||||
SP, PC,
|
||||
};
|
||||
|
||||
enum {
|
||||
ZF, NF, HF, CF,
|
||||
};
|
||||
|
||||
//register base class
|
||||
//the idea here is to have all registers derive from a single base class.
|
||||
//this allows construction of opcodes that can take any register as input or output,
|
||||
//despite the fact that behind-the-scenes, special handling is done for eg: F, AF, HL, etc.
|
||||
//registers can also be chained together: eg af = 0x0000 writes both a and f.
|
||||
struct Register {
|
||||
virtual operator unsigned() const = 0;
|
||||
virtual unsigned operator=(unsigned x) = 0;
|
||||
Register& operator=(const Register &x) { operator=((unsigned)x); return *this; }
|
||||
|
||||
unsigned operator++(int) { unsigned r = *this; operator=(*this + 1); return r; }
|
||||
unsigned operator--(int) { unsigned r = *this; operator=(*this - 1); return r; }
|
||||
unsigned operator++() { return operator=(*this + 1); }
|
||||
unsigned operator--() { return operator=(*this - 1); }
|
||||
|
||||
unsigned operator |=(unsigned x) { return operator=(*this | x); }
|
||||
unsigned operator ^=(unsigned x) { return operator=(*this ^ x); }
|
||||
unsigned operator &=(unsigned x) { return operator=(*this & x); }
|
||||
|
||||
unsigned operator<<=(unsigned x) { return operator=(*this << x); }
|
||||
unsigned operator>>=(unsigned x) { return operator=(*this >> x); }
|
||||
|
||||
unsigned operator +=(unsigned x) { return operator=(*this + x); }
|
||||
unsigned operator -=(unsigned x) { return operator=(*this - x); }
|
||||
unsigned operator *=(unsigned x) { return operator=(*this * x); }
|
||||
unsigned operator /=(unsigned x) { return operator=(*this / x); }
|
||||
unsigned operator %=(unsigned x) { return operator=(*this % x); }
|
||||
};
|
||||
|
||||
struct Register8 : Register {
|
||||
uint8 data;
|
||||
operator unsigned() const { return data; }
|
||||
unsigned operator=(unsigned x) { return data = x; }
|
||||
};
|
||||
|
||||
struct RegisterF : Register {
|
||||
bool z, n, h, c;
|
||||
operator unsigned() const { return (z << 7) | (n << 6) | (h << 5) | (c << 4); }
|
||||
unsigned operator=(unsigned x) { z = x & 0x80; n = x & 0x40; h = x & 0x20; c = x & 0x10; return *this; }
|
||||
bool& operator[](unsigned r) {
|
||||
static bool* table[] = { &z, &n, &h, &c };
|
||||
return *table[r];
|
||||
}
|
||||
};
|
||||
|
||||
struct Register16 : Register {
|
||||
uint16 data;
|
||||
operator unsigned() const { return data; }
|
||||
unsigned operator=(unsigned x) { return data = x; }
|
||||
};
|
||||
|
||||
struct RegisterAF : Register {
|
||||
Register8 &hi;
|
||||
RegisterF &lo;
|
||||
operator unsigned() const { return (hi << 8) | (lo << 0); }
|
||||
unsigned operator=(unsigned x) { hi = x >> 8; lo = x >> 0; return *this; }
|
||||
RegisterAF(Register8 &hi, RegisterF &lo) : hi(hi), lo(lo) {}
|
||||
};
|
||||
|
||||
struct RegisterW : Register {
|
||||
Register8 &hi, &lo;
|
||||
operator unsigned() const { return (hi << 8) | (lo << 0); }
|
||||
unsigned operator=(unsigned x) { hi = x >> 8; lo = x >> 0; return *this; }
|
||||
RegisterW(Register8 &hi, Register8 &lo) : hi(hi), lo(lo) {}
|
||||
};
|
||||
|
||||
struct Registers {
|
||||
Register8 a;
|
||||
RegisterF f;
|
||||
RegisterAF af;
|
||||
Register8 b;
|
||||
Register8 c;
|
||||
RegisterW bc;
|
||||
Register8 d;
|
||||
Register8 e;
|
||||
RegisterW de;
|
||||
Register8 h;
|
||||
Register8 l;
|
||||
RegisterW hl;
|
||||
Register16 sp;
|
||||
Register16 pc;
|
||||
|
||||
Register& operator[](unsigned r) {
|
||||
static Register* table[] = { &a, &f, &af, &b, &c, &bc, &d, &e, &de, &h, &l, &hl, &sp, &pc };
|
||||
return *table[r];
|
||||
}
|
||||
|
||||
Registers() : af(a, f), bc(b, c), de(d, e), hl(h, l) {}
|
||||
} r;
|
||||
Executable
+519
@@ -0,0 +1,519 @@
|
||||
#ifdef CPU_CPP
|
||||
|
||||
void CPU::initialize_opcode_table() {
|
||||
opcode_table[0x00] = &CPU::op_nop;
|
||||
opcode_table[0x01] = &CPU::op_ld_rr_nn<BC>;
|
||||
opcode_table[0x02] = &CPU::op_ld_rr_a<BC>;
|
||||
opcode_table[0x03] = &CPU::op_inc_rr<BC>;
|
||||
opcode_table[0x04] = &CPU::op_inc_r<B>;
|
||||
opcode_table[0x05] = &CPU::op_dec_r<B>;
|
||||
opcode_table[0x06] = &CPU::op_ld_r_n<B>;
|
||||
opcode_table[0x07] = &CPU::op_rlca;
|
||||
opcode_table[0x08] = &CPU::op_ld_nn_sp;
|
||||
opcode_table[0x09] = &CPU::op_add_hl_rr<BC>;
|
||||
opcode_table[0x0a] = &CPU::op_ld_a_rr<BC>;
|
||||
opcode_table[0x0b] = &CPU::op_dec_rr<BC>;
|
||||
opcode_table[0x0c] = &CPU::op_inc_r<C>;
|
||||
opcode_table[0x0d] = &CPU::op_dec_r<C>;
|
||||
opcode_table[0x0e] = &CPU::op_ld_r_n<C>;
|
||||
opcode_table[0x0f] = &CPU::op_rrca;
|
||||
opcode_table[0x10] = &CPU::op_stop;
|
||||
opcode_table[0x11] = &CPU::op_ld_rr_nn<DE>;
|
||||
opcode_table[0x12] = &CPU::op_ld_rr_a<DE>;
|
||||
opcode_table[0x13] = &CPU::op_inc_rr<DE>;
|
||||
opcode_table[0x14] = &CPU::op_inc_r<D>;
|
||||
opcode_table[0x15] = &CPU::op_dec_r<D>;
|
||||
opcode_table[0x16] = &CPU::op_ld_r_n<D>;
|
||||
opcode_table[0x17] = &CPU::op_rla;
|
||||
opcode_table[0x18] = &CPU::op_jr_n;
|
||||
opcode_table[0x19] = &CPU::op_add_hl_rr<DE>;
|
||||
opcode_table[0x1a] = &CPU::op_ld_a_rr<DE>;
|
||||
opcode_table[0x1b] = &CPU::op_dec_rr<DE>;
|
||||
opcode_table[0x1c] = &CPU::op_inc_r<E>;
|
||||
opcode_table[0x1d] = &CPU::op_dec_r<E>;
|
||||
opcode_table[0x1e] = &CPU::op_ld_r_n<E>;
|
||||
opcode_table[0x1f] = &CPU::op_rra;
|
||||
opcode_table[0x20] = &CPU::op_jr_f_n<ZF, 0>;
|
||||
opcode_table[0x21] = &CPU::op_ld_rr_nn<HL>;
|
||||
opcode_table[0x22] = &CPU::op_ldi_hl_a;
|
||||
opcode_table[0x23] = &CPU::op_inc_rr<HL>;
|
||||
opcode_table[0x24] = &CPU::op_inc_r<H>;
|
||||
opcode_table[0x25] = &CPU::op_dec_r<H>;
|
||||
opcode_table[0x26] = &CPU::op_ld_r_n<H>;
|
||||
opcode_table[0x27] = &CPU::op_daa;
|
||||
opcode_table[0x28] = &CPU::op_jr_f_n<ZF, 1>;
|
||||
opcode_table[0x29] = &CPU::op_add_hl_rr<HL>;
|
||||
opcode_table[0x2a] = &CPU::op_ldi_a_hl;
|
||||
opcode_table[0x2b] = &CPU::op_dec_rr<HL>;
|
||||
opcode_table[0x2c] = &CPU::op_inc_r<L>;
|
||||
opcode_table[0x2d] = &CPU::op_dec_r<L>;
|
||||
opcode_table[0x2e] = &CPU::op_ld_r_n<L>;
|
||||
opcode_table[0x2f] = &CPU::op_cpl;
|
||||
opcode_table[0x30] = &CPU::op_jr_f_n<CF, 0>;
|
||||
opcode_table[0x31] = &CPU::op_ld_rr_nn<SP>;
|
||||
opcode_table[0x32] = &CPU::op_ldd_hl_a;
|
||||
opcode_table[0x33] = &CPU::op_inc_rr<SP>;
|
||||
opcode_table[0x34] = &CPU::op_inc_hl;
|
||||
opcode_table[0x35] = &CPU::op_dec_hl;
|
||||
opcode_table[0x36] = &CPU::op_ld_hl_n;
|
||||
opcode_table[0x37] = &CPU::op_scf;
|
||||
opcode_table[0x38] = &CPU::op_jr_f_n<CF, 1>;
|
||||
opcode_table[0x39] = &CPU::op_add_hl_rr<SP>;
|
||||
opcode_table[0x3a] = &CPU::op_ldd_a_hl;
|
||||
opcode_table[0x3b] = &CPU::op_dec_rr<SP>;
|
||||
opcode_table[0x3c] = &CPU::op_inc_r<A>;
|
||||
opcode_table[0x3d] = &CPU::op_dec_r<A>;
|
||||
opcode_table[0x3e] = &CPU::op_ld_r_n<A>;
|
||||
opcode_table[0x3f] = &CPU::op_ccf;
|
||||
opcode_table[0x40] = &CPU::op_ld_r_r<B, B>;
|
||||
opcode_table[0x41] = &CPU::op_ld_r_r<B, C>;
|
||||
opcode_table[0x42] = &CPU::op_ld_r_r<B, D>;
|
||||
opcode_table[0x43] = &CPU::op_ld_r_r<B, E>;
|
||||
opcode_table[0x44] = &CPU::op_ld_r_r<B, H>;
|
||||
opcode_table[0x45] = &CPU::op_ld_r_r<B, L>;
|
||||
opcode_table[0x46] = &CPU::op_ld_r_hl<B>;
|
||||
opcode_table[0x47] = &CPU::op_ld_r_r<B, A>;
|
||||
opcode_table[0x48] = &CPU::op_ld_r_r<C, B>;
|
||||
opcode_table[0x49] = &CPU::op_ld_r_r<C, C>;
|
||||
opcode_table[0x4a] = &CPU::op_ld_r_r<C, D>;
|
||||
opcode_table[0x4b] = &CPU::op_ld_r_r<C, E>;
|
||||
opcode_table[0x4c] = &CPU::op_ld_r_r<C, H>;
|
||||
opcode_table[0x4d] = &CPU::op_ld_r_r<C, L>;
|
||||
opcode_table[0x4e] = &CPU::op_ld_r_hl<C>;
|
||||
opcode_table[0x4f] = &CPU::op_ld_r_r<C, A>;
|
||||
opcode_table[0x50] = &CPU::op_ld_r_r<D, B>;
|
||||
opcode_table[0x51] = &CPU::op_ld_r_r<D, C>;
|
||||
opcode_table[0x52] = &CPU::op_ld_r_r<D, D>;
|
||||
opcode_table[0x53] = &CPU::op_ld_r_r<D, E>;
|
||||
opcode_table[0x54] = &CPU::op_ld_r_r<D, H>;
|
||||
opcode_table[0x55] = &CPU::op_ld_r_r<D, L>;
|
||||
opcode_table[0x56] = &CPU::op_ld_r_hl<D>;
|
||||
opcode_table[0x57] = &CPU::op_ld_r_r<D, A>;
|
||||
opcode_table[0x58] = &CPU::op_ld_r_r<E, B>;
|
||||
opcode_table[0x59] = &CPU::op_ld_r_r<E, C>;
|
||||
opcode_table[0x5a] = &CPU::op_ld_r_r<E, D>;
|
||||
opcode_table[0x5b] = &CPU::op_ld_r_r<E, E>;
|
||||
opcode_table[0x5c] = &CPU::op_ld_r_r<E, H>;
|
||||
opcode_table[0x5d] = &CPU::op_ld_r_r<E, L>;
|
||||
opcode_table[0x5e] = &CPU::op_ld_r_hl<E>;
|
||||
opcode_table[0x5f] = &CPU::op_ld_r_r<E, A>;
|
||||
opcode_table[0x60] = &CPU::op_ld_r_r<H, B>;
|
||||
opcode_table[0x61] = &CPU::op_ld_r_r<H, C>;
|
||||
opcode_table[0x62] = &CPU::op_ld_r_r<H, D>;
|
||||
opcode_table[0x63] = &CPU::op_ld_r_r<H, E>;
|
||||
opcode_table[0x64] = &CPU::op_ld_r_r<H, H>;
|
||||
opcode_table[0x65] = &CPU::op_ld_r_r<H, L>;
|
||||
opcode_table[0x66] = &CPU::op_ld_r_hl<H>;
|
||||
opcode_table[0x67] = &CPU::op_ld_r_r<H, A>;
|
||||
opcode_table[0x68] = &CPU::op_ld_r_r<L, B>;
|
||||
opcode_table[0x69] = &CPU::op_ld_r_r<L, C>;
|
||||
opcode_table[0x6a] = &CPU::op_ld_r_r<L, D>;
|
||||
opcode_table[0x6b] = &CPU::op_ld_r_r<L, E>;
|
||||
opcode_table[0x6c] = &CPU::op_ld_r_r<L, H>;
|
||||
opcode_table[0x6d] = &CPU::op_ld_r_r<L, L>;
|
||||
opcode_table[0x6e] = &CPU::op_ld_r_hl<L>;
|
||||
opcode_table[0x6f] = &CPU::op_ld_r_r<L, A>;
|
||||
opcode_table[0x70] = &CPU::op_ld_hl_r<B>;
|
||||
opcode_table[0x71] = &CPU::op_ld_hl_r<C>;
|
||||
opcode_table[0x72] = &CPU::op_ld_hl_r<D>;
|
||||
opcode_table[0x73] = &CPU::op_ld_hl_r<E>;
|
||||
opcode_table[0x74] = &CPU::op_ld_hl_r<H>;
|
||||
opcode_table[0x75] = &CPU::op_ld_hl_r<L>;
|
||||
opcode_table[0x76] = &CPU::op_halt;
|
||||
opcode_table[0x77] = &CPU::op_ld_hl_r<A>;
|
||||
opcode_table[0x78] = &CPU::op_ld_r_r<A, B>;
|
||||
opcode_table[0x79] = &CPU::op_ld_r_r<A, C>;
|
||||
opcode_table[0x7a] = &CPU::op_ld_r_r<A, D>;
|
||||
opcode_table[0x7b] = &CPU::op_ld_r_r<A, E>;
|
||||
opcode_table[0x7c] = &CPU::op_ld_r_r<A, H>;
|
||||
opcode_table[0x7d] = &CPU::op_ld_r_r<A, L>;
|
||||
opcode_table[0x7e] = &CPU::op_ld_r_hl<A>;
|
||||
opcode_table[0x7f] = &CPU::op_ld_r_r<A, A>;
|
||||
opcode_table[0x80] = &CPU::op_add_a_r<B>;
|
||||
opcode_table[0x81] = &CPU::op_add_a_r<C>;
|
||||
opcode_table[0x82] = &CPU::op_add_a_r<D>;
|
||||
opcode_table[0x83] = &CPU::op_add_a_r<E>;
|
||||
opcode_table[0x84] = &CPU::op_add_a_r<H>;
|
||||
opcode_table[0x85] = &CPU::op_add_a_r<L>;
|
||||
opcode_table[0x86] = &CPU::op_add_a_hl;
|
||||
opcode_table[0x87] = &CPU::op_add_a_r<A>;
|
||||
opcode_table[0x88] = &CPU::op_adc_a_r<B>;
|
||||
opcode_table[0x89] = &CPU::op_adc_a_r<C>;
|
||||
opcode_table[0x8a] = &CPU::op_adc_a_r<D>;
|
||||
opcode_table[0x8b] = &CPU::op_adc_a_r<E>;
|
||||
opcode_table[0x8c] = &CPU::op_adc_a_r<H>;
|
||||
opcode_table[0x8d] = &CPU::op_adc_a_r<L>;
|
||||
opcode_table[0x8e] = &CPU::op_adc_a_hl;
|
||||
opcode_table[0x8f] = &CPU::op_adc_a_r<A>;
|
||||
opcode_table[0x90] = &CPU::op_sub_a_r<B>;
|
||||
opcode_table[0x91] = &CPU::op_sub_a_r<C>;
|
||||
opcode_table[0x92] = &CPU::op_sub_a_r<D>;
|
||||
opcode_table[0x93] = &CPU::op_sub_a_r<E>;
|
||||
opcode_table[0x94] = &CPU::op_sub_a_r<H>;
|
||||
opcode_table[0x95] = &CPU::op_sub_a_r<L>;
|
||||
opcode_table[0x96] = &CPU::op_sub_a_hl;
|
||||
opcode_table[0x97] = &CPU::op_sub_a_r<A>;
|
||||
opcode_table[0x98] = &CPU::op_sbc_a_r<B>;
|
||||
opcode_table[0x99] = &CPU::op_sbc_a_r<C>;
|
||||
opcode_table[0x9a] = &CPU::op_sbc_a_r<D>;
|
||||
opcode_table[0x9b] = &CPU::op_sbc_a_r<E>;
|
||||
opcode_table[0x9c] = &CPU::op_sbc_a_r<H>;
|
||||
opcode_table[0x9d] = &CPU::op_sbc_a_r<L>;
|
||||
opcode_table[0x9e] = &CPU::op_sbc_a_hl;
|
||||
opcode_table[0x9f] = &CPU::op_sbc_a_r<A>;
|
||||
opcode_table[0xa0] = &CPU::op_and_a_r<B>;
|
||||
opcode_table[0xa1] = &CPU::op_and_a_r<C>;
|
||||
opcode_table[0xa2] = &CPU::op_and_a_r<D>;
|
||||
opcode_table[0xa3] = &CPU::op_and_a_r<E>;
|
||||
opcode_table[0xa4] = &CPU::op_and_a_r<H>;
|
||||
opcode_table[0xa5] = &CPU::op_and_a_r<L>;
|
||||
opcode_table[0xa6] = &CPU::op_and_a_hl;
|
||||
opcode_table[0xa7] = &CPU::op_and_a_r<A>;
|
||||
opcode_table[0xa8] = &CPU::op_xor_a_r<B>;
|
||||
opcode_table[0xa9] = &CPU::op_xor_a_r<C>;
|
||||
opcode_table[0xaa] = &CPU::op_xor_a_r<D>;
|
||||
opcode_table[0xab] = &CPU::op_xor_a_r<E>;
|
||||
opcode_table[0xac] = &CPU::op_xor_a_r<H>;
|
||||
opcode_table[0xad] = &CPU::op_xor_a_r<L>;
|
||||
opcode_table[0xae] = &CPU::op_xor_a_hl;
|
||||
opcode_table[0xaf] = &CPU::op_xor_a_r<A>;
|
||||
opcode_table[0xb0] = &CPU::op_or_a_r<B>;
|
||||
opcode_table[0xb1] = &CPU::op_or_a_r<C>;
|
||||
opcode_table[0xb2] = &CPU::op_or_a_r<D>;
|
||||
opcode_table[0xb3] = &CPU::op_or_a_r<E>;
|
||||
opcode_table[0xb4] = &CPU::op_or_a_r<H>;
|
||||
opcode_table[0xb5] = &CPU::op_or_a_r<L>;
|
||||
opcode_table[0xb6] = &CPU::op_or_a_hl;
|
||||
opcode_table[0xb7] = &CPU::op_or_a_r<A>;
|
||||
opcode_table[0xb8] = &CPU::op_cp_a_r<B>;
|
||||
opcode_table[0xb9] = &CPU::op_cp_a_r<C>;
|
||||
opcode_table[0xba] = &CPU::op_cp_a_r<D>;
|
||||
opcode_table[0xbb] = &CPU::op_cp_a_r<E>;
|
||||
opcode_table[0xbc] = &CPU::op_cp_a_r<H>;
|
||||
opcode_table[0xbd] = &CPU::op_cp_a_r<L>;
|
||||
opcode_table[0xbe] = &CPU::op_cp_a_hl;
|
||||
opcode_table[0xbf] = &CPU::op_cp_a_r<A>;
|
||||
opcode_table[0xc0] = &CPU::op_ret_f<ZF, 0>;
|
||||
opcode_table[0xc1] = &CPU::op_pop_rr<BC>;
|
||||
opcode_table[0xc2] = &CPU::op_jp_f_nn<ZF, 0>;
|
||||
opcode_table[0xc3] = &CPU::op_jp_nn;
|
||||
opcode_table[0xc4] = &CPU::op_call_f_nn<ZF, 0>;
|
||||
opcode_table[0xc5] = &CPU::op_push_rr<BC>;
|
||||
opcode_table[0xc6] = &CPU::op_add_a_n;
|
||||
opcode_table[0xc7] = &CPU::op_rst_n<0x00>;
|
||||
opcode_table[0xc8] = &CPU::op_ret_f<ZF, 1>;
|
||||
opcode_table[0xc9] = &CPU::op_ret;
|
||||
opcode_table[0xca] = &CPU::op_jp_f_nn<ZF, 1>;
|
||||
opcode_table[0xcb] = &CPU::op_cb;
|
||||
opcode_table[0xcc] = &CPU::op_call_f_nn<ZF, 1>;
|
||||
opcode_table[0xcd] = &CPU::op_call_nn;
|
||||
opcode_table[0xce] = &CPU::op_adc_a_n;
|
||||
opcode_table[0xcf] = &CPU::op_rst_n<0x08>;
|
||||
opcode_table[0xd0] = &CPU::op_ret_f<CF, 0>;
|
||||
opcode_table[0xd1] = &CPU::op_pop_rr<DE>;
|
||||
opcode_table[0xd2] = &CPU::op_jp_f_nn<CF, 0>;
|
||||
opcode_table[0xd3] = &CPU::op_xx;
|
||||
opcode_table[0xd4] = &CPU::op_call_f_nn<CF, 0>;
|
||||
opcode_table[0xd5] = &CPU::op_push_rr<DE>;
|
||||
opcode_table[0xd6] = &CPU::op_sub_a_n;
|
||||
opcode_table[0xd7] = &CPU::op_rst_n<0x10>;
|
||||
opcode_table[0xd8] = &CPU::op_ret_f<CF, 1>;
|
||||
opcode_table[0xd9] = &CPU::op_reti;
|
||||
opcode_table[0xda] = &CPU::op_jp_f_nn<CF, 1>;
|
||||
opcode_table[0xdb] = &CPU::op_xx;
|
||||
opcode_table[0xdc] = &CPU::op_call_f_nn<CF, 1>;
|
||||
opcode_table[0xdd] = &CPU::op_xx;
|
||||
opcode_table[0xde] = &CPU::op_sbc_a_n;
|
||||
opcode_table[0xdf] = &CPU::op_rst_n<0x18>;
|
||||
opcode_table[0xe0] = &CPU::op_ld_ffn_a;
|
||||
opcode_table[0xe1] = &CPU::op_pop_rr<HL>;
|
||||
opcode_table[0xe2] = &CPU::op_ld_ffc_a;
|
||||
opcode_table[0xe3] = &CPU::op_xx;
|
||||
opcode_table[0xe4] = &CPU::op_xx;
|
||||
opcode_table[0xe5] = &CPU::op_push_rr<HL>;
|
||||
opcode_table[0xe6] = &CPU::op_and_a_n;
|
||||
opcode_table[0xe7] = &CPU::op_rst_n<0x20>;
|
||||
opcode_table[0xe8] = &CPU::op_add_sp_n;
|
||||
opcode_table[0xe9] = &CPU::op_jp_hl;
|
||||
opcode_table[0xea] = &CPU::op_ld_nn_a;
|
||||
opcode_table[0xeb] = &CPU::op_xx;
|
||||
opcode_table[0xec] = &CPU::op_xx;
|
||||
opcode_table[0xed] = &CPU::op_xx;
|
||||
opcode_table[0xee] = &CPU::op_xor_a_n;
|
||||
opcode_table[0xef] = &CPU::op_rst_n<0x28>;
|
||||
opcode_table[0xf0] = &CPU::op_ld_a_ffn;
|
||||
opcode_table[0xf1] = &CPU::op_pop_rr<AF>;
|
||||
opcode_table[0xf2] = &CPU::op_ld_a_ffc;
|
||||
opcode_table[0xf3] = &CPU::op_di;
|
||||
opcode_table[0xf4] = &CPU::op_xx;
|
||||
opcode_table[0xf5] = &CPU::op_push_rr<AF>;
|
||||
opcode_table[0xf6] = &CPU::op_or_a_n;
|
||||
opcode_table[0xf7] = &CPU::op_rst_n<0x30>;
|
||||
opcode_table[0xf8] = &CPU::op_ld_hl_sp_n;
|
||||
opcode_table[0xf9] = &CPU::op_ld_sp_hl;
|
||||
opcode_table[0xfa] = &CPU::op_ld_a_nn;
|
||||
opcode_table[0xfb] = &CPU::op_ei;
|
||||
opcode_table[0xfc] = &CPU::op_xx;
|
||||
opcode_table[0xfd] = &CPU::op_xx;
|
||||
opcode_table[0xfe] = &CPU::op_cp_a_n;
|
||||
opcode_table[0xff] = &CPU::op_rst_n<0x38>;
|
||||
|
||||
opcode_table_cb[0x00] = &CPU::op_rlc_r<B>;
|
||||
opcode_table_cb[0x01] = &CPU::op_rlc_r<C>;
|
||||
opcode_table_cb[0x02] = &CPU::op_rlc_r<D>;
|
||||
opcode_table_cb[0x03] = &CPU::op_rlc_r<E>;
|
||||
opcode_table_cb[0x04] = &CPU::op_rlc_r<H>;
|
||||
opcode_table_cb[0x05] = &CPU::op_rlc_r<L>;
|
||||
opcode_table_cb[0x06] = &CPU::op_rlc_hl;
|
||||
opcode_table_cb[0x07] = &CPU::op_rlc_r<A>;
|
||||
opcode_table_cb[0x08] = &CPU::op_rrc_r<B>;
|
||||
opcode_table_cb[0x09] = &CPU::op_rrc_r<C>;
|
||||
opcode_table_cb[0x0a] = &CPU::op_rrc_r<D>;
|
||||
opcode_table_cb[0x0b] = &CPU::op_rrc_r<E>;
|
||||
opcode_table_cb[0x0c] = &CPU::op_rrc_r<H>;
|
||||
opcode_table_cb[0x0d] = &CPU::op_rrc_r<L>;
|
||||
opcode_table_cb[0x0e] = &CPU::op_rrc_hl;
|
||||
opcode_table_cb[0x0f] = &CPU::op_rrc_r<A>;
|
||||
opcode_table_cb[0x10] = &CPU::op_rl_r<B>;
|
||||
opcode_table_cb[0x11] = &CPU::op_rl_r<C>;
|
||||
opcode_table_cb[0x12] = &CPU::op_rl_r<D>;
|
||||
opcode_table_cb[0x13] = &CPU::op_rl_r<E>;
|
||||
opcode_table_cb[0x14] = &CPU::op_rl_r<H>;
|
||||
opcode_table_cb[0x15] = &CPU::op_rl_r<L>;
|
||||
opcode_table_cb[0x16] = &CPU::op_rl_hl;
|
||||
opcode_table_cb[0x17] = &CPU::op_rl_r<A>;
|
||||
opcode_table_cb[0x18] = &CPU::op_rr_r<B>;
|
||||
opcode_table_cb[0x19] = &CPU::op_rr_r<C>;
|
||||
opcode_table_cb[0x1a] = &CPU::op_rr_r<D>;
|
||||
opcode_table_cb[0x1b] = &CPU::op_rr_r<E>;
|
||||
opcode_table_cb[0x1c] = &CPU::op_rr_r<H>;
|
||||
opcode_table_cb[0x1d] = &CPU::op_rr_r<L>;
|
||||
opcode_table_cb[0x1e] = &CPU::op_rr_hl;
|
||||
opcode_table_cb[0x1f] = &CPU::op_rr_r<A>;
|
||||
opcode_table_cb[0x20] = &CPU::op_sla_r<B>;
|
||||
opcode_table_cb[0x21] = &CPU::op_sla_r<C>;
|
||||
opcode_table_cb[0x22] = &CPU::op_sla_r<D>;
|
||||
opcode_table_cb[0x23] = &CPU::op_sla_r<E>;
|
||||
opcode_table_cb[0x24] = &CPU::op_sla_r<H>;
|
||||
opcode_table_cb[0x25] = &CPU::op_sla_r<L>;
|
||||
opcode_table_cb[0x26] = &CPU::op_sla_hl;
|
||||
opcode_table_cb[0x27] = &CPU::op_sla_r<A>;
|
||||
opcode_table_cb[0x28] = &CPU::op_sra_r<B>;
|
||||
opcode_table_cb[0x29] = &CPU::op_sra_r<C>;
|
||||
opcode_table_cb[0x2a] = &CPU::op_sra_r<D>;
|
||||
opcode_table_cb[0x2b] = &CPU::op_sra_r<E>;
|
||||
opcode_table_cb[0x2c] = &CPU::op_sra_r<H>;
|
||||
opcode_table_cb[0x2d] = &CPU::op_sra_r<L>;
|
||||
opcode_table_cb[0x2e] = &CPU::op_sra_hl;
|
||||
opcode_table_cb[0x2f] = &CPU::op_sra_r<A>;
|
||||
opcode_table_cb[0x30] = &CPU::op_swap_r<B>;
|
||||
opcode_table_cb[0x31] = &CPU::op_swap_r<C>;
|
||||
opcode_table_cb[0x32] = &CPU::op_swap_r<D>;
|
||||
opcode_table_cb[0x33] = &CPU::op_swap_r<E>;
|
||||
opcode_table_cb[0x34] = &CPU::op_swap_r<H>;
|
||||
opcode_table_cb[0x35] = &CPU::op_swap_r<L>;
|
||||
opcode_table_cb[0x36] = &CPU::op_swap_hl;
|
||||
opcode_table_cb[0x37] = &CPU::op_swap_r<A>;
|
||||
opcode_table_cb[0x38] = &CPU::op_srl_r<B>;
|
||||
opcode_table_cb[0x39] = &CPU::op_srl_r<C>;
|
||||
opcode_table_cb[0x3a] = &CPU::op_srl_r<D>;
|
||||
opcode_table_cb[0x3b] = &CPU::op_srl_r<E>;
|
||||
opcode_table_cb[0x3c] = &CPU::op_srl_r<H>;
|
||||
opcode_table_cb[0x3d] = &CPU::op_srl_r<L>;
|
||||
opcode_table_cb[0x3e] = &CPU::op_srl_hl;
|
||||
opcode_table_cb[0x3f] = &CPU::op_srl_r<A>;
|
||||
opcode_table_cb[0x40] = &CPU::op_bit_n_r<0, B>;
|
||||
opcode_table_cb[0x41] = &CPU::op_bit_n_r<0, C>;
|
||||
opcode_table_cb[0x42] = &CPU::op_bit_n_r<0, D>;
|
||||
opcode_table_cb[0x43] = &CPU::op_bit_n_r<0, E>;
|
||||
opcode_table_cb[0x44] = &CPU::op_bit_n_r<0, H>;
|
||||
opcode_table_cb[0x45] = &CPU::op_bit_n_r<0, L>;
|
||||
opcode_table_cb[0x46] = &CPU::op_bit_n_hl<0>;
|
||||
opcode_table_cb[0x47] = &CPU::op_bit_n_r<0, A>;
|
||||
opcode_table_cb[0x48] = &CPU::op_bit_n_r<1, B>;
|
||||
opcode_table_cb[0x49] = &CPU::op_bit_n_r<1, C>;
|
||||
opcode_table_cb[0x4a] = &CPU::op_bit_n_r<1, D>;
|
||||
opcode_table_cb[0x4b] = &CPU::op_bit_n_r<1, E>;
|
||||
opcode_table_cb[0x4c] = &CPU::op_bit_n_r<1, H>;
|
||||
opcode_table_cb[0x4d] = &CPU::op_bit_n_r<1, L>;
|
||||
opcode_table_cb[0x4e] = &CPU::op_bit_n_hl<1>;
|
||||
opcode_table_cb[0x4f] = &CPU::op_bit_n_r<1, A>;
|
||||
opcode_table_cb[0x50] = &CPU::op_bit_n_r<2, B>;
|
||||
opcode_table_cb[0x51] = &CPU::op_bit_n_r<2, C>;
|
||||
opcode_table_cb[0x52] = &CPU::op_bit_n_r<2, D>;
|
||||
opcode_table_cb[0x53] = &CPU::op_bit_n_r<2, E>;
|
||||
opcode_table_cb[0x54] = &CPU::op_bit_n_r<2, H>;
|
||||
opcode_table_cb[0x55] = &CPU::op_bit_n_r<2, L>;
|
||||
opcode_table_cb[0x56] = &CPU::op_bit_n_hl<2>;
|
||||
opcode_table_cb[0x57] = &CPU::op_bit_n_r<2, A>;
|
||||
opcode_table_cb[0x58] = &CPU::op_bit_n_r<3, B>;
|
||||
opcode_table_cb[0x59] = &CPU::op_bit_n_r<3, C>;
|
||||
opcode_table_cb[0x5a] = &CPU::op_bit_n_r<3, D>;
|
||||
opcode_table_cb[0x5b] = &CPU::op_bit_n_r<3, E>;
|
||||
opcode_table_cb[0x5c] = &CPU::op_bit_n_r<3, H>;
|
||||
opcode_table_cb[0x5d] = &CPU::op_bit_n_r<3, L>;
|
||||
opcode_table_cb[0x5e] = &CPU::op_bit_n_hl<3>;
|
||||
opcode_table_cb[0x5f] = &CPU::op_bit_n_r<3, A>;
|
||||
opcode_table_cb[0x60] = &CPU::op_bit_n_r<4, B>;
|
||||
opcode_table_cb[0x61] = &CPU::op_bit_n_r<4, C>;
|
||||
opcode_table_cb[0x62] = &CPU::op_bit_n_r<4, D>;
|
||||
opcode_table_cb[0x63] = &CPU::op_bit_n_r<4, E>;
|
||||
opcode_table_cb[0x64] = &CPU::op_bit_n_r<4, H>;
|
||||
opcode_table_cb[0x65] = &CPU::op_bit_n_r<4, L>;
|
||||
opcode_table_cb[0x66] = &CPU::op_bit_n_hl<4>;
|
||||
opcode_table_cb[0x67] = &CPU::op_bit_n_r<4, A>;
|
||||
opcode_table_cb[0x68] = &CPU::op_bit_n_r<5, B>;
|
||||
opcode_table_cb[0x69] = &CPU::op_bit_n_r<5, C>;
|
||||
opcode_table_cb[0x6a] = &CPU::op_bit_n_r<5, D>;
|
||||
opcode_table_cb[0x6b] = &CPU::op_bit_n_r<5, E>;
|
||||
opcode_table_cb[0x6c] = &CPU::op_bit_n_r<5, H>;
|
||||
opcode_table_cb[0x6d] = &CPU::op_bit_n_r<5, L>;
|
||||
opcode_table_cb[0x6e] = &CPU::op_bit_n_hl<5>;
|
||||
opcode_table_cb[0x6f] = &CPU::op_bit_n_r<5, A>;
|
||||
opcode_table_cb[0x70] = &CPU::op_bit_n_r<6, B>;
|
||||
opcode_table_cb[0x71] = &CPU::op_bit_n_r<6, C>;
|
||||
opcode_table_cb[0x72] = &CPU::op_bit_n_r<6, D>;
|
||||
opcode_table_cb[0x73] = &CPU::op_bit_n_r<6, E>;
|
||||
opcode_table_cb[0x74] = &CPU::op_bit_n_r<6, H>;
|
||||
opcode_table_cb[0x75] = &CPU::op_bit_n_r<6, L>;
|
||||
opcode_table_cb[0x76] = &CPU::op_bit_n_hl<6>;
|
||||
opcode_table_cb[0x77] = &CPU::op_bit_n_r<6, A>;
|
||||
opcode_table_cb[0x78] = &CPU::op_bit_n_r<7, B>;
|
||||
opcode_table_cb[0x79] = &CPU::op_bit_n_r<7, C>;
|
||||
opcode_table_cb[0x7a] = &CPU::op_bit_n_r<7, D>;
|
||||
opcode_table_cb[0x7b] = &CPU::op_bit_n_r<7, E>;
|
||||
opcode_table_cb[0x7c] = &CPU::op_bit_n_r<7, H>;
|
||||
opcode_table_cb[0x7d] = &CPU::op_bit_n_r<7, L>;
|
||||
opcode_table_cb[0x7e] = &CPU::op_bit_n_hl<7>;
|
||||
opcode_table_cb[0x7f] = &CPU::op_bit_n_r<7, A>;
|
||||
opcode_table_cb[0x80] = &CPU::op_res_n_r<0, B>;
|
||||
opcode_table_cb[0x81] = &CPU::op_res_n_r<0, C>;
|
||||
opcode_table_cb[0x82] = &CPU::op_res_n_r<0, D>;
|
||||
opcode_table_cb[0x83] = &CPU::op_res_n_r<0, E>;
|
||||
opcode_table_cb[0x84] = &CPU::op_res_n_r<0, H>;
|
||||
opcode_table_cb[0x85] = &CPU::op_res_n_r<0, L>;
|
||||
opcode_table_cb[0x86] = &CPU::op_res_n_hl<0>;
|
||||
opcode_table_cb[0x87] = &CPU::op_res_n_r<0, A>;
|
||||
opcode_table_cb[0x88] = &CPU::op_res_n_r<1, B>;
|
||||
opcode_table_cb[0x89] = &CPU::op_res_n_r<1, C>;
|
||||
opcode_table_cb[0x8a] = &CPU::op_res_n_r<1, D>;
|
||||
opcode_table_cb[0x8b] = &CPU::op_res_n_r<1, E>;
|
||||
opcode_table_cb[0x8c] = &CPU::op_res_n_r<1, H>;
|
||||
opcode_table_cb[0x8d] = &CPU::op_res_n_r<1, L>;
|
||||
opcode_table_cb[0x8e] = &CPU::op_res_n_hl<1>;
|
||||
opcode_table_cb[0x8f] = &CPU::op_res_n_r<1, A>;
|
||||
opcode_table_cb[0x90] = &CPU::op_res_n_r<2, B>;
|
||||
opcode_table_cb[0x91] = &CPU::op_res_n_r<2, C>;
|
||||
opcode_table_cb[0x92] = &CPU::op_res_n_r<2, D>;
|
||||
opcode_table_cb[0x93] = &CPU::op_res_n_r<2, E>;
|
||||
opcode_table_cb[0x94] = &CPU::op_res_n_r<2, H>;
|
||||
opcode_table_cb[0x95] = &CPU::op_res_n_r<2, L>;
|
||||
opcode_table_cb[0x96] = &CPU::op_res_n_hl<2>;
|
||||
opcode_table_cb[0x97] = &CPU::op_res_n_r<2, A>;
|
||||
opcode_table_cb[0x98] = &CPU::op_res_n_r<3, B>;
|
||||
opcode_table_cb[0x99] = &CPU::op_res_n_r<3, C>;
|
||||
opcode_table_cb[0x9a] = &CPU::op_res_n_r<3, D>;
|
||||
opcode_table_cb[0x9b] = &CPU::op_res_n_r<3, E>;
|
||||
opcode_table_cb[0x9c] = &CPU::op_res_n_r<3, H>;
|
||||
opcode_table_cb[0x9d] = &CPU::op_res_n_r<3, L>;
|
||||
opcode_table_cb[0x9e] = &CPU::op_res_n_hl<3>;
|
||||
opcode_table_cb[0x9f] = &CPU::op_res_n_r<3, A>;
|
||||
opcode_table_cb[0xa0] = &CPU::op_res_n_r<4, B>;
|
||||
opcode_table_cb[0xa1] = &CPU::op_res_n_r<4, C>;
|
||||
opcode_table_cb[0xa2] = &CPU::op_res_n_r<4, D>;
|
||||
opcode_table_cb[0xa3] = &CPU::op_res_n_r<4, E>;
|
||||
opcode_table_cb[0xa4] = &CPU::op_res_n_r<4, H>;
|
||||
opcode_table_cb[0xa5] = &CPU::op_res_n_r<4, L>;
|
||||
opcode_table_cb[0xa6] = &CPU::op_res_n_hl<4>;
|
||||
opcode_table_cb[0xa7] = &CPU::op_res_n_r<4, A>;
|
||||
opcode_table_cb[0xa8] = &CPU::op_res_n_r<5, B>;
|
||||
opcode_table_cb[0xa9] = &CPU::op_res_n_r<5, C>;
|
||||
opcode_table_cb[0xaa] = &CPU::op_res_n_r<5, D>;
|
||||
opcode_table_cb[0xab] = &CPU::op_res_n_r<5, E>;
|
||||
opcode_table_cb[0xac] = &CPU::op_res_n_r<5, H>;
|
||||
opcode_table_cb[0xad] = &CPU::op_res_n_r<5, L>;
|
||||
opcode_table_cb[0xae] = &CPU::op_res_n_hl<5>;
|
||||
opcode_table_cb[0xaf] = &CPU::op_res_n_r<5, A>;
|
||||
opcode_table_cb[0xb0] = &CPU::op_res_n_r<6, B>;
|
||||
opcode_table_cb[0xb1] = &CPU::op_res_n_r<6, C>;
|
||||
opcode_table_cb[0xb2] = &CPU::op_res_n_r<6, D>;
|
||||
opcode_table_cb[0xb3] = &CPU::op_res_n_r<6, E>;
|
||||
opcode_table_cb[0xb4] = &CPU::op_res_n_r<6, H>;
|
||||
opcode_table_cb[0xb5] = &CPU::op_res_n_r<6, L>;
|
||||
opcode_table_cb[0xb6] = &CPU::op_res_n_hl<6>;
|
||||
opcode_table_cb[0xb7] = &CPU::op_res_n_r<6, A>;
|
||||
opcode_table_cb[0xb8] = &CPU::op_res_n_r<7, B>;
|
||||
opcode_table_cb[0xb9] = &CPU::op_res_n_r<7, C>;
|
||||
opcode_table_cb[0xba] = &CPU::op_res_n_r<7, D>;
|
||||
opcode_table_cb[0xbb] = &CPU::op_res_n_r<7, E>;
|
||||
opcode_table_cb[0xbc] = &CPU::op_res_n_r<7, H>;
|
||||
opcode_table_cb[0xbd] = &CPU::op_res_n_r<7, L>;
|
||||
opcode_table_cb[0xbe] = &CPU::op_res_n_hl<7>;
|
||||
opcode_table_cb[0xbf] = &CPU::op_res_n_r<7, A>;
|
||||
opcode_table_cb[0xc0] = &CPU::op_set_n_r<0, B>;
|
||||
opcode_table_cb[0xc1] = &CPU::op_set_n_r<0, C>;
|
||||
opcode_table_cb[0xc2] = &CPU::op_set_n_r<0, D>;
|
||||
opcode_table_cb[0xc3] = &CPU::op_set_n_r<0, E>;
|
||||
opcode_table_cb[0xc4] = &CPU::op_set_n_r<0, H>;
|
||||
opcode_table_cb[0xc5] = &CPU::op_set_n_r<0, L>;
|
||||
opcode_table_cb[0xc6] = &CPU::op_set_n_hl<0>;
|
||||
opcode_table_cb[0xc7] = &CPU::op_set_n_r<0, A>;
|
||||
opcode_table_cb[0xc8] = &CPU::op_set_n_r<1, B>;
|
||||
opcode_table_cb[0xc9] = &CPU::op_set_n_r<1, C>;
|
||||
opcode_table_cb[0xca] = &CPU::op_set_n_r<1, D>;
|
||||
opcode_table_cb[0xcb] = &CPU::op_set_n_r<1, E>;
|
||||
opcode_table_cb[0xcc] = &CPU::op_set_n_r<1, H>;
|
||||
opcode_table_cb[0xcd] = &CPU::op_set_n_r<1, L>;
|
||||
opcode_table_cb[0xce] = &CPU::op_set_n_hl<1>;
|
||||
opcode_table_cb[0xcf] = &CPU::op_set_n_r<1, A>;
|
||||
opcode_table_cb[0xd0] = &CPU::op_set_n_r<2, B>;
|
||||
opcode_table_cb[0xd1] = &CPU::op_set_n_r<2, C>;
|
||||
opcode_table_cb[0xd2] = &CPU::op_set_n_r<2, D>;
|
||||
opcode_table_cb[0xd3] = &CPU::op_set_n_r<2, E>;
|
||||
opcode_table_cb[0xd4] = &CPU::op_set_n_r<2, H>;
|
||||
opcode_table_cb[0xd5] = &CPU::op_set_n_r<2, L>;
|
||||
opcode_table_cb[0xd6] = &CPU::op_set_n_hl<2>;
|
||||
opcode_table_cb[0xd7] = &CPU::op_set_n_r<2, A>;
|
||||
opcode_table_cb[0xd8] = &CPU::op_set_n_r<3, B>;
|
||||
opcode_table_cb[0xd9] = &CPU::op_set_n_r<3, C>;
|
||||
opcode_table_cb[0xda] = &CPU::op_set_n_r<3, D>;
|
||||
opcode_table_cb[0xdb] = &CPU::op_set_n_r<3, E>;
|
||||
opcode_table_cb[0xdc] = &CPU::op_set_n_r<3, H>;
|
||||
opcode_table_cb[0xdd] = &CPU::op_set_n_r<3, L>;
|
||||
opcode_table_cb[0xde] = &CPU::op_set_n_hl<3>;
|
||||
opcode_table_cb[0xdf] = &CPU::op_set_n_r<3, A>;
|
||||
opcode_table_cb[0xe0] = &CPU::op_set_n_r<4, B>;
|
||||
opcode_table_cb[0xe1] = &CPU::op_set_n_r<4, C>;
|
||||
opcode_table_cb[0xe2] = &CPU::op_set_n_r<4, D>;
|
||||
opcode_table_cb[0xe3] = &CPU::op_set_n_r<4, E>;
|
||||
opcode_table_cb[0xe4] = &CPU::op_set_n_r<4, H>;
|
||||
opcode_table_cb[0xe5] = &CPU::op_set_n_r<4, L>;
|
||||
opcode_table_cb[0xe6] = &CPU::op_set_n_hl<4>;
|
||||
opcode_table_cb[0xe7] = &CPU::op_set_n_r<4, A>;
|
||||
opcode_table_cb[0xe8] = &CPU::op_set_n_r<5, B>;
|
||||
opcode_table_cb[0xe9] = &CPU::op_set_n_r<5, C>;
|
||||
opcode_table_cb[0xea] = &CPU::op_set_n_r<5, D>;
|
||||
opcode_table_cb[0xeb] = &CPU::op_set_n_r<5, E>;
|
||||
opcode_table_cb[0xec] = &CPU::op_set_n_r<5, H>;
|
||||
opcode_table_cb[0xed] = &CPU::op_set_n_r<5, L>;
|
||||
opcode_table_cb[0xee] = &CPU::op_set_n_hl<5>;
|
||||
opcode_table_cb[0xef] = &CPU::op_set_n_r<5, A>;
|
||||
opcode_table_cb[0xf0] = &CPU::op_set_n_r<6, B>;
|
||||
opcode_table_cb[0xf1] = &CPU::op_set_n_r<6, C>;
|
||||
opcode_table_cb[0xf2] = &CPU::op_set_n_r<6, D>;
|
||||
opcode_table_cb[0xf3] = &CPU::op_set_n_r<6, E>;
|
||||
opcode_table_cb[0xf4] = &CPU::op_set_n_r<6, H>;
|
||||
opcode_table_cb[0xf5] = &CPU::op_set_n_r<6, L>;
|
||||
opcode_table_cb[0xf6] = &CPU::op_set_n_hl<6>;
|
||||
opcode_table_cb[0xf7] = &CPU::op_set_n_r<6, A>;
|
||||
opcode_table_cb[0xf8] = &CPU::op_set_n_r<7, B>;
|
||||
opcode_table_cb[0xf9] = &CPU::op_set_n_r<7, C>;
|
||||
opcode_table_cb[0xfa] = &CPU::op_set_n_r<7, D>;
|
||||
opcode_table_cb[0xfb] = &CPU::op_set_n_r<7, E>;
|
||||
opcode_table_cb[0xfc] = &CPU::op_set_n_r<7, H>;
|
||||
opcode_table_cb[0xfd] = &CPU::op_set_n_r<7, L>;
|
||||
opcode_table_cb[0xfe] = &CPU::op_set_n_hl<7>;
|
||||
opcode_table_cb[0xff] = &CPU::op_set_n_r<7, A>;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+156
@@ -0,0 +1,156 @@
|
||||
#include <gameboy/gameboy.hpp>
|
||||
|
||||
#define CPU_CPP
|
||||
namespace GameBoy {
|
||||
|
||||
#include "core/core.cpp"
|
||||
#include "mmio/mmio.cpp"
|
||||
#include "timing/timing.cpp"
|
||||
#include "serialization.cpp"
|
||||
CPU cpu;
|
||||
|
||||
void CPU::Main() {
|
||||
cpu.main();
|
||||
}
|
||||
|
||||
void CPU::main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::CPU) {
|
||||
scheduler.sync = Scheduler::SynchronizeMode::All;
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(trace) print(disassemble(r[PC]), "\n");
|
||||
interrupt_test();
|
||||
uint8 opcode = op_read(r[PC]++);
|
||||
(this->*opcode_table[opcode])();
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::interrupt_raise(CPU::Interrupt id) {
|
||||
if(id == Interrupt::Vblank) {
|
||||
status.interrupt_request_vblank = 1;
|
||||
if(status.interrupt_enable_vblank) status.halt = false;
|
||||
}
|
||||
|
||||
if(id == Interrupt::Stat) {
|
||||
status.interrupt_request_stat = 1;
|
||||
if(status.interrupt_enable_stat) status.halt = false;
|
||||
}
|
||||
|
||||
if(id == Interrupt::Timer) {
|
||||
status.interrupt_request_timer = 1;
|
||||
if(status.interrupt_enable_timer) status.halt = false;
|
||||
}
|
||||
|
||||
if(id == Interrupt::Serial) {
|
||||
status.interrupt_request_serial = 1;
|
||||
if(status.interrupt_enable_serial) status.halt = false;
|
||||
}
|
||||
|
||||
if(id == Interrupt::Joypad) {
|
||||
status.interrupt_request_joypad = 1;
|
||||
if(status.interrupt_enable_joypad) status.halt = status.stop = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::interrupt_test() {
|
||||
if(status.ime) {
|
||||
if(status.interrupt_request_vblank && status.interrupt_enable_vblank) {
|
||||
status.interrupt_request_vblank = 0;
|
||||
return interrupt_exec(0x0040);
|
||||
}
|
||||
|
||||
if(status.interrupt_request_stat && status.interrupt_enable_stat) {
|
||||
status.interrupt_request_stat = 0;
|
||||
return interrupt_exec(0x0048);
|
||||
}
|
||||
|
||||
if(status.interrupt_request_timer && status.interrupt_enable_timer) {
|
||||
status.interrupt_request_timer = 0;
|
||||
return interrupt_exec(0x0050);
|
||||
}
|
||||
|
||||
if(status.interrupt_request_serial && status.interrupt_enable_serial) {
|
||||
status.interrupt_request_serial = 0;
|
||||
return interrupt_exec(0x0058);
|
||||
}
|
||||
|
||||
if(status.interrupt_request_joypad && status.interrupt_enable_joypad) {
|
||||
status.interrupt_request_joypad = 0;
|
||||
return interrupt_exec(0x0060);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::interrupt_exec(uint16 pc) {
|
||||
status.ime = 0;
|
||||
op_write(--r[SP], r[PC] >> 8);
|
||||
op_write(--r[SP], r[PC] >> 0);
|
||||
r[PC] = pc;
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void CPU::power() {
|
||||
create(Main, 4194304);
|
||||
|
||||
for(unsigned n = 0xc000; n <= 0xdfff; n++) bus.mmio[n] = this; //WRAM
|
||||
for(unsigned n = 0xe000; n <= 0xfdff; n++) bus.mmio[n] = this; //WRAM (mirror)
|
||||
for(unsigned n = 0xff00; n <= 0xff0f; n++) bus.mmio[n] = this; //MMIO
|
||||
for(unsigned n = 0xff80; n <= 0xffff; n++) bus.mmio[n] = this; //HRAM+IE
|
||||
|
||||
for(unsigned n = 0; n < 8192; n++) wram[n] = 0x00;
|
||||
for(unsigned n = 0; n < 128; n++) hram[n] = 0x00;
|
||||
|
||||
r[PC] = 0x0000;
|
||||
r[SP] = 0x0000;
|
||||
r[AF] = 0x0000;
|
||||
r[BC] = 0x0000;
|
||||
r[DE] = 0x0000;
|
||||
r[HL] = 0x0000;
|
||||
|
||||
status.clock = 0;
|
||||
status.halt = false;
|
||||
status.stop = false;
|
||||
status.ime = 0;
|
||||
|
||||
status.p15 = 0;
|
||||
status.p14 = 0;
|
||||
status.joyp = 0;
|
||||
status.mlt_req = 0;
|
||||
|
||||
status.serial_data = 0;
|
||||
status.serial_bits = 0;
|
||||
|
||||
status.serial_transfer = 0;
|
||||
status.serial_clock = 0;
|
||||
|
||||
status.div = 0;
|
||||
|
||||
status.tima = 0;
|
||||
|
||||
status.tma = 0;
|
||||
|
||||
status.timer_enable = 0;
|
||||
status.timer_clock = 0;
|
||||
|
||||
status.interrupt_request_joypad = 0;
|
||||
status.interrupt_request_serial = 0;
|
||||
status.interrupt_request_timer = 0;
|
||||
status.interrupt_request_stat = 0;
|
||||
status.interrupt_request_vblank = 0;
|
||||
|
||||
status.interrupt_enable_joypad = 0;
|
||||
status.interrupt_enable_serial = 0;
|
||||
status.interrupt_enable_timer = 0;
|
||||
status.interrupt_enable_stat = 0;
|
||||
status.interrupt_enable_vblank = 0;
|
||||
}
|
||||
|
||||
CPU::CPU() : trace(false) {
|
||||
initialize_opcode_table();
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
struct CPU : Processor, MMIO {
|
||||
#include "core/core.hpp"
|
||||
#include "mmio/mmio.hpp"
|
||||
#include "timing/timing.hpp"
|
||||
|
||||
bool trace;
|
||||
|
||||
enum class Interrupt : unsigned {
|
||||
Vblank,
|
||||
Stat,
|
||||
Timer,
|
||||
Serial,
|
||||
Joypad,
|
||||
};
|
||||
|
||||
struct Status {
|
||||
unsigned clock;
|
||||
bool halt;
|
||||
bool stop;
|
||||
bool ime;
|
||||
|
||||
//$ff00 JOYP
|
||||
bool p15;
|
||||
bool p14;
|
||||
uint8 joyp;
|
||||
uint8 mlt_req;
|
||||
|
||||
//$ff01 SB
|
||||
uint8 serial_data;
|
||||
unsigned serial_bits;
|
||||
|
||||
//$ff02 SC
|
||||
bool serial_transfer;
|
||||
bool serial_clock;
|
||||
|
||||
//$ff04 DIV
|
||||
uint8 div;
|
||||
|
||||
//$ff05 TIMA
|
||||
uint8 tima;
|
||||
|
||||
//$ff06 TMA
|
||||
uint8 tma;
|
||||
|
||||
//$ff07 TAC
|
||||
bool timer_enable;
|
||||
unsigned timer_clock;
|
||||
|
||||
//$ff0f IF
|
||||
bool interrupt_request_joypad;
|
||||
bool interrupt_request_serial;
|
||||
bool interrupt_request_timer;
|
||||
bool interrupt_request_stat;
|
||||
bool interrupt_request_vblank;
|
||||
|
||||
//$ffff IE
|
||||
bool interrupt_enable_joypad;
|
||||
bool interrupt_enable_serial;
|
||||
bool interrupt_enable_timer;
|
||||
bool interrupt_enable_stat;
|
||||
bool interrupt_enable_vblank;
|
||||
} status;
|
||||
|
||||
uint8 wram[8192];
|
||||
uint8 hram[128];
|
||||
|
||||
static void Main();
|
||||
void main();
|
||||
void interrupt_raise(Interrupt id);
|
||||
void interrupt_test();
|
||||
void interrupt_exec(uint16 pc);
|
||||
void power();
|
||||
|
||||
void serialize(serializer&);
|
||||
CPU();
|
||||
};
|
||||
|
||||
extern CPU cpu;
|
||||
Executable
+144
@@ -0,0 +1,144 @@
|
||||
#ifdef CPU_CPP
|
||||
|
||||
void CPU::mmio_joyp_poll() {
|
||||
unsigned button = 0, dpad = 0;
|
||||
|
||||
button |= system.interface->input_poll((unsigned)Input::Start) << 3;
|
||||
button |= system.interface->input_poll((unsigned)Input::Select) << 2;
|
||||
button |= system.interface->input_poll((unsigned)Input::B) << 1;
|
||||
button |= system.interface->input_poll((unsigned)Input::A) << 0;
|
||||
|
||||
dpad |= system.interface->input_poll((unsigned)Input::Down) << 3;
|
||||
dpad |= system.interface->input_poll((unsigned)Input::Up) << 2;
|
||||
dpad |= system.interface->input_poll((unsigned)Input::Left) << 1;
|
||||
dpad |= system.interface->input_poll((unsigned)Input::Right) << 0;
|
||||
|
||||
status.joyp = 0x0f;
|
||||
if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mlt_req;
|
||||
if(status.p15 == 0) status.joyp &= button ^ 0x0f;
|
||||
if(status.p14 == 0) status.joyp &= dpad ^ 0x0f;
|
||||
if(status.joyp != 0x0f) interrupt_raise(Interrupt::Joypad);
|
||||
}
|
||||
|
||||
uint8 CPU::mmio_read(uint16 addr) {
|
||||
if(addr >= 0xc000 && addr <= 0xdfff) return wram[addr & 0x1fff];
|
||||
if(addr >= 0xe000 && addr <= 0xfdff) return wram[addr & 0x1fff];
|
||||
if(addr >= 0xff80 && addr <= 0xfffe) return hram[addr & 0x7f];
|
||||
|
||||
if(addr == 0xff00) { //JOYP
|
||||
return (status.p15 << 5)
|
||||
| (status.p14 << 4)
|
||||
| (status.joyp << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xff01) { //SB
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
if(addr == 0xff02) { //SC
|
||||
return (status.serial_transfer << 7)
|
||||
| (status.serial_clock << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xff04) { //DIV
|
||||
return status.div;
|
||||
}
|
||||
|
||||
if(addr == 0xff05) { //TIMA
|
||||
return status.tima;
|
||||
}
|
||||
|
||||
if(addr == 0xff06) { //TMA
|
||||
return status.tma;
|
||||
}
|
||||
|
||||
if(addr == 0xff07) { //TAC
|
||||
return (status.timer_enable << 2)
|
||||
| (status.timer_clock << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xff0f) { //IF
|
||||
return (status.interrupt_request_joypad << 4)
|
||||
| (status.interrupt_request_serial << 3)
|
||||
| (status.interrupt_request_timer << 2)
|
||||
| (status.interrupt_request_stat << 1)
|
||||
| (status.interrupt_request_vblank << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xffff) { //IE
|
||||
return (status.interrupt_enable_joypad << 4)
|
||||
| (status.interrupt_enable_serial << 3)
|
||||
| (status.interrupt_enable_timer << 2)
|
||||
| (status.interrupt_enable_stat << 1)
|
||||
| (status.interrupt_enable_vblank << 0);
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void CPU::mmio_write(uint16 addr, uint8 data) {
|
||||
if(addr >= 0xc000 && addr <= 0xdfff) { wram[addr & 0x1fff] = data; return; }
|
||||
if(addr >= 0xe000 && addr <= 0xfdff) { wram[addr & 0x1fff] = data; return; }
|
||||
if(addr >= 0xff80 && addr <= 0xfffe) { hram[addr & 0x7f] = data; return; }
|
||||
|
||||
if(addr == 0xff00) { //JOYP
|
||||
status.p15 = data & 0x20;
|
||||
status.p14 = data & 0x10;
|
||||
system.interface->joyp_write(status.p15, status.p14);
|
||||
mmio_joyp_poll();
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff01) { //SB
|
||||
status.serial_data = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff02) { //SC
|
||||
status.serial_transfer = data & 0x80;
|
||||
status.serial_clock = data & 0x01;
|
||||
if(status.serial_transfer) status.serial_bits = 8;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff04) { //DIV
|
||||
status.div = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff05) { //TIMA
|
||||
status.tima = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff06) { //TMA
|
||||
status.tma = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff07) { //TAC
|
||||
status.timer_enable = data & 0x04;
|
||||
status.timer_clock = data & 0x03;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff0f) { //IF
|
||||
status.interrupt_request_joypad = data & 0x10;
|
||||
status.interrupt_request_serial = data & 0x08;
|
||||
status.interrupt_request_timer = data & 0x04;
|
||||
status.interrupt_request_stat = data & 0x02;
|
||||
status.interrupt_request_vblank = data & 0x01;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xffff) { //IE
|
||||
status.interrupt_enable_joypad = data & 0x10;
|
||||
status.interrupt_enable_serial = data & 0x08;
|
||||
status.interrupt_enable_timer = data & 0x04;
|
||||
status.interrupt_enable_stat = data & 0x02;
|
||||
status.interrupt_enable_vblank = data & 0x01;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
void mmio_joyp_poll();
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#ifdef CPU_CPP
|
||||
|
||||
void CPU::serialize(serializer &s) {
|
||||
s.array(wram);
|
||||
s.array(hram);
|
||||
|
||||
s.integer(r.a.data);
|
||||
s.integer(r.f.z);
|
||||
s.integer(r.f.n);
|
||||
s.integer(r.f.h);
|
||||
s.integer(r.f.c);
|
||||
s.integer(r.b.data);
|
||||
s.integer(r.c.data);
|
||||
s.integer(r.d.data);
|
||||
s.integer(r.e.data);
|
||||
s.integer(r.h.data);
|
||||
s.integer(r.l.data);
|
||||
s.integer(r.sp.data);
|
||||
s.integer(r.pc.data);
|
||||
|
||||
s.integer(status.clock);
|
||||
s.integer(status.halt);
|
||||
s.integer(status.stop);
|
||||
s.integer(status.ime);
|
||||
|
||||
s.integer(status.p15);
|
||||
s.integer(status.p14);
|
||||
s.integer(status.joyp);
|
||||
s.integer(status.mlt_req);
|
||||
|
||||
s.integer(status.serial_data);
|
||||
s.integer(status.serial_bits);
|
||||
|
||||
s.integer(status.serial_transfer);
|
||||
s.integer(status.serial_clock);
|
||||
|
||||
s.integer(status.div);
|
||||
s.integer(status.tima);
|
||||
s.integer(status.tma);
|
||||
s.integer(status.timer_enable);
|
||||
s.integer(status.timer_clock);
|
||||
|
||||
s.integer(status.interrupt_request_joypad);
|
||||
s.integer(status.interrupt_request_serial);
|
||||
s.integer(status.interrupt_request_timer);
|
||||
s.integer(status.interrupt_request_stat);
|
||||
s.integer(status.interrupt_request_vblank);
|
||||
|
||||
s.integer(status.interrupt_enable_joypad);
|
||||
s.integer(status.interrupt_enable_serial);
|
||||
s.integer(status.interrupt_enable_timer);
|
||||
s.integer(status.interrupt_enable_stat);
|
||||
s.integer(status.interrupt_enable_vblank);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#ifdef CPU_CPP
|
||||
|
||||
void CPU::op_io() {
|
||||
add_clocks(4);
|
||||
}
|
||||
|
||||
uint8 CPU::op_read(uint16 addr) {
|
||||
uint8 r = bus.read(addr);
|
||||
add_clocks(4);
|
||||
return r;
|
||||
}
|
||||
|
||||
void CPU::op_write(uint16 addr, uint8 data) {
|
||||
bus.write(addr, data);
|
||||
add_clocks(4);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
//4194304hz (4 * 1024 * 1024)
|
||||
|
||||
//70224 clocks/frame
|
||||
// 456 clocks/scanline
|
||||
// 154 scanlines/frame
|
||||
|
||||
#ifdef CPU_CPP
|
||||
|
||||
#include "opcode.cpp"
|
||||
|
||||
void CPU::add_clocks(unsigned clocks) {
|
||||
system.clocks_executed += clocks;
|
||||
scheduler.exit(Scheduler::ExitReason::StepEvent);
|
||||
|
||||
status.clock += clocks;
|
||||
if(status.clock >= 4194304) {
|
||||
status.clock -= 4194304;
|
||||
cartridge.mbc3.second();
|
||||
}
|
||||
|
||||
//4194304 / N(hz) - 1 = mask
|
||||
if((status.clock & 15) == 0) timer_262144hz();
|
||||
if((status.clock & 63) == 0) timer_65536hz();
|
||||
if((status.clock & 255) == 0) timer_16384hz();
|
||||
if((status.clock & 511) == 0) timer_8192hz();
|
||||
if((status.clock & 1023) == 0) timer_4096hz();
|
||||
|
||||
lcd.clock -= clocks;
|
||||
if(lcd.clock <= 0) co_switch(scheduler.active_thread = lcd.thread);
|
||||
|
||||
apu.clock -= clocks;
|
||||
if(apu.clock <= 0) co_switch(scheduler.active_thread = apu.thread);
|
||||
}
|
||||
|
||||
void CPU::timer_262144hz() {
|
||||
if(status.timer_enable && status.timer_clock == 1) {
|
||||
if(++status.tima == 0) {
|
||||
status.tima = status.tma;
|
||||
interrupt_raise(Interrupt::Timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::timer_65536hz() {
|
||||
if(status.timer_enable && status.timer_clock == 2) {
|
||||
if(++status.tima == 0) {
|
||||
status.tima = status.tma;
|
||||
interrupt_raise(Interrupt::Timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::timer_16384hz() {
|
||||
if(status.timer_enable && status.timer_clock == 3) {
|
||||
if(++status.tima == 0) {
|
||||
status.tima = status.tma;
|
||||
interrupt_raise(Interrupt::Timer);
|
||||
}
|
||||
}
|
||||
|
||||
status.div++;
|
||||
}
|
||||
|
||||
void CPU::timer_8192hz() {
|
||||
if(status.serial_transfer && status.serial_clock) {
|
||||
if(--status.serial_bits == 0) {
|
||||
status.serial_transfer = 0;
|
||||
interrupt_raise(Interrupt::Serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPU::timer_4096hz() {
|
||||
if(status.timer_enable && status.timer_clock == 0) {
|
||||
if(++status.tima == 0) {
|
||||
status.tima = status.tma;
|
||||
interrupt_raise(Interrupt::Timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
void add_clocks(unsigned clocks);
|
||||
void timer_262144hz();
|
||||
void timer_65536hz();
|
||||
void timer_16384hz();
|
||||
void timer_8192hz();
|
||||
void timer_4096hz();
|
||||
|
||||
//opcode.cpp
|
||||
void op_io();
|
||||
uint8 op_read(uint16 addr);
|
||||
void op_write(uint16 addr, uint8 data);
|
||||
Executable
+96
@@ -0,0 +1,96 @@
|
||||
//bgameboy
|
||||
//author: byuu
|
||||
//project started: 2010-12-27
|
||||
|
||||
namespace GameBoy {
|
||||
namespace Info {
|
||||
static const char Name[] = "bgameboy";
|
||||
static const char Version[] = "000.19";
|
||||
static unsigned SerializerVersion = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#include <libco/libco.h>
|
||||
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/property.hpp>
|
||||
#include <nall/random.hpp>
|
||||
#include <nall/serializer.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/varint.hpp>
|
||||
using namespace nall;
|
||||
|
||||
namespace GameBoy {
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
typedef uint_t< 1> uint1;
|
||||
typedef uint_t< 2> uint2;
|
||||
typedef uint_t< 3> uint3;
|
||||
typedef uint_t< 4> uint4;
|
||||
typedef uint_t< 5> uint5;
|
||||
typedef uint_t< 6> uint6;
|
||||
typedef uint_t< 7> uint7;
|
||||
|
||||
typedef uint_t< 9> uint9;
|
||||
typedef uint_t<10> uint10;
|
||||
typedef uint_t<11> uint11;
|
||||
typedef uint_t<12> uint12;
|
||||
typedef uint_t<13> uint13;
|
||||
typedef uint_t<14> uint14;
|
||||
typedef uint_t<15> uint15;
|
||||
|
||||
typedef uint_t<17> uint17;
|
||||
typedef uint_t<18> uint18;
|
||||
typedef uint_t<19> uint19;
|
||||
typedef uint_t<20> uint20;
|
||||
typedef uint_t<21> uint21;
|
||||
typedef uint_t<22> uint22;
|
||||
typedef uint_t<23> uint23;
|
||||
typedef uint_t<24> uint24;
|
||||
typedef uint_t<25> uint25;
|
||||
typedef uint_t<26> uint26;
|
||||
typedef uint_t<27> uint27;
|
||||
typedef uint_t<28> uint28;
|
||||
typedef uint_t<29> uint29;
|
||||
typedef uint_t<30> uint30;
|
||||
typedef uint_t<31> uint31;
|
||||
|
||||
template<uint16 lo, uint16 hi>
|
||||
alwaysinline bool within(uint16 addr) {
|
||||
static const uint16 mask = ~(hi ^ lo);
|
||||
return (addr & mask) == lo;
|
||||
}
|
||||
|
||||
struct Processor {
|
||||
cothread_t thread;
|
||||
unsigned frequency;
|
||||
int64 clock;
|
||||
|
||||
inline void create(void (*entrypoint_)(), unsigned frequency_) {
|
||||
if(thread) co_delete(thread);
|
||||
thread = co_create(65536 * sizeof(void*), entrypoint_);
|
||||
frequency = frequency_;
|
||||
clock = 0;
|
||||
}
|
||||
|
||||
inline Processor() : thread(0) {}
|
||||
};
|
||||
|
||||
#include <gameboy/memory/memory.hpp>
|
||||
#include <gameboy/system/system.hpp>
|
||||
#include <gameboy/scheduler/scheduler.hpp>
|
||||
#include <gameboy/cartridge/cartridge.hpp>
|
||||
#include <gameboy/cpu/cpu.hpp>
|
||||
#include <gameboy/apu/apu.hpp>
|
||||
#include <gameboy/lcd/lcd.hpp>
|
||||
};
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
class Interface {
|
||||
public:
|
||||
virtual void lcd_scanline() {}
|
||||
virtual void joyp_write(bool p15, bool p14) {}
|
||||
|
||||
virtual void video_refresh(const uint8_t *data) {}
|
||||
virtual void audio_sample(int16_t center, int16_t left, int16_t right) {}
|
||||
virtual void input_poll() {}
|
||||
virtual bool input_poll(unsigned id) {}
|
||||
|
||||
virtual void message(const string &text) { print(text, "\n"); }
|
||||
};
|
||||
Executable
+239
@@ -0,0 +1,239 @@
|
||||
#include <gameboy/gameboy.hpp>
|
||||
|
||||
#define LCD_CPP
|
||||
namespace GameBoy {
|
||||
|
||||
#include "mmio/mmio.cpp"
|
||||
#include "serialization.cpp"
|
||||
LCD lcd;
|
||||
|
||||
void LCD::Main() {
|
||||
lcd.main();
|
||||
}
|
||||
|
||||
void LCD::main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
add_clocks(4);
|
||||
|
||||
if(status.lx == 0) {
|
||||
if(status.interrupt_oam) cpu.interrupt_raise(CPU::Interrupt::Stat);
|
||||
}
|
||||
|
||||
if(status.lx == 252) {
|
||||
if(status.interrupt_hblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LCD::add_clocks(unsigned clocks) {
|
||||
status.lx += clocks;
|
||||
if(status.lx >= 456) scanline();
|
||||
|
||||
clock += clocks;
|
||||
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) {
|
||||
co_switch(scheduler.active_thread = cpu.thread);
|
||||
}
|
||||
}
|
||||
|
||||
void LCD::scanline() {
|
||||
status.lx -= 456;
|
||||
if(++status.ly == 154) frame();
|
||||
|
||||
if(status.interrupt_lyc == true) {
|
||||
if(status.ly == status.lyc) cpu.interrupt_raise(CPU::Interrupt::Stat);
|
||||
}
|
||||
|
||||
if(status.ly < 144) render();
|
||||
|
||||
if(status.ly == 144) {
|
||||
cpu.interrupt_raise(CPU::Interrupt::Vblank);
|
||||
if(status.interrupt_vblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
|
||||
}
|
||||
}
|
||||
|
||||
void LCD::frame() {
|
||||
system.interface->video_refresh(screen);
|
||||
system.interface->input_poll();
|
||||
cpu.mmio_joyp_poll();
|
||||
|
||||
status.ly = 0;
|
||||
scheduler.exit(Scheduler::ExitReason::FrameEvent);
|
||||
}
|
||||
|
||||
void LCD::render() {
|
||||
for(unsigned n = 0; n < 160; n++) line[n] = 0x00;
|
||||
|
||||
if(status.display_enable == true) {
|
||||
if(status.bg_enable == true) render_bg();
|
||||
if(status.window_display_enable == true) render_window();
|
||||
if(status.obj_enable == true) render_obj();
|
||||
}
|
||||
|
||||
uint8_t *output = screen + status.ly * 160;
|
||||
for(unsigned n = 0; n < 160; n++) output[n] = (3 - line[n]) * 0x55;
|
||||
system.interface->lcd_scanline();
|
||||
}
|
||||
|
||||
uint16 LCD::read_tile(bool select, unsigned x, unsigned y) {
|
||||
unsigned tmaddr = 0x1800 + (select << 10), tdaddr;
|
||||
tmaddr += (((y >> 3) << 5) + (x >> 3)) & 0x03ff;
|
||||
if(status.bg_tiledata_select == 0) {
|
||||
tdaddr = 0x1000 + ((int8)vram[tmaddr] << 4);
|
||||
} else {
|
||||
tdaddr = 0x0000 + (vram[tmaddr] << 4);
|
||||
}
|
||||
tdaddr += (y & 7) << 1;
|
||||
return (vram[tdaddr + 0] << 0) | (vram[tdaddr + 1] << 8);
|
||||
}
|
||||
|
||||
void LCD::render_bg() {
|
||||
unsigned iy = (status.ly + status.scy) & 255;
|
||||
unsigned ix = status.scx, tx = ix & 7;
|
||||
unsigned data = read_tile(status.bg_tilemap_select, ix, iy);
|
||||
|
||||
for(unsigned ox = 0; ox < 160; ox++) {
|
||||
uint8 palette = ((data & (0x0080 >> tx)) ? 1 : 0)
|
||||
| ((data & (0x8000 >> tx)) ? 2 : 0);
|
||||
line[ox] = status.bgp[palette];
|
||||
|
||||
ix = (ix + 1) & 255;
|
||||
tx = (tx + 1) & 7;
|
||||
|
||||
if(tx == 0) data = read_tile(status.bg_tilemap_select, ix, iy);
|
||||
}
|
||||
}
|
||||
|
||||
void LCD::render_window() {
|
||||
if(status.ly - status.wy >= 144U) return;
|
||||
unsigned iy = status.ly - status.wy;
|
||||
unsigned ix = (status.wx - 7) & 255, tx = ix & 7;
|
||||
unsigned data = read_tile(status.window_tilemap_select, ix, iy);
|
||||
|
||||
for(unsigned ox = 0; ox < 160; ox++) {
|
||||
uint8 palette = ((data & (0x0080 >> tx)) ? 1 : 0)
|
||||
| ((data & (0x8000 >> tx)) ? 2 : 0);
|
||||
if(ox - (status.wx - 7) < 160U) line[ox] = status.bgp[palette];
|
||||
|
||||
ix = (ix + 1) & 255;
|
||||
tx = (tx + 1) & 7;
|
||||
|
||||
if(tx == 0) data = read_tile(status.window_tilemap_select, ix, iy);
|
||||
}
|
||||
}
|
||||
|
||||
void LCD::render_obj() {
|
||||
unsigned obj_size = (status.obj_size == 0 ? 8 : 16);
|
||||
|
||||
unsigned sprite[10], sprites = 0;
|
||||
|
||||
//find first ten sprites on this scanline
|
||||
for(unsigned s = 0; s < 40; s++) {
|
||||
unsigned sy = oam[(s << 2) + 0] - 16;
|
||||
unsigned sx = oam[(s << 2) + 1] - 8;
|
||||
|
||||
sy = status.ly - sy;
|
||||
if(sy >= obj_size) continue;
|
||||
|
||||
sprite[sprites++] = s;
|
||||
if(sprites == 10) break;
|
||||
}
|
||||
|
||||
//sort by X-coordinate, when equal, lower address comes first
|
||||
for(unsigned x = 0; x < sprites; x++) {
|
||||
for(unsigned y = x + 1; y < sprites; y++) {
|
||||
signed sx = oam[(sprite[x] << 2) + 1] - 8;
|
||||
signed sy = oam[(sprite[y] << 2) + 1] - 8;
|
||||
if(sy < sx) {
|
||||
sprite[x] ^= sprite[y];
|
||||
sprite[y] ^= sprite[x];
|
||||
sprite[x] ^= sprite[y];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//render backwards, so that first sprite has highest priority
|
||||
for(signed s = sprites - 1; s >= 0; s--) {
|
||||
unsigned n = sprite[s] << 2;
|
||||
unsigned sy = oam[n + 0] - 16;
|
||||
unsigned sx = oam[n + 1] - 8;
|
||||
unsigned tile = oam[n + 2];
|
||||
unsigned attribute = oam[n + 3];
|
||||
|
||||
sy = status.ly - sy;
|
||||
if(sy >= obj_size) continue;
|
||||
if(attribute & 0x40) sy ^= (obj_size - 1);
|
||||
|
||||
unsigned tdaddr = (tile << 4) + (sy << 1);
|
||||
uint8 d0 = vram[tdaddr + 0];
|
||||
uint8 d1 = vram[tdaddr + 1];
|
||||
unsigned xflip = attribute & 0x20 ? 7 : 0;
|
||||
|
||||
for(unsigned tx = 0; tx < 8; tx++) {
|
||||
uint8 palette = ((d0 & (0x80 >> tx)) ? 1 : 0)
|
||||
| ((d1 & (0x80 >> tx)) ? 2 : 0);
|
||||
if(palette == 0) continue;
|
||||
|
||||
palette = status.obp[(bool)(attribute & 0x10)][palette];
|
||||
unsigned ox = sx + (tx ^ xflip);
|
||||
|
||||
if(ox <= 159) {
|
||||
if(attribute & 0x80) {
|
||||
if(line[ox] > 0) continue;
|
||||
}
|
||||
line[ox] = palette;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LCD::power() {
|
||||
create(Main, 4194304);
|
||||
|
||||
for(unsigned n = 0x8000; n <= 0x9fff; n++) bus.mmio[n] = this; //VRAM
|
||||
for(unsigned n = 0xff40; n <= 0xff4b; n++) bus.mmio[n] = this; //MMIO
|
||||
for(unsigned n = 0xfe00; n <= 0xfe9f; n++) bus.mmio[n] = this; //OAM
|
||||
|
||||
for(unsigned n = 0; n < 8192; n++) vram[n] = 0x00;
|
||||
for(unsigned n = 0; n < 160; n++) oam [n] = 0x00;
|
||||
|
||||
for(unsigned n = 0; n < 160 * 144; n++) screen[n] = 0x00;
|
||||
|
||||
status.lx = 0;
|
||||
|
||||
status.display_enable = 0;
|
||||
status.window_tilemap_select = 0;
|
||||
status.window_display_enable = 0;
|
||||
status.bg_tiledata_select = 0;
|
||||
status.bg_tilemap_select = 0;
|
||||
status.obj_size = 0;
|
||||
status.obj_enable = 0;
|
||||
status.bg_enable = 0;
|
||||
|
||||
status.interrupt_lyc = 0;
|
||||
status.interrupt_oam = 0;
|
||||
status.interrupt_vblank = 0;
|
||||
status.interrupt_hblank = 0;
|
||||
|
||||
status.scy = 0;
|
||||
status.scx = 0;
|
||||
status.ly = 0;
|
||||
status.lyc = 0;
|
||||
|
||||
for(unsigned n = 0; n < 4; n++) {
|
||||
status.bgp[n] = n;
|
||||
status.obp[0][n] = n;
|
||||
status.obp[1][n] = n;
|
||||
}
|
||||
|
||||
status.wy = 0;
|
||||
status.wx = 0;
|
||||
}
|
||||
|
||||
LCD::LCD() {
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
struct LCD : Processor, MMIO {
|
||||
#include "mmio/mmio.hpp"
|
||||
|
||||
struct Status {
|
||||
unsigned lx;
|
||||
|
||||
//$ff40 LCDC
|
||||
bool display_enable;
|
||||
bool window_tilemap_select;
|
||||
bool window_display_enable;
|
||||
bool bg_tiledata_select;
|
||||
bool bg_tilemap_select;
|
||||
bool obj_size;
|
||||
bool obj_enable;
|
||||
bool bg_enable;
|
||||
|
||||
//$ff41 STAT
|
||||
bool interrupt_lyc;
|
||||
bool interrupt_oam;
|
||||
bool interrupt_vblank;
|
||||
bool interrupt_hblank;
|
||||
|
||||
//$ff42 SCY
|
||||
uint8 scy;
|
||||
|
||||
//$ff43 SCX
|
||||
uint8 scx;
|
||||
|
||||
//$ff44 LY
|
||||
uint8 ly;
|
||||
|
||||
//$ff45 LYC
|
||||
uint8 lyc;
|
||||
|
||||
//$ff47 BGP
|
||||
uint8 bgp[4];
|
||||
|
||||
//$ff48 OBP0
|
||||
//$ff49 OBP1
|
||||
uint8 obp[2][4];
|
||||
|
||||
//$ff4a WY
|
||||
uint8 wy;
|
||||
|
||||
//$ff4b WX
|
||||
uint8 wx;
|
||||
} status;
|
||||
|
||||
uint8 screen[160 * 144];
|
||||
uint8 vram[8192];
|
||||
uint8 oam[160];
|
||||
uint8 line[160];
|
||||
|
||||
static void Main();
|
||||
void main();
|
||||
void add_clocks(unsigned clocks);
|
||||
void scanline();
|
||||
void frame();
|
||||
void render();
|
||||
uint16 read_tile(bool select, unsigned x, unsigned y);
|
||||
void render_bg();
|
||||
void render_window();
|
||||
void render_obj();
|
||||
|
||||
void power();
|
||||
|
||||
void serialize(serializer&);
|
||||
LCD();
|
||||
};
|
||||
|
||||
extern LCD lcd;
|
||||
Executable
+165
@@ -0,0 +1,165 @@
|
||||
#ifdef LCD_CPP
|
||||
|
||||
uint8 LCD::mmio_read(uint16 addr) {
|
||||
if(addr >= 0x8000 && addr <= 0x9fff) return vram[addr & 0x1fff];
|
||||
if(addr >= 0xfe00 && addr <= 0xfe9f) return oam[addr & 0xff];
|
||||
|
||||
if(addr == 0xff40) { //LCDC
|
||||
return (status.display_enable << 7)
|
||||
| (status.window_tilemap_select << 6)
|
||||
| (status.window_display_enable << 5)
|
||||
| (status.bg_tiledata_select << 4)
|
||||
| (status.bg_tilemap_select << 3)
|
||||
| (status.obj_size << 2)
|
||||
| (status.obj_enable << 1)
|
||||
| (status.bg_enable << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xff41) { //STAT
|
||||
unsigned mode;
|
||||
if(status.ly >= 144) mode = 1; //Vblank
|
||||
else if(status.lx < 80) mode = 2; //OAM
|
||||
else if(status.lx < 252) mode = 3; //LCD
|
||||
else mode = 0; //Hblank
|
||||
|
||||
return (status.interrupt_lyc << 6)
|
||||
| (status.interrupt_oam << 5)
|
||||
| (status.interrupt_vblank << 4)
|
||||
| (status.interrupt_hblank << 3)
|
||||
| ((status.ly == status.lyc) << 2)
|
||||
| (mode << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xff42) { //SCY
|
||||
return status.scy;
|
||||
}
|
||||
|
||||
if(addr == 0xff43) { //SCX
|
||||
return status.scx;
|
||||
}
|
||||
|
||||
if(addr == 0xff44) { //LY
|
||||
return status.ly;
|
||||
}
|
||||
|
||||
if(addr == 0xff45) { //LYC
|
||||
return status.lyc;
|
||||
}
|
||||
|
||||
if(addr == 0xff47) { //BGP
|
||||
return (status.bgp[3] << 6)
|
||||
| (status.bgp[2] << 4)
|
||||
| (status.bgp[1] << 2)
|
||||
| (status.bgp[0] << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xff48) { //OBP0
|
||||
return (status.obp[0][3] << 6)
|
||||
| (status.obp[0][2] << 4)
|
||||
| (status.obp[0][1] << 2)
|
||||
| (status.obp[0][0] << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xff49) { //OBP1
|
||||
return (status.obp[1][3] << 6)
|
||||
| (status.obp[1][2] << 4)
|
||||
| (status.obp[1][1] << 2)
|
||||
| (status.obp[1][0] << 0);
|
||||
}
|
||||
|
||||
if(addr == 0xff4a) { //WY
|
||||
return status.wy;
|
||||
}
|
||||
|
||||
if(addr == 0xff4b) { //WX
|
||||
return status.wx;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void LCD::mmio_write(uint16 addr, uint8 data) {
|
||||
if(addr >= 0x8000 && addr <= 0x9fff) { vram[addr & 0x1fff] = data; return; }
|
||||
if(addr >= 0xfe00 && addr <= 0xfe9f) { oam[addr & 0xff] = data; return; }
|
||||
|
||||
if(addr == 0xff40) { //LCDC
|
||||
status.display_enable = data & 0x80;
|
||||
status.window_tilemap_select = data & 0x40;
|
||||
status.window_display_enable = data & 0x20;
|
||||
status.bg_tiledata_select = data & 0x10;
|
||||
status.bg_tilemap_select = data & 0x08;
|
||||
status.obj_size = data & 0x04;
|
||||
status.obj_enable = data & 0x02;
|
||||
status.bg_enable = data & 0x01;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff41) { //STAT
|
||||
status.interrupt_lyc = data & 0x40;
|
||||
status.interrupt_oam = data & 0x20;
|
||||
status.interrupt_vblank = data & 0x10;
|
||||
status.interrupt_hblank = data & 0x08;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff42) { //SCY
|
||||
status.scy = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff43) { //SCX
|
||||
status.scx = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff44) { //LY
|
||||
status.ly = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff45) { //LYC
|
||||
status.lyc = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff46) { //DMA
|
||||
for(unsigned n = 0x00; n <= 0x9f; n++) bus.write(0xfe00 + n, bus.read((data << 8) + n));
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff47) { //BGP
|
||||
status.bgp[3] = (data >> 6) & 3;
|
||||
status.bgp[2] = (data >> 4) & 3;
|
||||
status.bgp[1] = (data >> 2) & 3;
|
||||
status.bgp[0] = (data >> 0) & 3;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff48) { //OBP0
|
||||
status.obp[0][3] = (data >> 6) & 3;
|
||||
status.obp[0][2] = (data >> 4) & 3;
|
||||
status.obp[0][1] = (data >> 2) & 3;
|
||||
status.obp[0][0] = (data >> 0) & 3;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff49) { //OBP1
|
||||
status.obp[1][3] = (data >> 6) & 3;
|
||||
status.obp[1][2] = (data >> 4) & 3;
|
||||
status.obp[1][1] = (data >> 2) & 3;
|
||||
status.obp[1][0] = (data >> 0) & 3;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff4a) { //WY
|
||||
status.wy = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0xff4b) { //WX
|
||||
status.wx = data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#ifdef LCD_CPP
|
||||
|
||||
void LCD::serialize(serializer &s) {
|
||||
s.integer(status.lx);
|
||||
|
||||
s.integer(status.display_enable);
|
||||
s.integer(status.window_tilemap_select);
|
||||
s.integer(status.window_display_enable);
|
||||
s.integer(status.bg_tiledata_select);
|
||||
s.integer(status.bg_tilemap_select);
|
||||
s.integer(status.obj_size);
|
||||
s.integer(status.obj_enable);
|
||||
s.integer(status.bg_enable);
|
||||
|
||||
s.integer(status.interrupt_lyc);
|
||||
s.integer(status.interrupt_oam);
|
||||
s.integer(status.interrupt_vblank);
|
||||
s.integer(status.interrupt_hblank);
|
||||
|
||||
s.integer(status.scy);
|
||||
s.integer(status.scx);
|
||||
s.integer(status.ly);
|
||||
s.integer(status.lyc);
|
||||
|
||||
s.array(status.bgp);
|
||||
s.array(status.obp[0]);
|
||||
s.array(status.obp[1]);
|
||||
|
||||
s.integer(status.wy);
|
||||
s.integer(status.wx);
|
||||
|
||||
s.array(screen);
|
||||
s.array(vram);
|
||||
s.array(oam);
|
||||
s.array(line);
|
||||
}
|
||||
|
||||
#endif
|
||||
Loaded 100 of 1084 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user