mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-12 11:22:59 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f7cf1bd31 | ||
|
|
8751bc433f | ||
|
|
afbee40bc0 | ||
|
|
81e9be64d2 | ||
|
|
0cd4972d11 | ||
|
|
938609818f | ||
|
|
487491e6f2 | ||
|
|
a6ccc7e5d2 | ||
|
|
39dd39cc09 | ||
|
|
1a017ff697 | ||
|
|
591adfcb25 |
No files matched your search
@@ -1,3 +0,0 @@
|
||||
purify/*.o
|
||||
purify/purify
|
||||
purify/analyze-gba
|
||||
Executable → Regular
+43
-100
@@ -1,100 +1,43 @@
|
||||
include nall/Makefile
|
||||
|
||||
fc := fc
|
||||
sfc := sfc
|
||||
gb := gb
|
||||
gba := gba
|
||||
|
||||
profile := accuracy
|
||||
target := ethos
|
||||
|
||||
# options += console
|
||||
|
||||
# compiler
|
||||
c := $(compiler) -std=gnu99
|
||||
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||
flags := -I. -O3 -fomit-frame-pointer
|
||||
link := -s
|
||||
objects := libco
|
||||
|
||||
# profile-guided optimization mode
|
||||
# pgo := instrument
|
||||
# pgo := optimize
|
||||
|
||||
ifeq ($(pgo),instrument)
|
||||
flags += -fprofile-generate
|
||||
link += -lgcov
|
||||
else ifeq ($(pgo),optimize)
|
||||
flags += -fprofile-use
|
||||
endif
|
||||
|
||||
# platform
|
||||
ifeq ($(platform),x)
|
||||
flags += -march=native
|
||||
link += -ldl -lX11 -lXext
|
||||
else ifeq ($(platform),osx)
|
||||
else ifeq ($(platform),win)
|
||||
link += $(if $(findstring console,$(options)),-mconsole,-mwindows)
|
||||
link += -mthreads -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32
|
||||
link += -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
||||
else
|
||||
unknown_platform: help;
|
||||
endif
|
||||
|
||||
ui := target-$(target)
|
||||
|
||||
# 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
|
||||
flags := $(flags) $(foreach o,$(call strupper,$(options)),-D$o)
|
||||
|
||||
# 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)
|
||||
|
||||
sync:
|
||||
if [ -d ./libco ]; then rm -r ./libco; fi
|
||||
if [ -d ./nall ]; then rm -r ./nall; fi
|
||||
if [ -d ./ruby ]; then rm -r ./ruby; fi
|
||||
if [ -d ./phoenix ]; then rm -r ./phoenix; fi
|
||||
cp -r ../libco ./libco
|
||||
cp -r ../nall ./nall
|
||||
cp -r ../ruby ./ruby
|
||||
cp -r ../phoenix ./phoenix
|
||||
rm -r libco/doc
|
||||
rm -r libco/test
|
||||
rm -r nall/test
|
||||
rm -r ruby/_test
|
||||
rm -r phoenix/nall
|
||||
rm -r phoenix/test
|
||||
|
||||
archive:
|
||||
if [ -f bsnes.tar.bz2 ]; then rm bsnes.tar.bz2; fi
|
||||
tar -cjf bsnes.tar.bz2 `ls`
|
||||
|
||||
help:;
|
||||
CC = cl
|
||||
CFLAGS = /nologo /O2
|
||||
OBJS = main.obj timing.obj g65816.obj d65816.obj spc700.obj dspc700.obj memory.obj mmio.obj bridge.obj gui.obj libstr.obj
|
||||
LIBS = kernel32.lib user32.lib gdi32.lib comdlg32.lib ddraw.lib
|
||||
|
||||
all: $(OBJS)
|
||||
$(CC) /Febsnes.exe $(CFLAGS) $(OBJS) $(LIBS)
|
||||
|
||||
clean:
|
||||
del *.obj
|
||||
|
||||
main.obj: main.cpp main.h
|
||||
$(CC) $(CFLAGS) /c main.cpp
|
||||
|
||||
timing.obj: timing/timing.cpp timing/timing.h
|
||||
$(CC) $(CFLAGS) /c timing/timing.cpp
|
||||
|
||||
g65816.obj: cpu/g65816*.cpp cpu/g65816.h
|
||||
$(CC) $(CFLAGS) /c cpu/g65816.cpp
|
||||
|
||||
d65816.obj: cpu/d65816.cpp
|
||||
$(CC) $(CFLAGS) /c cpu/d65816.cpp
|
||||
|
||||
spc700.obj: apu/spc700*.cpp apu/spc700*.h
|
||||
$(CC) $(CFLAGS) /c apu/spc700.cpp
|
||||
|
||||
dspc700.obj: apu/dspc700.cpp
|
||||
$(CC) $(CFLAGS) /c apu/dspc700.cpp
|
||||
|
||||
memory.obj: mem/memory.cpp
|
||||
$(CC) $(CFLAGS) /c mem/memory.cpp
|
||||
|
||||
mmio.obj: ppu/mmio.cpp ppu/ppu*.cpp
|
||||
$(CC) $(CFLAGS) /c ppu/mmio.cpp
|
||||
|
||||
bridge.obj: bridge/bridge.cpp bridge/bridge.h
|
||||
$(CC) $(CFLAGS) /c bridge/bridge.cpp
|
||||
|
||||
gui.obj: win/gui*.cpp win/render*.cpp
|
||||
$(CC) $(CFLAGS) /c win/gui.cpp
|
||||
|
||||
libstr.obj: misc/libstr.cpp
|
||||
$(CC) $(CFLAGS) /c misc/libstr.cpp
|
||||
@@ -0,0 +1,314 @@
|
||||
#include "../base.h"
|
||||
#include "spc700.h"
|
||||
extern sony_spc700 *spc700;
|
||||
extern debugstate debugger;
|
||||
|
||||
char __disas_spc700_str[256];
|
||||
|
||||
word __disas_spc700_relb(byte arg, byte offset) {
|
||||
word r = spc700->regs.pc + (signed char)arg;
|
||||
r += offset;
|
||||
return r;
|
||||
}
|
||||
|
||||
void __disas_spc700_op(byte op, byte op0, byte op1) {
|
||||
char *s = (char*)__disas_spc700_str;
|
||||
word opw = (op1 << 8) | (op0);
|
||||
switch(op) {
|
||||
case 0x00:sprintf(s, "nop");break;
|
||||
case 0x01:sprintf(s, "tcall 0");break;
|
||||
case 0x02:sprintf(s, "set0 $%0.2x", op0);break;
|
||||
case 0x03:sprintf(s, "bbs0 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x04:sprintf(s, "or a,$%0.2x", op0);break;
|
||||
case 0x05:sprintf(s, "or a,$%0.4x", opw);break;
|
||||
case 0x06:sprintf(s, "or a,(x)");break;
|
||||
case 0x07:sprintf(s, "or a,($%0.2x+x)", op0);break;
|
||||
case 0x08:sprintf(s, "or a,#$%0.2x", op0);break;
|
||||
case 0x09:sprintf(s, "or ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x0a:sprintf(s, "or1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x0b:sprintf(s, "asl $%0.2x", op0);break;
|
||||
case 0x0c:sprintf(s, "mov $%0.4x,y", opw);break;
|
||||
case 0x0d:sprintf(s, "push psw");break;
|
||||
case 0x0e:sprintf(s, "tset1 $%0.4x", opw);break;
|
||||
case 0x0f:sprintf(s, "brk");break;
|
||||
case 0x10:sprintf(s, "bpl $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x11:sprintf(s, "tcall 1");break;
|
||||
case 0x12:sprintf(s, "clr0 $%0.2x", op0);break;
|
||||
case 0x13:sprintf(s, "bbc0 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x14:sprintf(s, "or a,$%0.2x+x", op0);break;
|
||||
case 0x15:sprintf(s, "or a,$%0.4x+x", opw);break;
|
||||
case 0x16:sprintf(s, "or a,$%0.4x+y", opw);break;
|
||||
case 0x17:sprintf(s, "or a,($%0.2x)+y", op0);break;
|
||||
case 0x18:sprintf(s, "or $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x19:sprintf(s, "or (x),(y)");break;
|
||||
case 0x1a:sprintf(s, "decw $%0.2x", op0);break;
|
||||
case 0x1b:sprintf(s, "asl $%0.2x+x", op0);break;
|
||||
case 0x1c:sprintf(s, "asl a");break;
|
||||
case 0x1d:sprintf(s, "dec x");break;
|
||||
case 0x1e:sprintf(s, "cmp x,$%0.4x", opw);break;
|
||||
case 0x1f:sprintf(s, "jmp ($%0.4x+x)", opw);break;
|
||||
case 0x20:sprintf(s, "clrp");break;
|
||||
case 0x21:sprintf(s, "tcall 2");break;
|
||||
case 0x22:sprintf(s, "set1 $%0.2x", op0);break;
|
||||
case 0x23:sprintf(s, "bbs1 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x24:sprintf(s, "and a,$%0.2x", op0);break;
|
||||
case 0x25:sprintf(s, "and a,$%0.4x", opw);break;
|
||||
case 0x26:sprintf(s, "and a,(x)", op0);break;
|
||||
case 0x27:sprintf(s, "and a,($%0.2x+x)", op0);break;
|
||||
case 0x28:sprintf(s, "and a,#$%0.2x", op0);break;
|
||||
case 0x29:sprintf(s, "and ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x2a:sprintf(s, "or1 c,!$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x2b:sprintf(s, "rol $%0.2x", op0);break;
|
||||
case 0x2c:sprintf(s, "rol $%0.4x", opw);break;
|
||||
case 0x2d:sprintf(s, "push a");break;
|
||||
case 0x2e:sprintf(s, "cbne $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x2f:sprintf(s, "bra $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x30:sprintf(s, "bmi $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x31:sprintf(s, "tcall 3");break;
|
||||
case 0x32:sprintf(s, "clr1 $%0.2x", op0);break;
|
||||
case 0x33:sprintf(s, "bbc1 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x34:sprintf(s, "and a,$%0.2x+x", op0);break;
|
||||
case 0x35:sprintf(s, "and a,$%0.4x+x", opw);break;
|
||||
case 0x36:sprintf(s, "and a,$%0.4x+y", opw);break;
|
||||
case 0x37:sprintf(s, "and a,($%0.2x)+y", op0);break;
|
||||
case 0x38:sprintf(s, "and $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x39:sprintf(s, "and (x),(y)");break;
|
||||
case 0x3a:sprintf(s, "incw $%0.2x", op0);break;
|
||||
case 0x3b:sprintf(s, "rol $%0.2x+x", op0);break;
|
||||
case 0x3c:sprintf(s, "rol a");break;
|
||||
case 0x3d:sprintf(s, "inc x");break;
|
||||
case 0x3e:sprintf(s, "cmp x,$%0.2x", op0);break;
|
||||
case 0x3f:sprintf(s, "call $%0.4x", opw);break;
|
||||
case 0x40:sprintf(s, "setp");break;
|
||||
case 0x41:sprintf(s, "tcall 4");break;
|
||||
case 0x42:sprintf(s, "set2 $%0.2x", op0);break;
|
||||
case 0x43:sprintf(s, "bbs2 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x44:sprintf(s, "eor a,$%0.2x", op0);break;
|
||||
case 0x45:sprintf(s, "eor a,$%0.4x", opw);break;
|
||||
case 0x46:sprintf(s, "eor a,(x)");break;
|
||||
case 0x47:sprintf(s, "eor a,($%0.2x+x)", op0);break;
|
||||
case 0x48:sprintf(s, "eor a,#$%0.2x", op0);break;
|
||||
case 0x49:sprintf(s, "eor ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x4a:sprintf(s, "and1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x4b:sprintf(s, "lsr $%0.2x", op0);break;
|
||||
case 0x4c:sprintf(s, "lsr $%0.4x", opw);break;
|
||||
case 0x4d:sprintf(s, "push x");break;
|
||||
case 0x4e:sprintf(s, "tclr1 $%0.4x", opw);break;
|
||||
case 0x4f:sprintf(s, "pcall $%0.2x", op0);break;
|
||||
case 0x50:sprintf(s, "bvc $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x51:sprintf(s, "tcall 5");break;
|
||||
case 0x52:sprintf(s, "clr2 $%0.2x", op0);break;
|
||||
case 0x53:sprintf(s, "bbc2 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x54:sprintf(s, "eor a,$%0.2x+x", op0);break;
|
||||
case 0x55:sprintf(s, "eor a,$%0.4x+x", opw);break;
|
||||
case 0x56:sprintf(s, "eor a,$%0.4x+y", opw);break;
|
||||
case 0x57:sprintf(s, "eor a,($%0.2x)+y", op0);break;
|
||||
case 0x58:sprintf(s, "eor $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x59:sprintf(s, "eor (x),(y)", op0);break;
|
||||
case 0x5a:sprintf(s, "cmpw ya,$%0.2x", op0);break;
|
||||
case 0x5b:sprintf(s, "lsr $%0.2x+x", op0);break;
|
||||
case 0x5c:sprintf(s, "lsr a");break;
|
||||
case 0x5d:sprintf(s, "mov x,a");break;
|
||||
case 0x5e:sprintf(s, "cmp y,$%0.4x", opw);break;
|
||||
case 0x5f:sprintf(s, "jmp $%0.4x", opw);break;
|
||||
case 0x60:sprintf(s, "clrc");break;
|
||||
case 0x61:sprintf(s, "tcall 6");break;
|
||||
case 0x62:sprintf(s, "set3 $%0.2x", op0);break;
|
||||
case 0x63:sprintf(s, "bbs3 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x64:sprintf(s, "cmp a,$%0.2x", op0);break;
|
||||
case 0x65:sprintf(s, "cmp a,$%0.4x", opw);break;
|
||||
case 0x66:sprintf(s, "cmp a,(x)", op0);break;
|
||||
case 0x67:sprintf(s, "cmp a,($%0.2x+x)", op0);break;
|
||||
case 0x68:sprintf(s, "cmp a,#$%0.2x", op0);break;
|
||||
case 0x69:sprintf(s, "cmp ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x6a:sprintf(s, "and1 c,!$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x6b:sprintf(s, "ror $%0.2x", op0);break;
|
||||
case 0x6c:sprintf(s, "ror $%0.4x", opw);break;
|
||||
case 0x6d:sprintf(s, "push y");break;
|
||||
case 0x6e:sprintf(s, "dbnz $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x6f:sprintf(s, "ret");break;
|
||||
case 0x70:sprintf(s, "bvs $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x71:sprintf(s, "tcall 7");break;
|
||||
case 0x72:sprintf(s, "clr3 $%0.2x", op0);break;
|
||||
case 0x73:sprintf(s, "bbc3 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x74:sprintf(s, "cmp a,$%0.2x+x", op0);break;
|
||||
case 0x75:sprintf(s, "cmp a,$%0.4x+x", opw);break;
|
||||
case 0x76:sprintf(s, "cmp a,$%0.4x+y", opw);break;
|
||||
case 0x77:sprintf(s, "cmp a,($%0.2x)+y", op0);break;
|
||||
case 0x78:sprintf(s, "cmp $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x79:sprintf(s, "cmp (x),(y)");break;
|
||||
case 0x7a:sprintf(s, "addw ya,$%0.2x", op0);break;
|
||||
case 0x7b:sprintf(s, "ror $%0.2x+x", op0);break;
|
||||
case 0x7c:sprintf(s, "ror a");break;
|
||||
case 0x7d:sprintf(s, "mov a,x");break;
|
||||
case 0x7e:sprintf(s, "cmp y,$%0.2x", op0);break;
|
||||
case 0x7f:sprintf(s, "reti");break;
|
||||
case 0x80:sprintf(s, "setc");break;
|
||||
case 0x81:sprintf(s, "tcall 8");break;
|
||||
case 0x82:sprintf(s, "set4 $%0.2x", op0);break;
|
||||
case 0x83:sprintf(s, "bbs4 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x84:sprintf(s, "adc a,$%0.2x", op0);break;
|
||||
case 0x85:sprintf(s, "adc a,$%0.4x", opw);break;
|
||||
case 0x86:sprintf(s, "adc a,(x)", op0);break;
|
||||
case 0x87:sprintf(s, "adc a,($%0.2x+x)", op0);break;
|
||||
case 0x88:sprintf(s, "adc a,#$%0.2x", op0);break;
|
||||
case 0x89:sprintf(s, "adc ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x8a:sprintf(s, "eor1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x8b:sprintf(s, "dec $%0.2x", op0);break;
|
||||
case 0x8c:sprintf(s, "dec $%0.4x", opw);break;
|
||||
case 0x8d:sprintf(s, "mov y,#$%0.2x", op0);break;
|
||||
case 0x8e:sprintf(s, "pop psw");break;
|
||||
case 0x8f:sprintf(s, "mov $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x90:sprintf(s, "bcc $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x91:sprintf(s, "tcall 9");break;
|
||||
case 0x92:sprintf(s, "clr4 $%0.2x", op0);break;
|
||||
case 0x93:sprintf(s, "bbc4 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x94:sprintf(s, "adc a,$%0.2x+x", op0);break;
|
||||
case 0x95:sprintf(s, "adc a,$%0.4x+x", opw);break;
|
||||
case 0x96:sprintf(s, "adc a,$%0.4x+y", opw);break;
|
||||
case 0x97:sprintf(s, "adc a,($%0.2x)+y", op0);break;
|
||||
case 0x98:sprintf(s, "adc $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x99:sprintf(s, "adc (x),(y)", op0);break;
|
||||
case 0x9a:sprintf(s, "subw ya,$%0.2x", op0);break;
|
||||
case 0x9b:sprintf(s, "dec $%0.2x+x", op0);break;
|
||||
case 0x9c:sprintf(s, "dec a");break;
|
||||
case 0x9d:sprintf(s, "mov x,sp");break;
|
||||
case 0x9e:sprintf(s, "div ya,x");break;
|
||||
case 0x9f:sprintf(s, "xcn a");break;
|
||||
case 0xa0:sprintf(s, "ei");break;
|
||||
case 0xa1:sprintf(s, "tcall 10");break;
|
||||
case 0xa2:sprintf(s, "set5 $%0.2x", op0);break;
|
||||
case 0xa3:sprintf(s, "bbs5 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xa4:sprintf(s, "sbc a,$%0.2x", op0);break;
|
||||
case 0xa5:sprintf(s, "sbc a,$%0.4x", opw);break;
|
||||
case 0xa6:sprintf(s, "sbc a,(x)", op0);break;
|
||||
case 0xa7:sprintf(s, "sbc a,($%0.2x+x)", op0);break;
|
||||
case 0xa8:sprintf(s, "sbc a,#$%0.2x", op0);break;
|
||||
case 0xa9:sprintf(s, "sbc ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0xaa:sprintf(s, "mov1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0xab:sprintf(s, "inc $%0.2x", op0);break;
|
||||
case 0xac:sprintf(s, "inc $%0.4x", opw);break;
|
||||
case 0xad:sprintf(s, "cmp y,#$%0.2x", op0);break;
|
||||
case 0xae:sprintf(s, "pop a");break;
|
||||
case 0xaf:sprintf(s, "mov (x)+,a");break;
|
||||
case 0xb0:sprintf(s, "bcs $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0xb1:sprintf(s, "tcall 11");break;
|
||||
case 0xb2:sprintf(s, "clr5 $%0.2x", op0);break;
|
||||
case 0xb3:sprintf(s, "bbc5 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xb4:sprintf(s, "sbc a,$%0.2x+x", op0);break;
|
||||
case 0xb5:sprintf(s, "sbc a,$%0.4x+x", opw);break;
|
||||
case 0xb6:sprintf(s, "sbc a,$%0.4x+y", opw);break;
|
||||
case 0xb7:sprintf(s, "sbc a,($%0.2x)+y", op0);break;
|
||||
case 0xb8:sprintf(s, "sbc $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0xb9:sprintf(s, "sbc (x),(y)", op0);break;
|
||||
case 0xba:sprintf(s, "movw ya,$%0.2x", op0);break;
|
||||
case 0xbb:sprintf(s, "inc $%0.2x+x", op0);break;
|
||||
case 0xbc:sprintf(s, "inc a");break;
|
||||
case 0xbd:sprintf(s, "mov sp,x");break;
|
||||
case 0xbe:sprintf(s, "das a");break;
|
||||
case 0xbf:sprintf(s, "mov a,(x)+");break;
|
||||
case 0xc0:sprintf(s, "di");break;
|
||||
case 0xc1:sprintf(s, "tcall 12");break;
|
||||
case 0xc2:sprintf(s, "set6 $%0.2x", op0);break;
|
||||
case 0xc3:sprintf(s, "bbs6 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xc4:sprintf(s, "mov $%0.2x,a", op0);break;
|
||||
case 0xc5:sprintf(s, "mov $%0.4x,a", opw);break;
|
||||
case 0xc6:sprintf(s, "mov (x),a");break;
|
||||
case 0xc7:sprintf(s, "mov ($%0.2x+x),a", op0);break;
|
||||
case 0xc8:sprintf(s, "cmp x,#$%0.2x", op0);break;
|
||||
case 0xc9:sprintf(s, "mov $%0.4x,x", opw);break;
|
||||
case 0xca:sprintf(s, "mov1 $%0.4x,%d,c", opw & 0x1fff, opw >> 13);break;
|
||||
case 0xcb:sprintf(s, "mov $%0.2x,y", op0);break;
|
||||
case 0xcc:sprintf(s, "asl $%0.4x", opw);break;
|
||||
case 0xcd:sprintf(s, "mov x,#$%0.2x", op0);break;
|
||||
case 0xce:sprintf(s, "pop x");break;
|
||||
case 0xcf:sprintf(s, "mul ya");break;
|
||||
case 0xd0:sprintf(s, "bne $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0xd1:sprintf(s, "tcall 13");break;
|
||||
case 0xd2:sprintf(s, "clr6 $%0.2x", op0);break;
|
||||
case 0xd3:sprintf(s, "bbc6 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xd4:sprintf(s, "mov $%0.2x+x,a", op0);break;
|
||||
case 0xd5:sprintf(s, "mov $%0.4x+x,a", opw);break;
|
||||
case 0xd6:sprintf(s, "mov $%0.4x+y,a", opw);break;
|
||||
case 0xd7:sprintf(s, "mov ($%0.2x)+y,a", op0);break;
|
||||
case 0xd8:sprintf(s, "mov $%0.2x,x", op0);break;
|
||||
case 0xd9:sprintf(s, "mov $%0.2x+y,x", op0);break;
|
||||
case 0xda:sprintf(s, "movw $%0.2x,ya", op0);break;
|
||||
case 0xdb:sprintf(s, "mov $%0.2x+x,y", op0);break;
|
||||
case 0xdc:sprintf(s, "dec y");break;
|
||||
case 0xdd:sprintf(s, "mov a,y");break;
|
||||
case 0xde:sprintf(s, "cbne $%0.2x+x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xdf:sprintf(s, "daa a");break;
|
||||
case 0xe0:sprintf(s, "clrv");break;
|
||||
case 0xe1:sprintf(s, "tcall 14");break;
|
||||
case 0xe2:sprintf(s, "set7 $%0.2x", op0);break;
|
||||
case 0xe3:sprintf(s, "bbs7 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xe4:sprintf(s, "mov a,$%0.2x", op0);break;
|
||||
case 0xe5:sprintf(s, "mov a,$%0.4x", opw);break;
|
||||
case 0xe6:sprintf(s, "mov a,(x)");break;
|
||||
case 0xe7:sprintf(s, "mov a,($%0.2x+x)", op0);break;
|
||||
case 0xe8:sprintf(s, "mov a,#$%0.2x", op0);break;
|
||||
case 0xe9:sprintf(s, "mov x,$%0.4x", opw);break;
|
||||
case 0xea:sprintf(s, "not1 $%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0xeb:sprintf(s, "mov y,$%0.2x", op0);break;
|
||||
case 0xec:sprintf(s, "mov y,$%0.4x", opw);break;
|
||||
case 0xed:sprintf(s, "notc");break;
|
||||
case 0xee:sprintf(s, "pop y");break;
|
||||
case 0xef:sprintf(s, "sleep");break;
|
||||
case 0xf0:sprintf(s, "beq $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0xf1:sprintf(s, "tcall 15");break;
|
||||
case 0xf2:sprintf(s, "clr7 $%0.2x", op0);break;
|
||||
case 0xf3:sprintf(s, "bbc7 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xf4:sprintf(s, "mov a,$%0.2x+x", op0);break;
|
||||
case 0xf5:sprintf(s, "mov a,$%0.4x+x", opw);break;
|
||||
case 0xf6:sprintf(s, "mov a,$%0.4x+y", opw);break;
|
||||
case 0xf7:sprintf(s, "mov a,($%0.2x)+y", op0);break;
|
||||
case 0xf8:sprintf(s, "mov x,$%0.2x", op0);break;
|
||||
case 0xf9:sprintf(s, "mov x,$%0.2x+y", op0);break;
|
||||
case 0xfa:sprintf(s, "mov ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0xfb:sprintf(s, "mov y,$%0.2x+x", op0);break;
|
||||
case 0xfc:sprintf(s, "inc y");break;
|
||||
case 0xfd:sprintf(s, "mov y,a");break;
|
||||
case 0xfe:sprintf(s, "dbnz y,$%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0xff:sprintf(s, "stop");break;
|
||||
}
|
||||
}
|
||||
|
||||
void disas_spc700_op(void) {
|
||||
byte op;
|
||||
byte op0, op1;
|
||||
word offset;
|
||||
char flags[256];
|
||||
char *s = (char*)__disas_spc700_str;
|
||||
int i;
|
||||
if(debug_write_status() == DEBUGWRITE_NONE)return;
|
||||
|
||||
//use offset instead of spc700->regs.pc + n to avoid going above 65535
|
||||
offset = spc700->regs.pc;
|
||||
op = spc700->ram[offset++];
|
||||
op0 = spc700->ram[offset++];
|
||||
op1 = spc700->ram[offset ];
|
||||
|
||||
strcpy(__disas_spc700_str, "???");
|
||||
__disas_spc700_op(op, op0, op1);
|
||||
i = strlen(s);
|
||||
while(i < 23) {
|
||||
s[i++] = ' ';
|
||||
s[i] = 0;
|
||||
}
|
||||
|
||||
sprintf(flags, "%c%c%c%c%c%c%c%c",
|
||||
(spc700->regs.p & 0x80)?'N':'n',
|
||||
(spc700->regs.p & 0x40)?'V':'v',
|
||||
(spc700->regs.p & 0x20)?'P':'p',
|
||||
(spc700->regs.p & 0x10)?'B':'b',
|
||||
(spc700->regs.p & 0x08)?'H':'h',
|
||||
(spc700->regs.p & 0x04)?'I':'i',
|
||||
(spc700->regs.p & 0x02)?'Z':'z',
|
||||
(spc700->regs.p & 0x01)?'C':'c');
|
||||
|
||||
dprintf(DEBUGMSG_APU, "--%0.4x %s A:%0.2x X:%0.2x Y:%0.2x SP:%0.2x YA:%0.4x %s",
|
||||
spc700->regs.pc, __disas_spc700_str,
|
||||
spc700->regs.a, spc700->regs.x, spc700->regs.y, spc700->regs.sp,
|
||||
(spc700->regs.y << 8) | (spc700->regs.a), flags);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "../base.h"
|
||||
#include "../timing/timing.h"
|
||||
#include "../bridge/bridge.h"
|
||||
#include "spc700_iplrom.h"
|
||||
#include "spc700.h"
|
||||
|
||||
extern snes_timer *snes_time;
|
||||
extern debugstate debugger;
|
||||
extern port_bridge *cpu_apu_bridge;
|
||||
sony_spc700 *spc700;
|
||||
|
||||
#include "spc700_ops.cpp"
|
||||
|
||||
void sony_spc700::Reset(void) {
|
||||
memset(ram, 0, 65536);
|
||||
memcpy(ram + 0xffc0, spc700_iplrom, 64);
|
||||
regs.pc = 0xffc0;
|
||||
regs.a = regs.x = regs.y = regs.sp = 0x00;
|
||||
regs.p = 0x02;
|
||||
regs.dp = 0x0000;
|
||||
}
|
||||
|
||||
void sony_spc700::exec_op(void) {
|
||||
byte op;
|
||||
op = spc700->ram[spc700->regs.pc];
|
||||
spc700_optbl[op]();
|
||||
debugger.apu_op_executed = true;
|
||||
debugger.disas_apu_op = true;
|
||||
|
||||
debug_test_bp(BPSRC_SPCRAM, BP_EXEC, spc700->regs.pc, 0);
|
||||
}
|
||||
|
||||
void sony_spc700::Run(void) {
|
||||
if(snes_time->bridge.cpu_cycles >= snes_time->bridge.apu_cycles) {
|
||||
exec_op();
|
||||
}
|
||||
if(snes_time->bridge.cpu_cycles >= 65536 && snes_time->bridge.apu_cycles >= 65536) {
|
||||
snes_time->bridge.cpu_cycles &= 65535;
|
||||
snes_time->bridge.apu_cycles &= 65535;
|
||||
}
|
||||
}
|
||||
|
||||
sony_spc700::sony_spc700() {
|
||||
ram = (byte*)malloc(65536);
|
||||
}
|
||||
|
||||
sony_spc700::~sony_spc700() {
|
||||
if(ram)free(ram);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
class sony_spc700 {
|
||||
public:
|
||||
struct {
|
||||
word pc;
|
||||
byte a, x, y, sp, p;
|
||||
word dp;
|
||||
}regs;
|
||||
byte *ram;
|
||||
|
||||
void Reset(void);
|
||||
void Run(void);
|
||||
|
||||
void exec_op(void);
|
||||
word convert_address(byte mode, word addr);
|
||||
byte mem_getbyte(word addr);
|
||||
void mem_putbyte(word addr, byte value);
|
||||
word mem_read(byte mode, byte size, word addr);
|
||||
void mem_write(byte mode, byte size, word addr, word value);
|
||||
byte stack_read(void);
|
||||
void stack_write(byte value);
|
||||
|
||||
sony_spc700();
|
||||
~sony_spc700();
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
byte spc700_iplrom[64] = {
|
||||
/*ffc0*/ 0xcd, 0xef, //mov x,#$ef
|
||||
/*ffc2*/ 0xbd, //mov sp,x
|
||||
/*ffc3*/ 0xe8, 0x00, //mov a,#$00
|
||||
/*ffc5*/ 0xc6, //mov (x),a
|
||||
/*ffc6*/ 0x1d, //dec x
|
||||
/*ffc7*/ 0xd0, 0xfc, //bne $ffc5
|
||||
/*ffc9*/ 0x8f, 0xaa, 0xf4, //mov $f4,#$aa
|
||||
/*ffcc*/ 0x8f, 0xbb, 0xf5, //mov $f5,#$bb
|
||||
/*ffcf*/ 0x78, 0xcc, 0xf4, //cmp $f4,#$cc
|
||||
/*ffd2*/ 0xd0, 0xfb, //bne $ffcf
|
||||
/*ffd4*/ 0x2f, 0x19, //bra $ffef
|
||||
/*ffd6*/ 0xeb, 0xf4, //mov y,$f4
|
||||
/*ffd8*/ 0xd0, 0xfc, //bne $ffd6
|
||||
/*ffda*/ 0x7e, 0xf4, //cmp y,$f4
|
||||
/*ffdc*/ 0xd0, 0x0b, //bne $ffe9
|
||||
/*ffde*/ 0xe4, 0xf5, //mov a,$f5
|
||||
/*ffe0*/ 0xcb, 0xf4, //mov $f4,y
|
||||
/*ffe2*/ 0xd7, 0x00, //mov ($00)+y,a
|
||||
/*ffe4*/ 0xfc, //inc y
|
||||
/*ffe5*/ 0xd0, 0xf3, //bne $ffda
|
||||
/*ffe7*/ 0xab, 0x01, //inc $01
|
||||
/*ffe9*/ 0x10, 0xef, //bpl $ffda
|
||||
/*ffeb*/ 0x7e, 0xf4, //cmp y,$f4
|
||||
/*ffed*/ 0x10, 0xeb, //bpl $ffda
|
||||
/*ffef*/ 0xba, 0xf6, //movw ya,$f6
|
||||
/*fff1*/ 0xda, 0x00, //movw $00,ya
|
||||
/*fff3*/ 0xba, 0xf4, //movw ya,$f4
|
||||
/*fff5*/ 0xc4, 0xf4, //mov $f4,a
|
||||
/*fff7*/ 0xdd, //mov a,y
|
||||
/*fff8*/ 0x5d, //mov x,a
|
||||
/*fff9*/ 0xd0, 0xdb, //bne $ffd6
|
||||
/*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x)
|
||||
/*fffe*/ 0xc0, 0xff //---reset vector location ($ffc0)
|
||||
};
|
||||
@@ -0,0 +1,194 @@
|
||||
#define spc700_setn() spc700->regs.p |= SPF_N
|
||||
#define spc700_clrn() spc700->regs.p &= ~SPF_N
|
||||
#define spc700_setv() spc700->regs.p |= SPF_V
|
||||
#define spc700_clrv() spc700->regs.p &= ~SPF_V
|
||||
#define spc700_setp() spc700->regs.p |= SPF_P;spc700->regs.dp = 0x0100
|
||||
#define spc700_clrp() spc700->regs.p &= ~SPF_P;spc700->regs.dp = 0x0000
|
||||
#define spc700_setb() spc700->regs.p |= SPF_B
|
||||
#define spc700_clrb() spc700->regs.p &= ~SPF_B
|
||||
#define spc700_seth() spc700->regs.p |= SPF_H
|
||||
#define spc700_clrh() spc700->regs.p &= ~SPF_H
|
||||
#define spc700_seti() spc700->regs.p |= SPF_I
|
||||
#define spc700_clri() spc700->regs.p &= ~SPF_I
|
||||
#define spc700_setz() spc700->regs.p |= SPF_Z
|
||||
#define spc700_clrz() spc700->regs.p &= ~SPF_Z
|
||||
#define spc700_setc() spc700->regs.p |= SPF_C
|
||||
#define spc700_clrc() spc700->regs.p &= ~SPF_C
|
||||
#define spc700_testn(x) if(x)spc700_setn(); else spc700_clrn()
|
||||
#define spc700_testv(x) if(x)spc700_setv(); else spc700_clrv()
|
||||
#define spc700_testp(x) if(x)spc700_setp(); else spc700_clrp()
|
||||
#define spc700_testb(x) if(x)spc700_setb(); else spc700_clrb()
|
||||
#define spc700_testh(x) if(x)spc700_seth(); else spc700_clrh()
|
||||
#define spc700_testi(x) if(x)spc700_seti(); else spc700_clri()
|
||||
#define spc700_testz(x) if(x)spc700_setz(); else spc700_clrz()
|
||||
#define spc700_testc(x) if(x)spc700_setc(); else spc700_clrc()
|
||||
|
||||
#define spc700_incpc(__n) spc700->regs.pc += __n
|
||||
|
||||
#define spc700_prefetchb() \
|
||||
byte arg = spc700->ram[(spc700->regs.pc + 1) & 0xffff]
|
||||
|
||||
#define spc700_prefetch2b() \
|
||||
byte arg0 = spc700->ram[(spc700->regs.pc + 1) & 0xffff]; \
|
||||
byte arg1 = spc700->ram[(spc700->regs.pc + 2) & 0xffff]
|
||||
|
||||
#define spc700_prefetchw() \
|
||||
word arg = spc700->ram[(spc700->regs.pc + 1) & 0xffff] | (spc700->ram[(spc700->regs.pc + 2) & 0xffff] << 8)
|
||||
|
||||
#define APUMODE_NONE 0
|
||||
#define APUMODE_DP 1
|
||||
#define APUMODE_DPX 2
|
||||
#define APUMODE_DPY 3
|
||||
#define APUMODE_IDP 4
|
||||
#define APUMODE_ADDR 5
|
||||
#define APUMODE_IX 6
|
||||
#define APUMODE_ADDRX 7
|
||||
#define APUMODE_ADDRY 8
|
||||
#define APUMODE_IDPX 9
|
||||
#define APUMODE_IDPY 10
|
||||
#define APUMODE_IADDRX 11
|
||||
#define APUMODE_IY 12
|
||||
|
||||
word sony_spc700::convert_address(byte mode, word addr) {
|
||||
word r;
|
||||
switch(mode) {
|
||||
case APUMODE_NONE:
|
||||
r = addr;
|
||||
case APUMODE_DP:
|
||||
r = spc700->regs.dp | (byte)addr;
|
||||
break;
|
||||
case APUMODE_DPX:
|
||||
r = spc700->regs.dp | (byte)(addr + spc700->regs.x);
|
||||
break;
|
||||
case APUMODE_DPY:
|
||||
r = spc700->regs.dp | (byte)(addr + spc700->regs.y);
|
||||
break;
|
||||
case APUMODE_IDP:
|
||||
r = spc700->regs.dp | (byte)addr;
|
||||
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
|
||||
break;
|
||||
case APUMODE_ADDR:
|
||||
r = addr;
|
||||
break;
|
||||
case APUMODE_IX:
|
||||
r = spc700->regs.dp | spc700->regs.x;
|
||||
break;
|
||||
case APUMODE_ADDRX:
|
||||
r = addr + spc700->regs.x;
|
||||
break;
|
||||
case APUMODE_ADDRY:
|
||||
r = addr + spc700->regs.y;
|
||||
break;
|
||||
case APUMODE_IDPX:
|
||||
r = spc700->regs.dp | (byte)(addr + spc700->regs.x);
|
||||
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
|
||||
break;
|
||||
case APUMODE_IDPY:
|
||||
r = spc700->regs.dp | (byte)addr;
|
||||
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
|
||||
r += spc700->regs.y;
|
||||
break;
|
||||
case APUMODE_IADDRX:
|
||||
r = (spc700->ram[(addr + spc700->regs.x )]) |
|
||||
(spc700->ram[(addr + spc700->regs.x + 1)] << 8);
|
||||
break;
|
||||
case APUMODE_IY:
|
||||
r = spc700->regs.dp | spc700->regs.y;
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
byte sony_spc700::mem_getbyte(word addr) {
|
||||
if(addr >= 0x00f4 && addr <= 0x00f7) {
|
||||
return cpu_apu_bridge->apu_read(addr - 0x00f4);
|
||||
} else {
|
||||
return spc700->ram[addr];
|
||||
}
|
||||
}
|
||||
|
||||
void sony_spc700::mem_putbyte(word addr, byte value) {
|
||||
if(addr >= 0x00f4 && addr <= 0x00f7) {
|
||||
cpu_apu_bridge->apu_write(addr - 0x00f4, value);
|
||||
} else if(addr < 0xffc0) {
|
||||
spc700->ram[addr] = value;
|
||||
}
|
||||
}
|
||||
|
||||
word sony_spc700::mem_read(byte mode, byte size, word addr) {
|
||||
word r;
|
||||
addr = convert_address(mode, addr);
|
||||
switch(size) {
|
||||
case MEMSIZE_BYTE:
|
||||
r = mem_getbyte(addr);
|
||||
break;
|
||||
case MEMSIZE_WORD:
|
||||
r = mem_getbyte(addr) | (mem_getbyte(addr + 1) << 8);
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void sony_spc700::mem_write(byte mode, byte size, word addr, word value) {
|
||||
addr = convert_address(mode, addr);
|
||||
switch(size) {
|
||||
case MEMSIZE_BYTE:
|
||||
mem_putbyte(addr, value);
|
||||
break;
|
||||
case MEMSIZE_WORD:
|
||||
mem_putbyte(addr , value);
|
||||
mem_putbyte(addr + 1, value >> 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
byte sony_spc700::stack_read(void) {
|
||||
word addr;
|
||||
spc700->regs.sp++;
|
||||
addr = 0x0100 | spc700->regs.sp;
|
||||
return mem_getbyte(addr);
|
||||
}
|
||||
|
||||
void sony_spc700::stack_write(byte value) {
|
||||
word addr;
|
||||
addr = 0x0100 | spc700->regs.sp;
|
||||
spc700->regs.sp--;
|
||||
mem_putbyte(addr, value);
|
||||
}
|
||||
|
||||
#include "spc700_ops_adc.cpp"
|
||||
#include "spc700_ops_and.cpp"
|
||||
#include "spc700_ops_cmp.cpp"
|
||||
#include "spc700_ops_eor.cpp"
|
||||
#include "spc700_ops_flags.cpp"
|
||||
#include "spc700_ops_incdec.cpp"
|
||||
#include "spc700_ops_misc.cpp"
|
||||
#include "spc700_ops_mov.cpp"
|
||||
#include "spc700_ops_or.cpp"
|
||||
#include "spc700_ops_pc.cpp"
|
||||
#include "spc700_ops_sbc.cpp"
|
||||
#include "spc700_ops_shift.cpp"
|
||||
#include "spc700_ops_stack.cpp"
|
||||
|
||||
vfunc spc700_optbl[256] = {
|
||||
// -----------------------------x0, -----------------------------x1, -----------------------------x2, -----------------------------x3, -------- -----------------------------x4, -----------------------------x5, -----------------------------x6, -----------------------------x7, -------- -----------------------------x8, -----------------------------x9, -----------------------------xa, -----------------------------xb, -------- -----------------------------xc, -----------------------------xd, -----------------------------xe, -----------------------------xf,
|
||||
/* 0x */ spc700_op_nop, spc700_op_tcall_0, spc700_op_set0_dp, spc700_op_bbc0, /* 0x */ spc700_op_or_a_dp, spc700_op_or_a_addr, spc700_op_or_a_ix, spc700_op_or_a_idpx, /* 0x */ spc700_op_or_a_const, spc700_op_or_dp_dp, spc700_op_or1_bit, spc700_op_asl_dp, /* 0x */ spc700_op_mov_addr_y, spc700_op_push_p, spc700_op_tset1_addr, spc700_op_brk,
|
||||
/* 1x */ spc700_op_bpl, spc700_op_tcall_1, spc700_op_clr0_dp, spc700_op_bbs0, /* 1x */ spc700_op_or_a_dpx, spc700_op_or_a_addrx, spc700_op_or_a_addry, spc700_op_or_a_idpy, /* 1x */ spc700_op_or_dp_imm, spc700_op_or_ix_iy, spc700_op_decw_dp, spc700_op_asl_dpx, /* 1x */ spc700_op_asl_a, spc700_op_dec_x, spc700_op_cmp_x_addr, spc700_op_jmp_iaddrx,
|
||||
/* 2x */ spc700_op_clrp, spc700_op_tcall_2, spc700_op_set1_dp, spc700_op_bbc1, /* 2x */ spc700_op_and_a_dp, spc700_op_and_a_addr, spc700_op_and_a_ix, spc700_op_and_a_idpx, /* 2x */ spc700_op_and_a_const, spc700_op_and_dp_dp, spc700_op_or1_notbit, spc700_op_rol_dp, /* 2x */ spc700_op_rol_addr, spc700_op_push_a, spc700_op_cbne_dp, spc700_op_bra,
|
||||
/* 3x */ spc700_op_bmi, spc700_op_tcall_3, spc700_op_clr1_dp, spc700_op_bbs1, /* 3x */ spc700_op_and_a_dpx, spc700_op_and_a_addrx, spc700_op_and_a_addry, spc700_op_and_a_idpy, /* 3x */ spc700_op_and_dp_imm, spc700_op_and_ix_iy, spc700_op_incw_dp, spc700_op_rol_dpx, /* 3x */ spc700_op_rol_a, spc700_op_inc_x, spc700_op_cmp_x_dp, spc700_op_call,
|
||||
|
||||
/* 4x */ spc700_op_setp, spc700_op_tcall_4, spc700_op_set2_dp, spc700_op_bbc2, /* 4x */ spc700_op_eor_a_dp, spc700_op_eor_a_addr, spc700_op_eor_a_ix, spc700_op_eor_a_idpx, /* 4x */ spc700_op_eor_a_const, spc700_op_eor_dp_dp, spc700_op_and1_bit, spc700_op_lsr_dp, /* 4x */ spc700_op_lsr_addr, spc700_op_push_x, spc700_op_tclr1_addr, spc700_op_pcall,
|
||||
/* 5x */ spc700_op_bvc, spc700_op_tcall_5, spc700_op_clr2_dp, spc700_op_bbs2, /* 5x */ spc700_op_eor_a_dpx, spc700_op_eor_a_addrx, spc700_op_eor_a_addry, spc700_op_eor_a_idpy, /* 5x */ spc700_op_eor_dp_imm, spc700_op_eor_ix_iy, spc700_op_cmpw_ya_dp, spc700_op_lsr_dpx, /* 5x */ spc700_op_lsr_a, spc700_op_mov_x_a, spc700_op_cmp_y_addr, spc700_op_jmp_addr,
|
||||
/* 6x */ spc700_op_clrc, spc700_op_tcall_6, spc700_op_set3_dp, spc700_op_bbc3, /* 6x */ spc700_op_cmp_a_dp, spc700_op_cmp_a_addr, spc700_op_cmp_a_ix, spc700_op_cmp_a_idpx, /* 6x */ spc700_op_cmp_a_const, spc700_op_cmp_dp_dp, spc700_op_and1_notbit, spc700_op_ror_dp, /* 6x */ spc700_op_ror_addr, spc700_op_push_y, spc700_op_dbnz_dp, spc700_op_ret,
|
||||
/* 7x */ spc700_op_bvs, spc700_op_tcall_7, spc700_op_clr3_dp, spc700_op_bbs3, /* 7x */ spc700_op_cmp_a_dpx, spc700_op_cmp_a_addrx, spc700_op_cmp_a_addry, spc700_op_cmp_a_idpy, /* 7x */ spc700_op_cmp_dp_imm, spc700_op_cmp_ix_iy, spc700_op_addw_ya_dp, spc700_op_ror_dpx, /* 7x */ spc700_op_ror_a, spc700_op_mov_a_x, spc700_op_cmp_y_dp, spc700_op_reti,
|
||||
|
||||
/* 8x */ spc700_op_setc, spc700_op_tcall_8, spc700_op_set4_dp, spc700_op_bbc4, /* 8x */ spc700_op_adc_a_dp, spc700_op_adc_a_addr, spc700_op_adc_a_ix, spc700_op_adc_a_idpx, /* 8x */ spc700_op_adc_a_const, spc700_op_adc_dp_dp, spc700_op_eor1_bit, spc700_op_dec_dp, /* 8x */ spc700_op_dec_addr, spc700_op_mov_y_const, spc700_op_pop_p, spc700_op_mov_dp_imm,
|
||||
/* 9x */ spc700_op_bcc, spc700_op_tcall_9, spc700_op_clr4_dp, spc700_op_bbs4, /* 9x */ spc700_op_adc_a_dpx, spc700_op_adc_a_addrx, spc700_op_adc_a_addry, spc700_op_adc_a_idpy, /* 9x */ spc700_op_adc_dp_imm, spc700_op_adc_ix_iy, spc700_op_subw_ya_dp, spc700_op_dec_dpx, /* 9x */ spc700_op_dec_a, spc700_op_mov_x_sp, spc700_op_div_ya_x, spc700_op_xcn_a,
|
||||
/* ax */ spc700_op_ei, spc700_op_tcall_10, spc700_op_set5_dp, spc700_op_bbc5, /* ax */ spc700_op_sbc_a_dp, spc700_op_sbc_a_addr, spc700_op_sbc_a_ix, spc700_op_sbc_a_idpx, /* ax */ spc700_op_sbc_a_const, spc700_op_sbc_dp_dp, spc700_op_mov1_c_bit, spc700_op_inc_dp, /* ax */ spc700_op_inc_addr, spc700_op_cmp_y_const, spc700_op_pop_a, spc700_op_mov_ixinc_a,
|
||||
/* bx */ spc700_op_bcs, spc700_op_tcall_11, spc700_op_clr5_dp, spc700_op_bbs5, /* bx */ spc700_op_sbc_a_dpx, spc700_op_sbc_a_addrx, spc700_op_sbc_a_addry, spc700_op_sbc_a_idpy, /* bx */ spc700_op_sbc_dp_imm, spc700_op_sbc_ix_iy, spc700_op_mov_ya_dp, spc700_op_inc_dpx, /* bx */ spc700_op_inc_a, spc700_op_mov_sp_x, spc700_op_das_a, spc700_op_mov_a_ixinc,
|
||||
|
||||
/* cx */ spc700_op_di, spc700_op_tcall_12, spc700_op_set6_dp, spc700_op_bbc6, /* cx */ spc700_op_mov_dp_a, spc700_op_mov_addr_a, spc700_op_mov_ix_a, spc700_op_mov_idpx_a, /* cx */ spc700_op_cmp_x_const, spc700_op_mov_addr_x, spc700_op_mov1_bit_c, spc700_op_mov_dp_y, /* cx */ spc700_op_asl_addr, spc700_op_mov_x_const, spc700_op_pop_x, spc700_op_mul_ya,
|
||||
/* dx */ spc700_op_bne, spc700_op_tcall_13, spc700_op_clr6_dp, spc700_op_bbs6, /* dx */ spc700_op_mov_dpx_a, spc700_op_mov_addrx_a, spc700_op_mov_addry_a, spc700_op_mov_idpy_a, /* dx */ spc700_op_mov_dp_x, spc700_op_mov_dpy_x, spc700_op_mov_dp_ya, spc700_op_mov_dpx_y, /* dx */ spc700_op_dec_y, spc700_op_mov_a_y, spc700_op_cbne_dpx, spc700_op_daa_a,
|
||||
/* ex */ spc700_op_clrv, spc700_op_tcall_14, spc700_op_set7_dp, spc700_op_bbc7, /* ex */ spc700_op_mov_a_dp, spc700_op_mov_a_addr, spc700_op_mov_a_ix, spc700_op_mov_a_idpx, /* ex */ spc700_op_mov_a_const, spc700_op_mov_x_addr, spc700_op_not1_bit, spc700_op_mov_y_dp, /* ex */ spc700_op_mov_y_addr, spc700_op_notc, spc700_op_pop_y, spc700_op_sleep,
|
||||
/* fx */ spc700_op_beq, spc700_op_tcall_15, spc700_op_clr7_dp, spc700_op_bbs7, /* fx */ spc700_op_mov_a_dpx, spc700_op_mov_a_addrx, spc700_op_mov_a_addry, spc700_op_mov_a_idpy, /* fx */ spc700_op_mov_x_dp, spc700_op_mov_x_dpy, spc700_op_mov_dp_dp, spc700_op_mov_y_dpx, /* fx */ spc700_op_inc_y, spc700_op_mov_y_a, spc700_op_dbnz_y, spc700_op_stop
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
byte spc700_op_adc(byte x, byte y) {
|
||||
word r = x + y + (spc700->regs.p & SPF_C);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testv((~(x ^ y) & (y ^ (byte)r) & 0x80));
|
||||
spc700_testh((x ^ y ^ (byte)r) & 0x10);
|
||||
spc700_testz((byte)r == 0);
|
||||
spc700_testc(r >= 0x100);
|
||||
return (byte)r;
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_ix(void) {
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a += spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700->regs.a += (spc700->regs.p & PF_C);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_adc_ix_iy(void) {
|
||||
byte x = spc700_op_adc(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_adc_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x = spc700_op_adc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_adc_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x = spc700_op_adc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_addw_ya_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
|
||||
ulong r = ya + dp;
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testv(~(ya ^ dp) & (dp ^ (word)r) & 0x8000);
|
||||
spc700_testh((ya ^ dp ^ (word)r) & 0x1000);
|
||||
spc700_testz((word)r == 0);
|
||||
spc700_testc(r >= 0x10000);
|
||||
spc700->regs.a = r;
|
||||
spc700->regs.y = r >> 8;
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
void spc700_op_and_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a &= arg;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_ix(void) {
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_and_ix_iy(void) {
|
||||
word i;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
x &= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_and_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x &= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_and_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x &= arg0;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_and1_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
if(spc700->regs.p & SPF_C) {
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(!(x & (1 << bit))) {
|
||||
spc700_clrc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_and1_notbit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
if(spc700->regs.p & SPF_C) {
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(x & (1 << bit)) {
|
||||
spc700_clrc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
void spc700_op_cmp(byte x, byte y) {
|
||||
short r = (short)x - (short)y;
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz((byte)r == 0);
|
||||
spc700_testc(r >= 0);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_ix(void) {
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_ix_iy(void) {
|
||||
spc700_op_cmp(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
spc700_op_cmp(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
spc700_op_cmp(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_x_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.x, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_x_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.x, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_x_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.x, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_y_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.y, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_y_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.y, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_y_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.y, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_cmpw_ya_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word ya = ((spc700->regs.y << 8) | spc700->regs.a);
|
||||
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
|
||||
long r = (long)ya - (long)dp;
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testz((word)r == 0);
|
||||
spc700_testc(r >= 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
void spc700_op_eor_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a ^= arg;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_ix(void) {
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_eor_ix_iy(void) {
|
||||
word i;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
x ^= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_eor_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x ^= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_eor_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x ^= arg0;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_eor1_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(spc700->regs.p & SPF_C) {
|
||||
if(x & (1 << bit)) {
|
||||
spc700_clrc();
|
||||
}
|
||||
} else {
|
||||
if(x & (1 << bit)) {
|
||||
spc700_setc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_not1_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
x ^= (1 << bit);
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, addr, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
void spc700_op_clrc(void) {
|
||||
spc700_clrc();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_setc(void) {
|
||||
spc700_setc();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_notc(void) {
|
||||
spc700->regs.p ^= SPF_C;
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_clrv(void) {
|
||||
spc700_clrv();
|
||||
spc700_clrh();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_clrp(void) {
|
||||
spc700_clrp();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_setp(void) {
|
||||
spc700_setp();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_di(void) {
|
||||
spc700_clri();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_ei(void) {
|
||||
spc700_seti();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
void spc700_op_inc_a(void) {
|
||||
spc700->regs.a++;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_inc_x(void) {
|
||||
spc700->regs.x++;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_inc_y(void) {
|
||||
spc700->regs.y++;
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_inc_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg) + 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_inc_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg) + 1;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_inc_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg) + 1;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_dec_a(void) {
|
||||
spc700->regs.a--;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_dec_x(void) {
|
||||
spc700->regs.x--;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_dec_y(void) {
|
||||
spc700->regs.y--;
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_dec_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg) - 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_dec_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg) - 1;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_dec_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg) - 1;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_incw_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg) + 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, r);
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_decw_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg) - 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, r);
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
void spc700_op_nop(void) {
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_sleep(void) {
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_stop(void) {
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_xcn_a(void) {
|
||||
spc700->regs.a = (spc700->regs.a >> 4) | (spc700->regs.a << 4);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_daa_a(void) {
|
||||
int a = spc700->regs.a;
|
||||
if(((a ) & 15) > 9)a += 6;
|
||||
if(((a >> 4) & 15) > 9)a += 6 << 4;
|
||||
spc700->regs.a = a;
|
||||
spc700_testn(a & 0x80);
|
||||
spc700_testz(a == 0);
|
||||
spc700_testc(a >= 0x0100);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_das_a(void) {
|
||||
int a = spc700->regs.a;
|
||||
if(((a ) & 15) > 9)a -= 6;
|
||||
if(((a >> 4) & 15) > 9)a -= 6 << 4;
|
||||
spc700->regs.a = a;
|
||||
spc700_testn(a & 0x80);
|
||||
spc700_testz(a == 0);
|
||||
spc700_testc(a < 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_set0_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x01;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr0_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x01;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set1_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x02;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr1_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x02;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set2_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x04;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr2_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x04;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set3_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x08;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr3_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x08;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set4_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x10;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr4_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x10;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set5_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x20;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr5_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x20;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set6_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x40;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr6_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x40;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set7_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x80;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr7_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x80;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_tset1_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
x |= spc700->regs.a;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_tclr1_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
x &= ~spc700->regs.a;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mul_ya(void) {
|
||||
word ya;
|
||||
ya = spc700->regs.y * spc700->regs.a;
|
||||
spc700->regs.a = ya;
|
||||
spc700->regs.y = ya >> 8;
|
||||
spc700_testn(ya & 0x8000);
|
||||
spc700_testz(ya == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(9);
|
||||
}
|
||||
|
||||
/*
|
||||
v/h flags not set, may have result backwards
|
||||
(a and y may need to be swapped)
|
||||
*/
|
||||
void spc700_op_div_ya_x(void) {
|
||||
word ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
if(spc700->regs.x == 0) {
|
||||
spc700->regs.a = 0;
|
||||
spc700->regs.y = 0;
|
||||
} else {
|
||||
spc700->regs.a = ya / spc700->regs.x;
|
||||
spc700->regs.y = ya % spc700->regs.x;
|
||||
}
|
||||
ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
spc700_testn(ya & 0x8000);
|
||||
spc700_testz(ya == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(12);
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
void spc700_op_mov_a_x(void) {
|
||||
spc700->regs.a = spc700->regs.x;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_y(void) {
|
||||
spc700->regs.a = spc700->regs.y;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_a(void) {
|
||||
spc700->regs.x = spc700->regs.a;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_a(void) {
|
||||
spc700->regs.y = spc700->regs.a;
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_sp(void) {
|
||||
spc700->regs.x = spc700->regs.sp;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_sp_x(void) {
|
||||
spc700->regs.sp = spc700->regs.x;
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, arg0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = arg;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.x = arg;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.y = arg;
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_ix_a(void) {
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, spc700->regs.a);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_ixinc_a(void) {
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, spc700->regs.a);
|
||||
spc700->regs.x++;
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_a(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dpx_a(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addr_a(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addrx_a(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDRX, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addry_a(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDRY, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mov_idpx_a(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->mem_write(APUMODE_IDPX, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(7);
|
||||
}
|
||||
|
||||
void spc700_op_mov_idpy_a(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->mem_write(APUMODE_IDPY, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(7);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_x(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dpy_x(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DPY, MEMSIZE_BYTE, arg, spc700->regs.x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addr_x(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_y(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.y);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dpx_y(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, spc700->regs.y);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addr_y(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.y);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_ix(void) {
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_ixinc(void) {
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700->regs.x++;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_dpy(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.x = spc700->mem_read(APUMODE_DPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.y = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.y = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.y = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_ya_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word ya;
|
||||
ya = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
|
||||
spc700->regs.a = ya;
|
||||
spc700->regs.y = ya >> 8;
|
||||
spc700_testn(ya & 0x8000);
|
||||
spc700_testz(ya == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_ya(void) {
|
||||
spc700_prefetchb();
|
||||
word ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, ya);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov1_c_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
spc700_testc(x & (1 << bit));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov1_bit_c(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(spc700->regs.p & SPF_C) {
|
||||
x |= (1 << bit);
|
||||
} else {
|
||||
x &= ~(1 << bit);
|
||||
}
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, addr, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
void spc700_op_or_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a |= arg;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_ix(void) {
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_or_ix_iy(void) {
|
||||
word i;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
x |= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x |= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_or_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x |= arg0;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or1_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
if(!(spc700->regs.p & SPF_C)) {
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(x & (1 << bit)) {
|
||||
spc700_setc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or1_notbit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
if(!(spc700->regs.p & SPF_C)) {
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(!(x & (1 << bit))) {
|
||||
spc700_setc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
void spc700_op_bra(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_bcc(void) {
|
||||
spc700_prefetchb();
|
||||
if(!(spc700->regs.p & SPF_C)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bcs(void) {
|
||||
spc700_prefetchb();
|
||||
if((spc700->regs.p & SPF_C)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_beq(void) {
|
||||
spc700_prefetchb();
|
||||
if((spc700->regs.p & SPF_Z)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bmi(void) {
|
||||
spc700_prefetchb();
|
||||
if((spc700->regs.p & SPF_N)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bne(void) {
|
||||
spc700_prefetchb();
|
||||
if(!(spc700->regs.p & SPF_Z)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bpl(void) {
|
||||
spc700_prefetchb();
|
||||
if(!(spc700->regs.p & SPF_N)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bvc(void) {
|
||||
spc700_prefetchb();
|
||||
if(!(spc700->regs.p & SPF_V)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bvs(void) {
|
||||
spc700_prefetchb();
|
||||
if((spc700->regs.p & SPF_V)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
#define spc700_op_bbc(__n) \
|
||||
void spc700_op_bbc##__n##(void) { \
|
||||
spc700_prefetch2b(); \
|
||||
byte r; \
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0); \
|
||||
if(!(r & (1 << __n))) { \
|
||||
spc700->regs.pc += (signed char)arg1; \
|
||||
add_apu_cycles(7); \
|
||||
} else { \
|
||||
add_apu_cycles(5); \
|
||||
} \
|
||||
spc700_incpc(3); \
|
||||
}
|
||||
|
||||
#define spc700_op_bbs(__n) \
|
||||
void spc700_op_bbs##__n##(void) { \
|
||||
spc700_prefetch2b(); \
|
||||
byte r; \
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0); \
|
||||
if(r & (1 << __n)) { \
|
||||
spc700->regs.pc += (signed char)arg1; \
|
||||
add_apu_cycles(7); \
|
||||
} else { \
|
||||
add_apu_cycles(5); \
|
||||
} \
|
||||
spc700_incpc(3); \
|
||||
}
|
||||
|
||||
spc700_op_bbc(0)
|
||||
spc700_op_bbc(1)
|
||||
spc700_op_bbc(2)
|
||||
spc700_op_bbc(3)
|
||||
spc700_op_bbc(4)
|
||||
spc700_op_bbc(5)
|
||||
spc700_op_bbc(6)
|
||||
spc700_op_bbc(7)
|
||||
|
||||
spc700_op_bbs(0)
|
||||
spc700_op_bbs(1)
|
||||
spc700_op_bbs(2)
|
||||
spc700_op_bbs(3)
|
||||
spc700_op_bbs(4)
|
||||
spc700_op_bbs(5)
|
||||
spc700_op_bbs(6)
|
||||
spc700_op_bbs(7)
|
||||
|
||||
void spc700_op_cbne_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
if(r != spc700->regs.a) {
|
||||
spc700->regs.pc += (signed char)arg1;
|
||||
add_apu_cycles(7);
|
||||
} else {
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
spc700_incpc(3);
|
||||
}
|
||||
|
||||
void spc700_op_cbne_dpx(void) {
|
||||
spc700_prefetch2b();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg0);
|
||||
if(r != spc700->regs.a) {
|
||||
spc700->regs.pc += (signed char)arg1;
|
||||
add_apu_cycles(8);
|
||||
} else {
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
spc700_incpc(3);
|
||||
}
|
||||
|
||||
void spc700_op_dbnz_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0) - 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg0, r);
|
||||
if(r != 0) {
|
||||
spc700->regs.pc += (signed char)arg1;
|
||||
add_apu_cycles(7);
|
||||
} else {
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
spc700_incpc(3);
|
||||
}
|
||||
|
||||
void spc700_op_dbnz_y(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.y--;
|
||||
if(spc700->regs.y != 0) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(6);
|
||||
} else {
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_jmp_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.pc = arg;
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_jmp_iaddrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.pc = spc700->mem_read(APUMODE_IADDRX, MEMSIZE_WORD, arg);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_call(void) {
|
||||
spc700_prefetchw();
|
||||
word r = spc700->regs.pc + 3;
|
||||
spc700_incpc(3);
|
||||
spc700->stack_write(r);
|
||||
spc700->stack_write(r >> 8);
|
||||
spc700->regs.pc = arg;
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_pcall(void) {
|
||||
spc700_prefetchb();
|
||||
word r = spc700->regs.pc + 2;
|
||||
spc700->stack_write(r);
|
||||
spc700->stack_write(r >> 8);
|
||||
spc700->regs.pc = 0xff00 | arg;
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_0(void) {
|
||||
dprintf("* spc700 opcode tcall 0 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_1(void) {
|
||||
dprintf("* spc700 opcode tcall 1 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_2(void) {
|
||||
dprintf("* spc700 opcode tcall 2 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_3(void) {
|
||||
dprintf("* spc700 opcode tcall 3 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_4(void) {
|
||||
dprintf("* spc700 opcode tcall 4 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_5(void) {
|
||||
dprintf("* spc700 opcode tcall 5 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_6(void) {
|
||||
dprintf("* spc700 opcode tcall 6 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_7(void) {
|
||||
dprintf("* spc700 opcode tcall 7 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_8(void) {
|
||||
dprintf("* spc700 opcode tcall 8 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_9(void) {
|
||||
dprintf("* spc700 opcode tcall 9 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_10(void) {
|
||||
dprintf("* spc700 opcode tcall 10 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_11(void) {
|
||||
dprintf("* spc700 opcode tcall 11 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_12(void) {
|
||||
dprintf("* spc700 opcode tcall 12 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_13(void) {
|
||||
dprintf("* spc700 opcode tcall 13 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_14(void) {
|
||||
dprintf("* spc700 opcode tcall 14 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_15(void) {
|
||||
dprintf("* spc700 opcode tcall 15 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_brk(void) {
|
||||
dprintf("* spc700 opcode brk not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_ret(void) {
|
||||
word r;
|
||||
r = spc700->stack_read();
|
||||
r |= spc700->stack_read() << 8;
|
||||
spc700->regs.pc = r;
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_reti(void) {
|
||||
word r;
|
||||
spc700->regs.p = spc700->stack_read();
|
||||
r = spc700->stack_read();
|
||||
r |= spc700->stack_read() << 8;
|
||||
spc700->regs.pc = r;
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
byte spc700_op_sbc(byte x, byte y) {
|
||||
short r = (short)x - (short)y - (short)(!(spc700->regs.p & SPF_C));
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testv(((x ^ y) & 0x80) && ((x ^ (byte)r) & 0x80));
|
||||
spc700_testh(((x ^ y ^ (byte)r) & 0x10) == 0);
|
||||
spc700_testz((byte)r == 0);
|
||||
spc700_testc(r >= 0);
|
||||
return (byte)r;
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_ix(void) {
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_ix_iy(void) {
|
||||
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_subw_ya_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
|
||||
long r = (long)ya - (long)dp;
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testv(((ya ^ dp) & 0x8000) && ((ya ^ (word)r) & 0x8000));
|
||||
spc700_testh(((ya ^ dp ^ (word)r) & 0x1000) == 0);
|
||||
spc700_testz((word)r == 0);
|
||||
spc700_testc(r >= 0);
|
||||
spc700->regs.a = r;
|
||||
spc700->regs.y = r >> 8;
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
void spc700_op_asl_a(void) {
|
||||
spc700_testc(spc700->regs.a & 0x80);
|
||||
spc700->regs.a <<= 1;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_asl_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_asl_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_asl_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_lsr_a(void) {
|
||||
spc700_testc(spc700->regs.a & 0x01);
|
||||
spc700->regs.a >>= 1;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_lsr_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_lsr_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_lsr_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_rol_a(void) {
|
||||
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
|
||||
spc700_testc(spc700->regs.a & 0x80);
|
||||
spc700->regs.a <<= 1;
|
||||
spc700->regs.a |= c;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_rol_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_rol_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_rol_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_ror_a(void) {
|
||||
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
|
||||
spc700_testc(spc700->regs.a & 0x01);
|
||||
spc700->regs.a >>= 1;
|
||||
spc700->regs.a |= c;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_ror_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_ror_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_ror_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
void spc700_op_push_a(void) {
|
||||
spc700->stack_write(spc700->regs.a);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_push_x(void) {
|
||||
spc700->stack_write(spc700->regs.x);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_push_y(void) {
|
||||
spc700->stack_write(spc700->regs.y);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_push_p(void) {
|
||||
spc700->stack_write(spc700->regs.p);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_pop_a(void) {
|
||||
spc700->regs.a = spc700->stack_read();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_pop_x(void) {
|
||||
spc700->regs.x = spc700->stack_read();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_pop_y(void) {
|
||||
spc700->regs.y = spc700->stack_read();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_pop_p(void) {
|
||||
spc700->regs.p = spc700->stack_read();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
spc700->regs.dp = (spc700->regs.p & SPF_P)?0x0100:0x0000;
|
||||
}
|
||||
+424
@@ -0,0 +1,424 @@
|
||||
#define NO_SPC700
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define null 0xffffffff
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned long ulong;
|
||||
typedef void (*vfunc)(void);
|
||||
|
||||
#define SH_2 1
|
||||
#define SH_4 2
|
||||
#define SH_8 3
|
||||
#define SH_16 4
|
||||
#define SH_32 5
|
||||
#define SH_64 6
|
||||
#define SH_128 7
|
||||
#define SH_256 8
|
||||
#define SH_512 9
|
||||
#define SH_1024 10
|
||||
#define SH_2048 11
|
||||
#define SH_4096 12
|
||||
|
||||
/*************************
|
||||
*** general functions ***
|
||||
************************/
|
||||
|
||||
void alert(char *s, ...);
|
||||
|
||||
/************************
|
||||
*** joypad functions ***
|
||||
***********************/
|
||||
|
||||
void UpdateJoypad(void);
|
||||
|
||||
typedef struct {
|
||||
byte a, b, x, y;
|
||||
byte l, r;
|
||||
byte select, start;
|
||||
byte up, down, left, right;
|
||||
|
||||
byte read_pos;
|
||||
}joypad_state;
|
||||
|
||||
/******************
|
||||
*** deprecated ***
|
||||
*****************/
|
||||
|
||||
typedef struct {
|
||||
bool rom_loaded;
|
||||
ulong sram_save_tick_count;
|
||||
char rom_name[4096], sram_name[4096];
|
||||
}emustate;
|
||||
|
||||
/***********************
|
||||
*** video functions ***
|
||||
**********************/
|
||||
|
||||
void video_setmode(bool fullscreen, word width, word height);
|
||||
void video_setsnesmode(void);
|
||||
|
||||
#define LINE_DOUBLEWIDTH 1
|
||||
#define LINE_DOUBLEHEIGHT 2
|
||||
|
||||
//global export: render
|
||||
typedef struct {
|
||||
word display_width, display_height;
|
||||
word snes_width, snes_height;
|
||||
bool fullscreen;
|
||||
bool show_menu;
|
||||
|
||||
byte frame_skip;
|
||||
byte frame_count;
|
||||
|
||||
bool bg1_enabled[3], bg2_enabled[3], bg3_enabled[3], bg4_enabled[3], oam_enabled[5];
|
||||
|
||||
byte line[239];
|
||||
}videostate;
|
||||
|
||||
/***************************
|
||||
*** debugging functions ***
|
||||
**************************/
|
||||
|
||||
#define DEBUGMSG_INFO 0
|
||||
#define DEBUGMSG_CPU 1
|
||||
#define DEBUGMSG_APU 2
|
||||
|
||||
#define DEBUGWRITE_NONE 0
|
||||
#define DEBUGWRITE_CONSOLE 1
|
||||
#define DEBUGWRITE_TRACE 2
|
||||
|
||||
enum {
|
||||
DEBUGMODE_DISABLED = 0,
|
||||
DEBUGMODE_WAIT,
|
||||
DEBUGMODE_RUN,
|
||||
DEBUGMODE_CPUSTEP,
|
||||
DEBUGMODE_APUSTEP,
|
||||
DEBUGMODE_PROCEED
|
||||
};
|
||||
|
||||
#define DEBUG_BGENABLED_ALL 0
|
||||
#define DEBUG_BGENABLED_PRI0 1
|
||||
#define DEBUG_BGENABLED_PRI1 2
|
||||
#define DEBUG_BGENABLED_PRI2 3
|
||||
#define DEBUG_BGENABLED_PRI3 4
|
||||
|
||||
#define BP_OFF 0
|
||||
#define BP_READ 1
|
||||
#define BP_WRITE 2
|
||||
#define BP_EXEC 4
|
||||
#define BP_VAL 8
|
||||
|
||||
#define BPSRC_MEM 0
|
||||
#define BPSRC_VRAM 1
|
||||
#define BPSRC_CGRAM 2
|
||||
#define BPSRC_OAM 3
|
||||
#define BPSRC_SPCRAM 4
|
||||
|
||||
void debug_test_breakpoint(byte source, byte flag, ulong offset, byte value);
|
||||
#define debug_get_state() debugger.mode
|
||||
#define debugger_enabled() ((debugger.mode == DEBUGMODE_DISABLED)?false:true)
|
||||
#define debug_test_bp(__source, __flag, __offset, __value) \
|
||||
if(debug_get_state() != DEBUGMODE_DISABLED) { \
|
||||
debug_test_breakpoint(__source, __flag, __offset, __value); \
|
||||
}
|
||||
void debug_set_state(byte state);
|
||||
void dprintf(char *s, ...);
|
||||
void dprintf(ulong msg_type, char *s, ...);
|
||||
void debug_refresh_mem(void);
|
||||
void debug_refresh_bp(void);
|
||||
void debug_update_status(void);
|
||||
ulong debug_write_status(void);
|
||||
|
||||
typedef struct {
|
||||
byte mode;
|
||||
|
||||
ulong mem_ptr; //position of wram ptr for debug window
|
||||
bool disas_cpu_op, disas_apu_op;
|
||||
bool refresh_mem;
|
||||
bool refresh_bp;
|
||||
bool refresh_status;
|
||||
|
||||
bool cpu_op_executed;
|
||||
bool apu_op_executed;
|
||||
|
||||
bool output_cpu_instrs;
|
||||
bool output_apu_instrs;
|
||||
bool output_debug_info;
|
||||
bool trace_enabled;
|
||||
bool trace_output_enabled;
|
||||
|
||||
bool lock_up, lock_down, lock_left, lock_right;
|
||||
bool lock_a, lock_b, lock_x, lock_y;
|
||||
bool lock_l, lock_r, lock_select, lock_start;
|
||||
|
||||
struct {
|
||||
ulong offset;
|
||||
byte flags;
|
||||
byte source;
|
||||
byte value;
|
||||
ulong hit_count;
|
||||
}bp_list[16];
|
||||
|
||||
FILE *trace_fp;
|
||||
}debugstate;
|
||||
|
||||
/*********************
|
||||
*** ppu functions ***
|
||||
********************/
|
||||
|
||||
#define BG1 0x00
|
||||
#define BG2 0x01
|
||||
#define BG3 0x02
|
||||
#define BG4 0x03
|
||||
#define OAM 0x04
|
||||
#define SS_BG1 0x80
|
||||
#define SS_BG2 0x81
|
||||
#define SS_BG3 0x82
|
||||
#define SS_BG4 0x83
|
||||
#define SS_OAM 0x84
|
||||
#define BACK 0x05
|
||||
|
||||
#define CLIPMODE_IN 0
|
||||
#define CLIPMODE_OUT 1
|
||||
|
||||
#define WINDOWMASK_OR 0
|
||||
#define WINDOWMASK_AND 1
|
||||
#define WINDOWMASK_XOR 2
|
||||
#define WINDOWMASK_XNOR 3
|
||||
|
||||
#define COLORMODE_ADD 0
|
||||
#define COLORMODE_SUB 1
|
||||
|
||||
typedef struct {
|
||||
word *screen; //internal buffer used to render 512x448 screen
|
||||
byte *vram; //65536 bytes
|
||||
byte *cgram; //512 bytes
|
||||
byte *oam; //544 bytes mirrored as 1024 bytes (512-543 are mirrored to 544-1023)
|
||||
word *light_table; //16 * 32768 -- applies display_brightness to bgr555 color data
|
||||
//ppu.mosaic_table[ppu.mosaic_size][x] == (x / (ppu.mosaic_size + 1)) * (ppu.mosaic_size + 1)
|
||||
word *mosaic_table[16];
|
||||
|
||||
ulong ppu_cycles, ppu_prev_cycles; //used in ppu_update_scanline()
|
||||
|
||||
bool display_disable; //$2100 bit 7
|
||||
byte display_brightness; //$2100 bits 0-3
|
||||
|
||||
bool overscan;
|
||||
byte visible_scanlines;
|
||||
bool sprite_halve;
|
||||
bool interlace, toggle_interlace;
|
||||
byte interlace_frame; //0 or 1, used to alternate between scanlines rendered
|
||||
|
||||
bool bg_enabled[5];
|
||||
bool ss_bg_enabled[5];
|
||||
byte mosaic_size;
|
||||
bool mosaic_enabled[4];
|
||||
word bg_tilemap_loc[4];
|
||||
byte bg_tile_size[4];
|
||||
byte bg_tilemap_size[4];
|
||||
word bg_tiledata_loc[4];
|
||||
word oam_tiledata_loc;
|
||||
byte bg_priority_mode;
|
||||
byte oam_base_size;
|
||||
byte oam_name_sel;
|
||||
byte bg_mode;
|
||||
|
||||
word hline_pos; //0-255: inside vblank, 256-339: outside vblank
|
||||
word vline_pos; //0-223: inside vblank, 224-261: outside vblank, 180 cycles/scanline
|
||||
bool irq_triggered; //for $4211 read
|
||||
bool virq_triggered; //prevent recursive calling
|
||||
bool hirq_triggered; //prevent recursive calling
|
||||
word vram_write_pos; //holds value at $2116
|
||||
word vram_write_buffer;
|
||||
word vram_read_buffer;
|
||||
word vram_remap_mode;
|
||||
word vram_inc_size; //amount to increment vram_write_pos by
|
||||
byte vram_inc_reg; //increment on 2118 (0) or 2119 (1)
|
||||
word cgram_write_pos; //holds value at $2121 (multiplied by 2)
|
||||
word oam_write_pos; //holds value at $2102/$2103 (multiplied by 2)
|
||||
ulong wram_write_pos; //holds value at $2181-$2183
|
||||
|
||||
word bg_hscroll_pos[4]; //$210d-$2114
|
||||
word bg_vscroll_pos[4];
|
||||
word m7hofs, m7vofs;
|
||||
|
||||
byte mul_a, mul_b;
|
||||
word div_a;
|
||||
byte div_b;
|
||||
word r_4214, r_4216;
|
||||
ulong r_2134;
|
||||
|
||||
bool bg_window1_enabled[5];
|
||||
bool bg_window2_enabled[5];
|
||||
byte bg_window1_clipmode[5];
|
||||
byte bg_window2_clipmode[5];
|
||||
|
||||
byte window1_left, window1_right;
|
||||
byte window2_left, window2_right;
|
||||
|
||||
bool bg_windowing_enabled[5];
|
||||
bool ss_bg_windowing_enabled[5];
|
||||
byte bg_window_mask[5];
|
||||
|
||||
bool color_window1_enabled, color_window2_enabled;
|
||||
bool color_window1_clipmode, color_window2_clipmode;
|
||||
byte color_window_mask;
|
||||
byte color_mask, ss_color_mask;
|
||||
byte addsub_mode;
|
||||
byte color_mode, color_halve;
|
||||
bool bg_color_enabled[6];
|
||||
byte color_r, color_g, color_b;
|
||||
|
||||
byte active_hdma_channels;
|
||||
word hdma_scanlines_remaining[8];
|
||||
word hdma_index_pointer[8];
|
||||
bool hdma_completed[8];
|
||||
|
||||
bool vcounter_enabled, hcounter_enabled;
|
||||
word hirq_pos, virq_pos;
|
||||
|
||||
bool auto_joypad_read;
|
||||
byte joypad_strobe_value;
|
||||
|
||||
byte latch_toggle;
|
||||
word latch_vpos, latch_hpos;
|
||||
|
||||
word m7a, m7b, m7c, m7d, m7x, m7y;
|
||||
|
||||
byte mode7_repeat;
|
||||
bool mode7_extbg;
|
||||
bool mode7_vflip, mode7_hflip;
|
||||
|
||||
byte io4201;
|
||||
bool counter_latched;
|
||||
|
||||
byte mmio_mem_43xx[0x80];
|
||||
}ppustate;
|
||||
|
||||
/*********************
|
||||
*** cpu functions ***
|
||||
********************/
|
||||
|
||||
#define CPUSTATE_RUN 0
|
||||
#define CPUSTATE_DMA 1
|
||||
#define CPUSTATE_STP 2
|
||||
|
||||
#define MEMSPEED_SLOWROM 0
|
||||
#define MEMSPEED_FASTROM 1
|
||||
|
||||
void add_apu_cycles(int n);
|
||||
|
||||
//g65816 cpu flags
|
||||
#define PF_N 0x80
|
||||
#define PF_V 0x40
|
||||
#define PF_M 0x20
|
||||
#define PF_X 0x10
|
||||
#define PF_D 0x08
|
||||
#define PF_I 0x04
|
||||
#define PF_Z 0x02
|
||||
#define PF_C 0x01
|
||||
|
||||
//spc700 cpu flags
|
||||
#define SPF_N 0x80
|
||||
#define SPF_V 0x40
|
||||
#define SPF_P 0x20
|
||||
#define SPF_B 0x10
|
||||
#define SPF_H 0x08
|
||||
#define SPF_I 0x04
|
||||
#define SPF_Z 0x02
|
||||
#define SPF_C 0x01
|
||||
|
||||
/************************
|
||||
*** memory functions ***
|
||||
***********************/
|
||||
|
||||
#define MEMSPEED_FAST 6
|
||||
#define MEMSPEED_SLOW 8
|
||||
#define MEMSPEED_XSLOW 12
|
||||
|
||||
#define MEMMAP_HIROM 0x01
|
||||
#define MEMMAP_LOROM 0x02
|
||||
|
||||
#define MEMACCESS_NORMAL 0
|
||||
#define MEMACCESS_CPU 1
|
||||
#define MEMACCESS_DEBUGGER 1
|
||||
|
||||
enum {
|
||||
MEMMODE_NONE = 0, //(no address translation)
|
||||
MEMMODE_DP, //dp
|
||||
MEMMODE_DPX, //dp,x
|
||||
MEMMODE_DPY, //dp,y
|
||||
MEMMODE_IDP, //(dp)
|
||||
MEMMODE_IDPX, //(dp,x)
|
||||
MEMMODE_IDPY, //(dp),y
|
||||
MEMMODE_ILDP, //[dp]
|
||||
MEMMODE_ILDPY, //[dp],y
|
||||
MEMMODE_ADDR, //addr
|
||||
MEMMODE_ADDRX, //addr,x
|
||||
MEMMODE_ADDRY, //addr,y
|
||||
MEMMODE_IADDRX, //(addr,x)
|
||||
MEMMODE_ILADDR, //[addr]
|
||||
MEMMODE_LONG, //long
|
||||
MEMMODE_LONGX, //long, x
|
||||
MEMMODE_SR, //sr,s
|
||||
MEMMODE_ISRY, //(sr,s),y
|
||||
//exchanges pbr for dbr, disables address mirroring
|
||||
MEMMODE_ADDR_PC, //addr
|
||||
MEMMODE_IADDR_PC, //(addr)
|
||||
MEMMODE_IADDRX_PC, //(addr,x)
|
||||
MEMMODE_ILADDR_PC, //[addr]
|
||||
//opcode memory access types
|
||||
OPMODE_DBR,
|
||||
OPMODE_PBR,
|
||||
OPMODE_LONG,
|
||||
OPMODE_DP,
|
||||
OPMODE_SP,
|
||||
OPMODE_ADDR
|
||||
};
|
||||
|
||||
#define MEMSIZE_BYTE 1
|
||||
#define MEMSIZE_WORD 2
|
||||
#define MEMSIZE_LONG 3
|
||||
|
||||
/***********************
|
||||
*** misc. functions ***
|
||||
**********************/
|
||||
|
||||
//main.cpp
|
||||
void InitSNES(void);
|
||||
void RunSNES(void);
|
||||
void ResetSNES(void);
|
||||
|
||||
//cpu/g65816_ops_stack.cpp
|
||||
//ulong g65816_stackread(byte size);
|
||||
//void g65816_stackwrite(byte size, ulong value);
|
||||
|
||||
//cpu/d65816.cpp
|
||||
void disas_g65816_op(void);
|
||||
|
||||
//apu/dspc700.cpp
|
||||
void disas_spc700_op(void);
|
||||
|
||||
//ppu/mmio.cpp
|
||||
byte mmio_read(word addr);
|
||||
void mmio_write(word addr, byte value);
|
||||
|
||||
//ppu/ppu.cpp
|
||||
void ppu_render_scanline(void);
|
||||
void ppu_update_scanline(void);
|
||||
byte oam_read(word addr);
|
||||
void oam_write(word addr, byte value);
|
||||
void PPUInit(byte first_time);
|
||||
void ppu_update_dma(void);
|
||||
|
||||
//win/render.cpp
|
||||
void UpdateDisplay(void);
|
||||
|
||||
//misc/libstr.cpp
|
||||
ulong strhex(char *str);
|
||||
ulong strdec(char *str);
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "../base.h"
|
||||
#include "bridge.h"
|
||||
port_bridge *cpu_apu_bridge;
|
||||
|
||||
port_bridge::port_bridge() {
|
||||
cputoapu_port[0] = cputoapu_port[1] =
|
||||
cputoapu_port[2] = cputoapu_port[3] =
|
||||
aputocpu_port[0] = aputocpu_port[1] =
|
||||
aputocpu_port[2] = aputocpu_port[3] = 0;
|
||||
}
|
||||
|
||||
byte port_bridge::cpu_read(byte port) {
|
||||
return aputocpu_port[port & 3];
|
||||
}
|
||||
|
||||
byte port_bridge::apu_read(byte port) {
|
||||
return cputoapu_port[port & 3];
|
||||
}
|
||||
|
||||
void port_bridge::cpu_write(byte port, byte value) {
|
||||
cputoapu_port[port & 3] = value;
|
||||
}
|
||||
|
||||
void port_bridge::apu_write(byte port, byte value) {
|
||||
aputocpu_port[port & 3] = value;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class port_bridge {
|
||||
public:
|
||||
byte cputoapu_port[4]; //holds values written to CPU at $2140-$2143
|
||||
byte aputocpu_port[4]; //holds values written to APU at $f4-$f7
|
||||
|
||||
port_bridge();
|
||||
byte cpu_read(byte port);
|
||||
byte apu_read(byte port);
|
||||
void cpu_write(byte port, byte value);
|
||||
void apu_write(byte port, byte value);
|
||||
};
|
||||
Binary file not shown.
Executable → Regular
+2
-2
@@ -1,2 +1,2 @@
|
||||
@mingw32-make -j 8
|
||||
@pause
|
||||
@nmake /NOLOGO
|
||||
@pause
|
||||
@@ -0,0 +1 @@
|
||||
@nmake /NOLOGO clean
|
||||
@@ -0,0 +1,339 @@
|
||||
#include "../base.h"
|
||||
#include "g65816.h"
|
||||
extern g65816 *gx816;
|
||||
extern debugstate debugger;
|
||||
|
||||
ulong _disas_relb(byte addr) {
|
||||
return gx816->regs.pc + (signed char)(addr + 2);
|
||||
}
|
||||
|
||||
ulong _disas_relw(word addr) {
|
||||
return gx816->regs.pc + (signed short)(addr + 3);
|
||||
}
|
||||
|
||||
char __disas_op_str[256];
|
||||
void __disas_op(byte op, byte op0, byte op1, byte op2) {
|
||||
char *s = (char*)__disas_op_str;
|
||||
switch(op) {
|
||||
case 0x00:sprintf(s, "brk #$%0.2x ", op0);break;
|
||||
case 0x01:sprintf(s, "ora ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x02:sprintf(s, "cop #$%0.2x ", op0);break;
|
||||
case 0x03:sprintf(s, "ora $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x04:sprintf(s, "tsb $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x05:sprintf(s, "ora $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x06:sprintf(s, "asl $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x07:sprintf(s, "ora [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x08:sprintf(s, "php ");break;
|
||||
case 0x09:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "ora #$%0.2x ", op0);
|
||||
else sprintf(s, "ora #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x0a:sprintf(s, "asl a ");break;
|
||||
case 0x0b:sprintf(s, "phd ");break;
|
||||
case 0x0c:sprintf(s, "tsb $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0d:sprintf(s, "ora $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0e:sprintf(s, "asl $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0f:sprintf(s, "ora $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x10:sprintf(s, "bpl $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x11:sprintf(s, "ora ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x12:sprintf(s, "ora ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x13:sprintf(s, "ora ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x14:sprintf(s, "trb $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x15:sprintf(s, "ora $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x16:sprintf(s, "asl $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x17:sprintf(s, "ora [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x18:sprintf(s, "clc ");break;
|
||||
case 0x19:sprintf(s, "ora $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x1a:sprintf(s, "inc ");break;
|
||||
case 0x1b:sprintf(s, "tcs ");break;
|
||||
case 0x1c:sprintf(s, "trb $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x1d:sprintf(s, "ora $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x1e:sprintf(s, "asl $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x1f:sprintf(s, "ora $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x20:sprintf(s, "jsr $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x21:sprintf(s, "and ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x22:sprintf(s, "jsl $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x23:sprintf(s, "and $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x24:sprintf(s, "bit $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x25:sprintf(s, "and $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x26:sprintf(s, "rol $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x27:sprintf(s, "and [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x28:sprintf(s, "plp ");break;
|
||||
case 0x29:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "and #$%0.2x ", op0);
|
||||
else sprintf(s, "and #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x2a:sprintf(s, "rol a ");break;
|
||||
case 0x2b:sprintf(s, "pld ");break;
|
||||
case 0x2c:sprintf(s, "bit $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2d:sprintf(s, "and $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2e:sprintf(s, "rol $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2f:sprintf(s, "and $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x30:sprintf(s, "bmi $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x31:sprintf(s, "and ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x32:sprintf(s, "and ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x33:sprintf(s, "and ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x34:sprintf(s, "bit $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x35:sprintf(s, "and $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x36:sprintf(s, "rol $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x37:sprintf(s, "and [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x38:sprintf(s, "sec ");break;
|
||||
case 0x39:sprintf(s, "and $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x3a:sprintf(s, "dec ");break;
|
||||
case 0x3b:sprintf(s, "tsc ");break;
|
||||
case 0x3c:sprintf(s, "bit $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3d:sprintf(s, "and $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3e:sprintf(s, "rol $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3f:sprintf(s, "and $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x40:sprintf(s, "rti ");break;
|
||||
case 0x41:sprintf(s, "eor ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x42:sprintf(s, "wdm ");break;
|
||||
case 0x43:sprintf(s, "eor $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x44:sprintf(s, "mvp $%0.2x,$%0.2x ", op1, op0);break;
|
||||
case 0x45:sprintf(s, "eor $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x46:sprintf(s, "lsr $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x47:sprintf(s, "eor [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x48:sprintf(s, "pha ");break;
|
||||
case 0x49:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "eor #$%0.2x ", op0);
|
||||
else sprintf(s, "eor #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x4a:sprintf(s, "lsr a ");break;
|
||||
case 0x4b:sprintf(s, "phk ");break;
|
||||
case 0x4c:sprintf(s, "jmp $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x4d:sprintf(s, "eor $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x4e:sprintf(s, "lsr $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x4f:sprintf(s, "eor $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x50:sprintf(s, "bvc $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x51:sprintf(s, "eor ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x52:sprintf(s, "eor ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x53:sprintf(s, "eor ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x54:sprintf(s, "mvn $%0.2x,$%0.2x ", op1, op0);break;
|
||||
case 0x55:sprintf(s, "eor $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x56:sprintf(s, "lsr $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x57:sprintf(s, "eor [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x58:sprintf(s, "cli ");break;
|
||||
case 0x59:sprintf(s, "eor $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x5a:sprintf(s, "phy ");break;
|
||||
case 0x5b:sprintf(s, "tcd ");break;
|
||||
case 0x5c:sprintf(s, "jml $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x5d:sprintf(s, "eor $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x5e:sprintf(s, "lsr $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x5f:sprintf(s, "eor $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x60:sprintf(s, "rts ");break;
|
||||
case 0x61:sprintf(s, "adc ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x62:sprintf(s, "per $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x63:sprintf(s, "adc $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x64:sprintf(s, "stz $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x65:sprintf(s, "adc $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x66:sprintf(s, "ror $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x67:sprintf(s, "adc [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x68:sprintf(s, "pla ");break;
|
||||
case 0x69:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "adc #$%0.2x ", op0);
|
||||
else sprintf(s, "adc #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x6a:sprintf(s, "ror a ");break;
|
||||
case 0x6b:sprintf(s, "rtl ");break;
|
||||
case 0x6c:sprintf(s, "jmp ($%0.4x) [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x6d:sprintf(s, "adc $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x6e:sprintf(s, "ror $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x6f:sprintf(s, "adc $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x70:sprintf(s, "bvs $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x71:sprintf(s, "adc ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x72:sprintf(s, "adc ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x73:sprintf(s, "adc ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x74:sprintf(s, "stz $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x75:sprintf(s, "adc $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x76:sprintf(s, "ror $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x77:sprintf(s, "adc [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x78:sprintf(s, "sei ");break;
|
||||
case 0x79:sprintf(s, "adc $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x7a:sprintf(s, "ply ");break;
|
||||
case 0x7b:sprintf(s, "tdc ");break;
|
||||
case 0x7c:sprintf(s, "jmp ($%0.4x,x) [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDRX_PC, (op0|op1<<8)));break;
|
||||
case 0x7d:sprintf(s, "adc $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x7e:sprintf(s, "ror $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x7f:sprintf(s, "adc $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x80:sprintf(s, "bra $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x81:sprintf(s, "sta ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x82:sprintf(s, "brl $%0.4x [$%0.6x]", _disas_relw(op0|op1<<8)&0xffff, _disas_relw(op0|op1<<8)&0xffffff);break;
|
||||
case 0x83:sprintf(s, "sta $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x84:sprintf(s, "sty $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x85:sprintf(s, "sta $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x86:sprintf(s, "stx $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x87:sprintf(s, "sta [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x88:sprintf(s, "dey ");break;
|
||||
case 0x89:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "bit #$%0.2x ", op0);
|
||||
else sprintf(s, "bit #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x8a:sprintf(s, "txa ");break;
|
||||
case 0x8b:sprintf(s, "phb ");break;
|
||||
case 0x8c:sprintf(s, "sty $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8d:sprintf(s, "sta $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8e:sprintf(s, "stx $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8f:sprintf(s, "sta $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x90:sprintf(s, "bcc $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x91:sprintf(s, "sta ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x92:sprintf(s, "sta ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x93:sprintf(s, "sta ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x94:sprintf(s, "sty $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x95:sprintf(s, "sta $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x96:sprintf(s, "stx $%0.2x,y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPY, op0));break;
|
||||
case 0x97:sprintf(s, "sta [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x98:sprintf(s, "tya ");break;
|
||||
case 0x99:sprintf(s, "sta $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x9a:sprintf(s, "txs ");break;
|
||||
case 0x9b:sprintf(s, "txy ");break;
|
||||
case 0x9c:sprintf(s, "stz $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x9d:sprintf(s, "sta $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x9e:sprintf(s, "stz $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x9f:sprintf(s, "sta $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xa0:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "ldy #$%0.2x ", op0);
|
||||
else sprintf(s, "ldy #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xa1:sprintf(s, "lda ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0xa2:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "ldx #$%0.2x ", op0);
|
||||
else sprintf(s, "ldx #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xa3:sprintf(s, "lda $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0xa4:sprintf(s, "ldy $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xa5:sprintf(s, "lda $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xa6:sprintf(s, "ldx $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xa7:sprintf(s, "lda [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0xa8:sprintf(s, "tay ");break;
|
||||
case 0xa9:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "lda #$%0.2x ", op0);
|
||||
else sprintf(s, "lda #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xaa:sprintf(s, "tax ");break;
|
||||
case 0xab:sprintf(s, "plb ");break;
|
||||
case 0xac:sprintf(s, "ldy $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xad:sprintf(s, "lda $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xae:sprintf(s, "ldx $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xaf:sprintf(s, "lda $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xb0:sprintf(s, "bcs $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0xb1:sprintf(s, "lda ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0xb2:sprintf(s, "lda ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0xb3:sprintf(s, "lda ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0xb4:sprintf(s, "ldy $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xb5:sprintf(s, "lda $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xb6:sprintf(s, "ldx $%0.2x,y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPY, op0));break;
|
||||
case 0xb7:sprintf(s, "lda [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0xb8:sprintf(s, "clv ");break;
|
||||
case 0xb9:sprintf(s, "lda $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xba:sprintf(s, "tsx ");break;
|
||||
case 0xbb:sprintf(s, "tyx ");break;
|
||||
case 0xbc:sprintf(s, "ldy $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xbd:sprintf(s, "lda $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xbe:sprintf(s, "ldx $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xbf:sprintf(s, "lda $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xc0:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "cpy #$%0.2x ", op0);
|
||||
else sprintf(s, "cpy #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xc1:sprintf(s, "cmp ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0xc2:sprintf(s, "rep #$%0.2x ", op0);break;
|
||||
case 0xc3:sprintf(s, "cmp $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0xc4:sprintf(s, "cpy $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xc5:sprintf(s, "cmp $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xc6:sprintf(s, "dec $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xc7:sprintf(s, "cmp [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0xc8:sprintf(s, "iny ");break;
|
||||
case 0xc9:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "cmp #$%0.2x ", op0);
|
||||
else sprintf(s, "cmp #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xca:sprintf(s, "dex ");break;
|
||||
case 0xcb:sprintf(s, "wai ");break;
|
||||
case 0xcc:sprintf(s, "cpy $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xcd:sprintf(s, "cmp $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xce:sprintf(s, "dec $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xcf:sprintf(s, "cmp $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xd0:sprintf(s, "bne $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0xd1:sprintf(s, "cmp ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0xd2:sprintf(s, "cmp ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0xd3:sprintf(s, "cmp ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0xd4:sprintf(s, "pei ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0xd5:sprintf(s, "cmp $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xd6:sprintf(s, "dec $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xd7:sprintf(s, "cmp [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0xd8:sprintf(s, "cld ");break;
|
||||
case 0xd9:sprintf(s, "cmp $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xda:sprintf(s, "phx ");break;
|
||||
case 0xdb:sprintf(s, "stp ");break;
|
||||
case 0xdc:sprintf(s, "jmp [$%0.4x] [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ILADDR_PC, (op0|op1<<8)));break;
|
||||
case 0xdd:sprintf(s, "cmp $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xde:sprintf(s, "dec $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xdf:sprintf(s, "cmp $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xe0:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "cpx #$%0.2x ", op0);
|
||||
else sprintf(s, "cpx #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xe1:sprintf(s, "sbc ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0xe2:sprintf(s, "sep #$%0.2x ", op0);break;
|
||||
case 0xe3:sprintf(s, "sbc $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0xe4:sprintf(s, "cpx $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xe5:sprintf(s, "sbc $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xe6:sprintf(s, "inc $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xe7:sprintf(s, "sbc [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0xe8:sprintf(s, "inx ");break;
|
||||
case 0xe9:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "sbc #$%0.2x ", op0);
|
||||
else sprintf(s, "sbc #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xea:sprintf(s, "nop ");break;
|
||||
case 0xeb:sprintf(s, "xba ");break;
|
||||
case 0xec:sprintf(s, "cpx $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xed:sprintf(s, "sbc $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xee:sprintf(s, "inc $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xef:sprintf(s, "sbc $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xf0:sprintf(s, "beq $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0xf1:sprintf(s, "sbc ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0xf2:sprintf(s, "sbc ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0xf3:sprintf(s, "sbc ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0xf4:sprintf(s, "pea $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xf5:sprintf(s, "sbc $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xf6:sprintf(s, "inc $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xf7:sprintf(s, "sbc [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0xf8:sprintf(s, "sed ");break;
|
||||
case 0xf9:sprintf(s, "sbc $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xfa:sprintf(s, "plx ");break;
|
||||
case 0xfb:sprintf(s, "xce ");break;
|
||||
case 0xfc:sprintf(s, "jsr ($%0.4x,x) [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDRX_PC, (op0|op1<<8)));break;
|
||||
case 0xfd:sprintf(s, "sbc $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xfe:sprintf(s, "inc $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xff:sprintf(s, "sbc $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
}
|
||||
}
|
||||
|
||||
void disas_g65816_op(void) {
|
||||
byte op, op0, op1, op2;
|
||||
char str0[256], str1[256], str2[256];
|
||||
if(debug_write_status() == DEBUGWRITE_NONE)return;
|
||||
|
||||
op = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc, MEMACCESS_DEBUGGER);
|
||||
op0 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 1, MEMACCESS_DEBUGGER);
|
||||
op1 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 2, MEMACCESS_DEBUGGER);
|
||||
op2 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 3, MEMACCESS_DEBUGGER);
|
||||
|
||||
strcpy(__disas_op_str, "??? ");
|
||||
__disas_op(op, op0, op1, op2);
|
||||
|
||||
if(gx816->regs.e == true) {
|
||||
sprintf(str1, "%c%c%c%c%c%c%c%c E",
|
||||
(gx816->regs.p & 0x80)?'N':'n',
|
||||
(gx816->regs.p & 0x40)?'V':'v',
|
||||
(gx816->regs.p & 0x20)?'1':'0',
|
||||
(gx816->regs.p & 0x10)?'B':'b',
|
||||
(gx816->regs.p & 0x08)?'D':'d',
|
||||
(gx816->regs.p & 0x04)?'I':'i',
|
||||
(gx816->regs.p & 0x02)?'Z':'z',
|
||||
(gx816->regs.p & 0x01)?'C':'c');
|
||||
} else {
|
||||
sprintf(str1, "%c%c%c%c%c%c%c%c N",
|
||||
(gx816->regs.p & 0x80)?'N':'n',
|
||||
(gx816->regs.p & 0x40)?'V':'v',
|
||||
(gx816->regs.p & 0x20)?'M':'m',
|
||||
(gx816->regs.p & 0x10)?'X':'x',
|
||||
(gx816->regs.p & 0x08)?'D':'d',
|
||||
(gx816->regs.p & 0x04)?'I':'i',
|
||||
(gx816->regs.p & 0x02)?'Z':'z',
|
||||
(gx816->regs.p & 0x01)?'C':'c');
|
||||
}
|
||||
|
||||
dprintf(DEBUGMSG_CPU, "%0.6x %s A:%0.4x X:%0.4x Y:%0.4x S:%0.4x D:%0.4x DB:%0.2x %s", gx816->regs.pc, __disas_op_str,
|
||||
gx816->regs.a.w, gx816->regs.x, gx816->regs.y, gx816->regs.s,
|
||||
gx816->regs.d, gx816->regs.db, str1);
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "../base.h"
|
||||
#include "../timing/timing.h"
|
||||
#include "g65816.h"
|
||||
|
||||
extern emustate emu_state;
|
||||
extern debugstate debugger;
|
||||
extern ppustate ppu;
|
||||
extern snes_timer *snes_time;
|
||||
g65816 *gx816;
|
||||
|
||||
#include "g65816_ops.cpp"
|
||||
|
||||
void g65816::LoadROM(void) {
|
||||
FILE *fp;
|
||||
ulong fsize;
|
||||
word header_offset = 0;
|
||||
word cksum, icksum;
|
||||
byte t;
|
||||
int i;
|
||||
dprintf("* Loading [%s]...", emu_state.rom_name);
|
||||
|
||||
fp = fopen(emu_state.rom_name, "rb");
|
||||
if(!fp)return;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
fsize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
map = MEMMAP_LOROM;
|
||||
|
||||
if((fsize & 0x000fff) == 0x000200)header_offset = 512;
|
||||
|
||||
fseek(fp, 0x7fdc + header_offset, SEEK_SET);
|
||||
cksum = fgetc(fp) | fgetc(fp) << 8;
|
||||
icksum = fgetc(fp) | fgetc(fp) << 8;
|
||||
if(cksum + icksum == 0xffff)map = MEMMAP_LOROM;
|
||||
|
||||
fseek(fp, 0xffdc + header_offset, SEEK_SET);
|
||||
cksum = fgetc(fp) | fgetc(fp) << 8;
|
||||
icksum = fgetc(fp) | fgetc(fp) << 8;
|
||||
if(cksum + icksum == 0xffff)map = MEMMAP_HIROM;
|
||||
|
||||
fseek(fp, 0 + header_offset, SEEK_SET);
|
||||
fsize -= header_offset;
|
||||
|
||||
dprintf("* ROM detected as: %s", (map == MEMMAP_LOROM)?"LoROM":"HiROM");
|
||||
|
||||
InitializeROM(map);
|
||||
|
||||
fread(rom, 1, fsize, fp);
|
||||
|
||||
t = (mem_read(MEMMODE_NONE, MEMSIZE_BYTE, 0x00ffd8) & 7);
|
||||
switch(t) {
|
||||
case 0: sram_size = 0; break;
|
||||
case 1: sram_size = 2 * 1024;break;
|
||||
case 2: sram_size = 4 * 1024;break;
|
||||
case 3: sram_size = 8 * 1024;break;
|
||||
case 4: sram_size = 16 * 1024;break;
|
||||
case 5: sram_size = 32 * 1024;break;
|
||||
case 6: sram_size = 64 * 1024;break;
|
||||
case 7: sram_size = 128 * 1024;break;
|
||||
default:sram_size = 0; break;
|
||||
}
|
||||
dprintf("* SRAM Size: %dkb", sram_size / 1024);
|
||||
|
||||
//pbr is loaded with 00, and 16-bit pc is loaded with reset vector at 0xfffc
|
||||
//upon power on and at first reset
|
||||
regs.pc = mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00fffc);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(sram_size != 0) {
|
||||
fp = fopen(emu_state.sram_name, "rb");
|
||||
|
||||
//create sram file if it does not exist
|
||||
if(!fp) {
|
||||
fp = fopen(emu_state.sram_name, "wb");
|
||||
for(i=0;i<sram_size;i++) {
|
||||
fputc(0, fp);
|
||||
}
|
||||
fclose(fp);
|
||||
fp = fopen(emu_state.sram_name, "rb");
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
fsize = ftell(fp);
|
||||
|
||||
//fix sram size if it is smaller than actual size
|
||||
if(fsize < sram_size) {
|
||||
fclose(fp);
|
||||
fp = fopen(emu_state.sram_name, "rb+wb");
|
||||
fseek(fp, 0, SEEK_END);
|
||||
while(fsize < sram_size) {
|
||||
fputc(0, fp);
|
||||
fsize++;
|
||||
}
|
||||
fclose(fp);
|
||||
fp = fopen(emu_state.sram_name, "rb");
|
||||
}
|
||||
|
||||
//read file into sram
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(sram, 1, sram_size, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void g65816::PowerOn(byte first_time) {
|
||||
//default register states
|
||||
regs.a.w = regs.x = regs.y = 0x0000;
|
||||
regs.d = 0x0000;
|
||||
regs.s = 0x01ff;
|
||||
regs.db = 0x00;
|
||||
regs.p = 0x34;
|
||||
regs.e = true;
|
||||
snes_time->master_cycles = 0;
|
||||
memory_speed = MEMSPEED_SLOWROM;
|
||||
wai_interrupt_occurred = false;
|
||||
|
||||
InitializeWRAM(0x00);
|
||||
PPUInit(first_time);
|
||||
UpdateDisplay();
|
||||
snes_time->set_speed_map(MEMSPEED_SLOWROM);
|
||||
cpu_state = CPUSTATE_RUN;
|
||||
}
|
||||
|
||||
void g65816::Reset(void) {
|
||||
regs.x &= 0xff;
|
||||
regs.y &= 0xff;
|
||||
regs.s = 0x0100 | (regs.s & 0xff);
|
||||
regs.d = 0x0000;
|
||||
regs.db = 0x00;
|
||||
regs.p = 0x34;
|
||||
regs.e = true;
|
||||
regs.pc = mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00fffc);
|
||||
snes_time->master_cycles = 0;
|
||||
memory_speed = MEMSPEED_SLOWROM;
|
||||
wai_interrupt_occurred = false;
|
||||
|
||||
PPUInit(0); //0 blocks reallocating memory for vram, cgram, etc.
|
||||
UpdateDisplay();
|
||||
snes_time->set_speed_map(MEMSPEED_SLOWROM);
|
||||
cpu_state = CPUSTATE_RUN;
|
||||
}
|
||||
|
||||
/***********
|
||||
*** IRQ ***
|
||||
***********
|
||||
cycles:
|
||||
[1] pbr,pc ; io
|
||||
[2] pbr,pc ; io
|
||||
[3] 0,s ; pbr
|
||||
[4] 0,s-1 ; pch
|
||||
[5] 0,s-2 ; pcl
|
||||
[6] 0,s-3 ; p
|
||||
[7] 0,va ; aavl
|
||||
[8] 0,va+1 ; aavh
|
||||
*/
|
||||
|
||||
void g65816::InvokeIRQ(word addr) {
|
||||
snes_time->add_cpu_icycles(2); //1,2 [i/o]
|
||||
gx816->stack_write(gx816->regs.pc >> 16); //3 [write pbr]
|
||||
gx816->stack_write(gx816->regs.pc >> 8); //4 [write pch]
|
||||
gx816->stack_write(gx816->regs.pc); //5 [write pcl]
|
||||
gx816->stack_write(gx816->regs.p); //6 [write p]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, addr); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, addr + 1); //8 [read high]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.w;
|
||||
gx816->regs.p |= PF_I;
|
||||
wai_interrupt_occurred = true;
|
||||
snes_time->update_timer();
|
||||
}
|
||||
|
||||
void g65816::exec_op(void) {
|
||||
FILE *fp;
|
||||
byte op;
|
||||
int i;
|
||||
static ulong sram_save_tick = 0;
|
||||
if(cpu_state == CPUSTATE_RUN || cpu_state == CPUSTATE_STP) {
|
||||
op = mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc);
|
||||
if(regs.e == true)g65816_optbl_e[op]();
|
||||
else switch((regs.p & 0x30)) {
|
||||
case 0x30:g65816_optbl_MX[op]();break;
|
||||
case 0x20:g65816_optbl_Mx[op]();break;
|
||||
case 0x10:g65816_optbl_mX[op]();break;
|
||||
case 0x00:g65816_optbl_mx[op]();break;
|
||||
}
|
||||
debugger.cpu_op_executed = true;
|
||||
debugger.disas_cpu_op = true;
|
||||
snes_time->update_timer();
|
||||
} else if(cpu_state == CPUSTATE_DMA) {
|
||||
ppu_update_dma();
|
||||
snes_time->update_timer();
|
||||
}
|
||||
|
||||
snes_time->update_timer_events();
|
||||
ppu_update_scanline();
|
||||
|
||||
//see if we need to backup sram to a file yet...
|
||||
if(sram_size != 0) {
|
||||
sram_save_tick++;
|
||||
if(sram_save_tick >= emu_state.sram_save_tick_count) {
|
||||
sram_save_tick = 0;
|
||||
fp = fopen(emu_state.sram_name, "wb");
|
||||
fwrite(sram, 1, sram_size, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
debug_test_bp(BPSRC_MEM, BP_EXEC, gx816->regs.pc, 0);
|
||||
}
|
||||
|
||||
void g65816::Run(void) {
|
||||
if(snes_time->bridge.apu_cycles >= snes_time->bridge.cpu_cycles) {
|
||||
exec_op();
|
||||
}
|
||||
if(snes_time->bridge.cpu_cycles >= 65536 && snes_time->bridge.apu_cycles >= 65536) {
|
||||
snes_time->bridge.cpu_cycles &= 65535;
|
||||
snes_time->bridge.apu_cycles &= 65535;
|
||||
}
|
||||
}
|
||||
|
||||
g65816::g65816() {
|
||||
int i;
|
||||
rom = (byte*)malloc(0x600000);
|
||||
wram = (byte*)malloc(0x020000);
|
||||
sram = (byte*)malloc(0x0e0000);
|
||||
nmi_enabled = false;
|
||||
nmi_pin = 0;
|
||||
|
||||
op.dp = op.sp = 0x00;
|
||||
op.r.l = 0x000000;
|
||||
op.aa.l = 0x000000;
|
||||
}
|
||||
|
||||
g65816::~g65816() {
|
||||
if(rom)free(rom);
|
||||
if(wram)free(wram);
|
||||
if(sram)free(sram);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
regs.dc is not a real register. it is used to store the data counter
|
||||
for reading from / writing to memory locations. it is also needed
|
||||
to emulate slowrom / fastrom, as the speed varies depending on the
|
||||
location where the memory was accessed.
|
||||
*/
|
||||
|
||||
class g65816 {
|
||||
public:
|
||||
//cpu declarations
|
||||
byte cpu_state;
|
||||
struct {
|
||||
ulong pc;
|
||||
union {
|
||||
byte b;
|
||||
word w;
|
||||
struct { byte l, h; }p;
|
||||
}a;
|
||||
word x, y, d, s;
|
||||
byte db, p;
|
||||
bool e;
|
||||
}regs;
|
||||
struct {
|
||||
byte dp, sp;
|
||||
union {
|
||||
byte b;
|
||||
word w;
|
||||
ulong l;
|
||||
struct { byte l, h, b; }p;
|
||||
}r;
|
||||
union {
|
||||
word w;
|
||||
ulong l;
|
||||
struct { byte l, h, b; }p;
|
||||
}aa;
|
||||
ulong addr, iaddr;
|
||||
bool c2, c4;
|
||||
}op;
|
||||
byte memory_speed;
|
||||
|
||||
byte nmi_pin;
|
||||
bool nmi_enabled;
|
||||
|
||||
bool wai_interrupt_occurred;
|
||||
|
||||
//memory declarations
|
||||
byte *wram, *sram, *rom;
|
||||
ulong map;
|
||||
ulong sram_size;
|
||||
|
||||
//cpu functions (cpu/g65816.cpp)
|
||||
void Run(void);
|
||||
void LoadROM(void);
|
||||
void PowerOn(byte first_time);
|
||||
void Reset(void);
|
||||
void InvokeIRQ(word addr);
|
||||
|
||||
//memory functions (mem/memory.cpp)
|
||||
void exec_op(void);
|
||||
void InitializeROM(byte memory_map);
|
||||
void InitializeWRAM(byte value);
|
||||
ulong mirror_offset(ulong offset);
|
||||
ulong convert_offset(byte read_mode, ulong addr, bool mirror = true);
|
||||
//ulong adjust_base_offset(byte read_mode, ulong addr);
|
||||
//ulong read_indirect_address(byte read_mode, ulong addr);
|
||||
//ulong get_dc(byte read_mode, ulong addr);
|
||||
|
||||
byte mem_getbyte_direct(ulong addr, byte access_mode = MEMACCESS_NORMAL);
|
||||
byte mem_getbyte(ulong addr, byte access_mode = MEMACCESS_NORMAL);
|
||||
void mem_putbyte_direct(ulong addr, byte value, byte access_mode = MEMACCESS_NORMAL);
|
||||
void mem_putbyte(ulong addr, byte value, byte access_mode = MEMACCESS_NORMAL);
|
||||
ulong mem_read(byte read_mode, byte read_size, ulong addr, byte access_mode = MEMACCESS_NORMAL);
|
||||
void mem_write(byte write_mode, byte write_size, ulong addr, ulong value, byte access_mode = MEMACCESS_NORMAL);
|
||||
|
||||
ulong read_operand(byte size);
|
||||
byte op_read(byte mode, ulong addr);
|
||||
void op_write(byte mode, ulong addr, byte value);
|
||||
byte stack_read(void);
|
||||
void stack_write(byte value);
|
||||
void op_cond(byte c, ulong n0 = 0, ulong n1 = 0);
|
||||
|
||||
ulong rom_read(ulong addr, byte read_size);
|
||||
void rom_write(ulong addr, ulong v, byte write_size);
|
||||
|
||||
g65816();
|
||||
~g65816();
|
||||
};
|
||||
@@ -0,0 +1,162 @@
|
||||
#define g65816_setn() gx816->regs.p |= PF_N
|
||||
#define g65816_clrn() gx816->regs.p &= ~PF_N
|
||||
#define g65816_setv() gx816->regs.p |= PF_V
|
||||
#define g65816_clrv() gx816->regs.p &= ~PF_V
|
||||
#define g65816_setm() gx816->regs.p |= PF_M
|
||||
#define g65816_clrm() gx816->regs.p &= ~PF_M
|
||||
#define g65816_setx() gx816->regs.p |= PF_X
|
||||
#define g65816_clrx() gx816->regs.p &= ~PF_X
|
||||
#define g65816_setd() gx816->regs.p |= PF_D
|
||||
#define g65816_clrd() gx816->regs.p &= ~PF_D
|
||||
#define g65816_seti() gx816->regs.p |= PF_I
|
||||
#define g65816_clri() gx816->regs.p &= ~PF_I
|
||||
#define g65816_setz() gx816->regs.p |= PF_Z
|
||||
#define g65816_clrz() gx816->regs.p &= ~PF_Z
|
||||
#define g65816_setc() gx816->regs.p |= PF_C
|
||||
#define g65816_clrc() gx816->regs.p &= ~PF_C
|
||||
#define g65816_testn(x) if(x)g65816_setn(); else g65816_clrn()
|
||||
#define g65816_testv(x) if(x)g65816_setv(); else g65816_clrv()
|
||||
#define g65816_testd(x) if(x)g65816_setd(); else g65816_clrd()
|
||||
#define g65816_testi(x) if(x)g65816_seti(); else g65816_clri()
|
||||
#define g65816_testz(x) if(x)g65816_setz(); else g65816_clrz()
|
||||
#define g65816_testc(x) if(x)g65816_setc(); else g65816_clrc()
|
||||
|
||||
//increment program counter, wrap around pbr
|
||||
#define g65816_incpc(__n) gx816->regs.pc = (gx816->regs.pc & 0xff0000) | (word)(gx816->regs.pc + __n)
|
||||
|
||||
/*
|
||||
vpa = 1, vda = 1 -> add_cpu_pcycles (opcode fetch)
|
||||
vpa = 1, vda = 0 -> add_cpu_pcycles (operand fetch)
|
||||
vpa = 0, vda = 1 -> add_cpu_dcycles (memory fetch)
|
||||
vpa = 0, vda = 0 -> add_cpu_icycles (internal operation)
|
||||
*/
|
||||
|
||||
//opcode functions
|
||||
#include "g65816_ops_adc.cpp"
|
||||
#include "g65816_ops_and.cpp"
|
||||
#include "g65816_ops_cmp.cpp"
|
||||
#include "g65816_ops_eor.cpp"
|
||||
#include "g65816_ops_lda.cpp"
|
||||
#include "g65816_ops_ora.cpp"
|
||||
#include "g65816_ops_sbc.cpp"
|
||||
#include "g65816_ops_sta.cpp"
|
||||
#include "g65816_ops_incdec.cpp"
|
||||
#include "g65816_ops_shift.cpp"
|
||||
#include "g65816_ops_stack.cpp"
|
||||
#include "g65816_ops_pc.cpp"
|
||||
#include "g65816_ops_misc.cpp"
|
||||
|
||||
vfunc g65816_optbl_e[256] = { // g65816_optbl_e, g65816_optbl_e, g65816_optbl_e,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxb, g65816_op_cop, g65816_op_ora_srb, /* 0x */ g65816_op_tsb_dpb, g65816_op_ora_dpb, g65816_op_asl_dpb, g65816_op_ora_ildpb, /* 0x */ g65816_op_php, g65816_op_ora_constb, g65816_op_aslb, g65816_op_phd, /* 0x */ g65816_op_tsb_addrb, g65816_op_ora_addrb, g65816_op_asl_addrb, g65816_op_ora_longb,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyb, g65816_op_ora_idpb, g65816_op_ora_isryb, /* 1x */ g65816_op_trb_dpb, g65816_op_ora_dpxb, g65816_op_asl_dpxb, g65816_op_ora_ildpyb, /* 1x */ g65816_op_clc, g65816_op_ora_addryb, g65816_op_incb, g65816_op_tcse, /* 1x */ g65816_op_trb_addrb, g65816_op_ora_addrxb, g65816_op_asl_addrxb, g65816_op_ora_longxb,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxb, g65816_op_jsr_long, g65816_op_and_srb, /* 2x */ g65816_op_bit_dpb, g65816_op_and_dpb, g65816_op_rol_dpb, g65816_op_and_ildpb, /* 2x */ g65816_op_plp, g65816_op_and_constb, g65816_op_rolb, g65816_op_pld, /* 2x */ g65816_op_bit_addrb, g65816_op_and_addrb, g65816_op_rol_addrb, g65816_op_and_longb,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyb, g65816_op_and_idpb, g65816_op_and_isryb, /* 3x */ g65816_op_bit_dpxb, g65816_op_and_dpxb, g65816_op_rol_dpxb, g65816_op_and_ildpyb, /* 3x */ g65816_op_sec, g65816_op_and_addryb, g65816_op_decb, g65816_op_tsce, /* 3x */ g65816_op_bit_addrxb, g65816_op_and_addrxb, g65816_op_rol_addrxb, g65816_op_and_longxb,
|
||||
|
||||
/* 4x */ g65816_op_rtie, g65816_op_eor_idpxb, g65816_op_wdm, g65816_op_eor_srb, /* 4x */ g65816_op_mvp, g65816_op_eor_dpb, g65816_op_lsr_dpb, g65816_op_eor_ildpb, /* 4x */ g65816_op_phab, g65816_op_eor_constb, g65816_op_lsrb, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrb, g65816_op_lsr_addrb, g65816_op_eor_longb,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyb, g65816_op_eor_idpb, g65816_op_eor_isryb, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxb, g65816_op_lsr_dpxb, g65816_op_eor_ildpyb, /* 5x */ g65816_op_cli, g65816_op_eor_addryb, g65816_op_phyb, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxb, g65816_op_lsr_addrxb, g65816_op_eor_longxb,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxb, g65816_op_per, g65816_op_adc_srb, /* 6x */ g65816_op_stz_dpb, g65816_op_adc_dpb, g65816_op_ror_dpb, g65816_op_adc_ildpb, /* 6x */ g65816_op_plab, g65816_op_adc_constb, g65816_op_rorb, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrb, g65816_op_ror_addrb, g65816_op_adc_longb,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyb, g65816_op_adc_idpb, g65816_op_adc_isryb, /* 7x */ g65816_op_stz_dpxb, g65816_op_adc_dpxb, g65816_op_ror_dpxb, g65816_op_adc_ildpyb, /* 7x */ g65816_op_sei, g65816_op_adc_addryb, g65816_op_plyb, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxb, g65816_op_ror_addrxb, g65816_op_adc_longxb,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxb, g65816_op_brl, g65816_op_sta_srb, /* 8x */ g65816_op_sty_dpb, g65816_op_sta_dpb, g65816_op_stx_dpb, g65816_op_sta_ildpb, /* 8x */ g65816_op_deyb, g65816_op_bit_constb, g65816_op_txab, g65816_op_phb, /* 8x */ g65816_op_sty_addrb, g65816_op_sta_addrb, g65816_op_stx_addrb, g65816_op_sta_longb,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyb, g65816_op_sta_idpb, g65816_op_sta_isryb, /* 9x */ g65816_op_sty_dpxb, g65816_op_sta_dpxb, g65816_op_stx_dpyb, g65816_op_sta_ildpyb, /* 9x */ g65816_op_tyab, g65816_op_sta_addryb, g65816_op_txsb, g65816_op_txyb, /* 9x */ g65816_op_stz_addrb, g65816_op_sta_addrxb, g65816_op_stz_addrxb, g65816_op_sta_longxb,
|
||||
/* ax */ g65816_op_ldy_constb, g65816_op_lda_idpxb, g65816_op_ldx_constb, g65816_op_lda_srb, /* ax */ g65816_op_ldy_dpb, g65816_op_lda_dpb, g65816_op_ldx_dpb, g65816_op_lda_ildpb, /* ax */ g65816_op_tayb, g65816_op_lda_constb, g65816_op_taxb, g65816_op_plb, /* ax */ g65816_op_ldy_addrb, g65816_op_lda_addrb, g65816_op_ldx_addrb, g65816_op_lda_longb,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyb, g65816_op_lda_idpb, g65816_op_lda_isryb, /* bx */ g65816_op_ldy_dpxb, g65816_op_lda_dpxb, g65816_op_ldx_dpyb, g65816_op_lda_ildpyb, /* bx */ g65816_op_clv, g65816_op_lda_addryb, g65816_op_tsxb, g65816_op_tyxb, /* bx */ g65816_op_ldy_addrxb, g65816_op_lda_addrxb, g65816_op_ldx_addryb, g65816_op_lda_longxb,
|
||||
|
||||
/* cx */ g65816_op_cpy_constb, g65816_op_cmp_idpxb, g65816_op_rep, g65816_op_cmp_srb, /* cx */ g65816_op_cpy_dpb, g65816_op_cmp_dpb, g65816_op_dec_dpb, g65816_op_cmp_ildpb, /* cx */ g65816_op_inyb, g65816_op_cmp_constb, g65816_op_dexb, g65816_op_wai, /* cx */ g65816_op_cpy_addrb, g65816_op_cmp_addrb, g65816_op_dec_addrb, g65816_op_cmp_longb,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyb, g65816_op_cmp_idpb, g65816_op_cmp_isryb, /* dx */ g65816_op_pei, g65816_op_cmp_dpxb, g65816_op_dec_dpxb, g65816_op_cmp_ildpyb, /* dx */ g65816_op_cld, g65816_op_cmp_addryb, g65816_op_phxb, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxb, g65816_op_dec_addrxb, g65816_op_cmp_longxb,
|
||||
/* ex */ g65816_op_cpx_constb, g65816_op_sbc_idpxb, g65816_op_sep, g65816_op_sbc_srb, /* ex */ g65816_op_cpx_dpb, g65816_op_sbc_dpb, g65816_op_inc_dpb, g65816_op_sbc_ildpb, /* ex */ g65816_op_inxb, g65816_op_sbc_constb, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrb, g65816_op_sbc_addrb, g65816_op_inc_addrb, g65816_op_sbc_longb,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyb, g65816_op_sbc_idpb, g65816_op_sbc_isryb, /* fx */ g65816_op_pea, g65816_op_sbc_dpxb, g65816_op_inc_dpxb, g65816_op_sbc_ildpyb, /* fx */ g65816_op_sed, g65816_op_sbc_addryb, g65816_op_plxb, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxb, g65816_op_inc_addrxb, g65816_op_sbc_longxb
|
||||
};
|
||||
|
||||
vfunc g65816_optbl_MX[256] = { // g65816_optbl_MX, g65816_optbl_MX, g65816_optbl_MX,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxb, g65816_op_cop, g65816_op_ora_srb, /* 0x */ g65816_op_tsb_dpb, g65816_op_ora_dpb, g65816_op_asl_dpb, g65816_op_ora_ildpb, /* 0x */ g65816_op_php, g65816_op_ora_constb, g65816_op_aslb, g65816_op_phd, /* 0x */ g65816_op_tsb_addrb, g65816_op_ora_addrb, g65816_op_asl_addrb, g65816_op_ora_longb,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyb, g65816_op_ora_idpb, g65816_op_ora_isryb, /* 1x */ g65816_op_trb_dpb, g65816_op_ora_dpxb, g65816_op_asl_dpxb, g65816_op_ora_ildpyb, /* 1x */ g65816_op_clc, g65816_op_ora_addryb, g65816_op_incb, g65816_op_tcsn, /* 1x */ g65816_op_trb_addrb, g65816_op_ora_addrxb, g65816_op_asl_addrxb, g65816_op_ora_longxb,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxb, g65816_op_jsr_long, g65816_op_and_srb, /* 2x */ g65816_op_bit_dpb, g65816_op_and_dpb, g65816_op_rol_dpb, g65816_op_and_ildpb, /* 2x */ g65816_op_plp, g65816_op_and_constb, g65816_op_rolb, g65816_op_pld, /* 2x */ g65816_op_bit_addrb, g65816_op_and_addrb, g65816_op_rol_addrb, g65816_op_and_longb,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyb, g65816_op_and_idpb, g65816_op_and_isryb, /* 3x */ g65816_op_bit_dpxb, g65816_op_and_dpxb, g65816_op_rol_dpxb, g65816_op_and_ildpyb, /* 3x */ g65816_op_sec, g65816_op_and_addryb, g65816_op_decb, g65816_op_tscn, /* 3x */ g65816_op_bit_addrxb, g65816_op_and_addrxb, g65816_op_rol_addrxb, g65816_op_and_longxb,
|
||||
|
||||
/* 4x */ g65816_op_rtin, g65816_op_eor_idpxb, g65816_op_wdm, g65816_op_eor_srb, /* 4x */ g65816_op_mvp, g65816_op_eor_dpb, g65816_op_lsr_dpb, g65816_op_eor_ildpb, /* 4x */ g65816_op_phab, g65816_op_eor_constb, g65816_op_lsrb, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrb, g65816_op_lsr_addrb, g65816_op_eor_longb,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyb, g65816_op_eor_idpb, g65816_op_eor_isryb, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxb, g65816_op_lsr_dpxb, g65816_op_eor_ildpyb, /* 5x */ g65816_op_cli, g65816_op_eor_addryb, g65816_op_phyb, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxb, g65816_op_lsr_addrxb, g65816_op_eor_longxb,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxb, g65816_op_per, g65816_op_adc_srb, /* 6x */ g65816_op_stz_dpb, g65816_op_adc_dpb, g65816_op_ror_dpb, g65816_op_adc_ildpb, /* 6x */ g65816_op_plab, g65816_op_adc_constb, g65816_op_rorb, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrb, g65816_op_ror_addrb, g65816_op_adc_longb,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyb, g65816_op_adc_idpb, g65816_op_adc_isryb, /* 7x */ g65816_op_stz_dpxb, g65816_op_adc_dpxb, g65816_op_ror_dpxb, g65816_op_adc_ildpyb, /* 7x */ g65816_op_sei, g65816_op_adc_addryb, g65816_op_plyb, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxb, g65816_op_ror_addrxb, g65816_op_adc_longxb,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxb, g65816_op_brl, g65816_op_sta_srb, /* 8x */ g65816_op_sty_dpb, g65816_op_sta_dpb, g65816_op_stx_dpb, g65816_op_sta_ildpb, /* 8x */ g65816_op_deyb, g65816_op_bit_constb, g65816_op_txab, g65816_op_phb, /* 8x */ g65816_op_sty_addrb, g65816_op_sta_addrb, g65816_op_stx_addrb, g65816_op_sta_longb,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyb, g65816_op_sta_idpb, g65816_op_sta_isryb, /* 9x */ g65816_op_sty_dpxb, g65816_op_sta_dpxb, g65816_op_stx_dpyb, g65816_op_sta_ildpyb, /* 9x */ g65816_op_tyab, g65816_op_sta_addryb, g65816_op_txsb, g65816_op_txyb, /* 9x */ g65816_op_stz_addrb, g65816_op_sta_addrxb, g65816_op_stz_addrxb, g65816_op_sta_longxb,
|
||||
/* ax */ g65816_op_ldy_constb, g65816_op_lda_idpxb, g65816_op_ldx_constb, g65816_op_lda_srb, /* ax */ g65816_op_ldy_dpb, g65816_op_lda_dpb, g65816_op_ldx_dpb, g65816_op_lda_ildpb, /* ax */ g65816_op_tayb, g65816_op_lda_constb, g65816_op_taxb, g65816_op_plb, /* ax */ g65816_op_ldy_addrb, g65816_op_lda_addrb, g65816_op_ldx_addrb, g65816_op_lda_longb,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyb, g65816_op_lda_idpb, g65816_op_lda_isryb, /* bx */ g65816_op_ldy_dpxb, g65816_op_lda_dpxb, g65816_op_ldx_dpyb, g65816_op_lda_ildpyb, /* bx */ g65816_op_clv, g65816_op_lda_addryb, g65816_op_tsxb, g65816_op_tyxb, /* bx */ g65816_op_ldy_addrxb, g65816_op_lda_addrxb, g65816_op_ldx_addryb, g65816_op_lda_longxb,
|
||||
|
||||
/* cx */ g65816_op_cpy_constb, g65816_op_cmp_idpxb, g65816_op_rep, g65816_op_cmp_srb, /* cx */ g65816_op_cpy_dpb, g65816_op_cmp_dpb, g65816_op_dec_dpb, g65816_op_cmp_ildpb, /* cx */ g65816_op_inyb, g65816_op_cmp_constb, g65816_op_dexb, g65816_op_wai, /* cx */ g65816_op_cpy_addrb, g65816_op_cmp_addrb, g65816_op_dec_addrb, g65816_op_cmp_longb,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyb, g65816_op_cmp_idpb, g65816_op_cmp_isryb, /* dx */ g65816_op_pei, g65816_op_cmp_dpxb, g65816_op_dec_dpxb, g65816_op_cmp_ildpyb, /* dx */ g65816_op_cld, g65816_op_cmp_addryb, g65816_op_phxb, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxb, g65816_op_dec_addrxb, g65816_op_cmp_longxb,
|
||||
/* ex */ g65816_op_cpx_constb, g65816_op_sbc_idpxb, g65816_op_sep, g65816_op_sbc_srb, /* ex */ g65816_op_cpx_dpb, g65816_op_sbc_dpb, g65816_op_inc_dpb, g65816_op_sbc_ildpb, /* ex */ g65816_op_inxb, g65816_op_sbc_constb, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrb, g65816_op_sbc_addrb, g65816_op_inc_addrb, g65816_op_sbc_longb,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyb, g65816_op_sbc_idpb, g65816_op_sbc_isryb, /* fx */ g65816_op_pea, g65816_op_sbc_dpxb, g65816_op_inc_dpxb, g65816_op_sbc_ildpyb, /* fx */ g65816_op_sed, g65816_op_sbc_addryb, g65816_op_plxb, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxb, g65816_op_inc_addrxb, g65816_op_sbc_longxb
|
||||
};
|
||||
|
||||
vfunc g65816_optbl_Mx[256] = { // g65816_optbl_Mx, g65816_optbl_Mx, g65816_optbl_Mx,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxb, g65816_op_cop, g65816_op_ora_srb, /* 0x */ g65816_op_tsb_dpb, g65816_op_ora_dpb, g65816_op_asl_dpb, g65816_op_ora_ildpb, /* 0x */ g65816_op_php, g65816_op_ora_constb, g65816_op_aslb, g65816_op_phd, /* 0x */ g65816_op_tsb_addrb, g65816_op_ora_addrb, g65816_op_asl_addrb, g65816_op_ora_longb,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyb, g65816_op_ora_idpb, g65816_op_ora_isryb, /* 1x */ g65816_op_trb_dpb, g65816_op_ora_dpxb, g65816_op_asl_dpxb, g65816_op_ora_ildpyb, /* 1x */ g65816_op_clc, g65816_op_ora_addryb, g65816_op_incb, g65816_op_tcsn, /* 1x */ g65816_op_trb_addrb, g65816_op_ora_addrxb, g65816_op_asl_addrxb, g65816_op_ora_longxb,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxb, g65816_op_jsr_long, g65816_op_and_srb, /* 2x */ g65816_op_bit_dpb, g65816_op_and_dpb, g65816_op_rol_dpb, g65816_op_and_ildpb, /* 2x */ g65816_op_plp, g65816_op_and_constb, g65816_op_rolb, g65816_op_pld, /* 2x */ g65816_op_bit_addrb, g65816_op_and_addrb, g65816_op_rol_addrb, g65816_op_and_longb,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyb, g65816_op_and_idpb, g65816_op_and_isryb, /* 3x */ g65816_op_bit_dpxb, g65816_op_and_dpxb, g65816_op_rol_dpxb, g65816_op_and_ildpyb, /* 3x */ g65816_op_sec, g65816_op_and_addryb, g65816_op_decb, g65816_op_tscn, /* 3x */ g65816_op_bit_addrxb, g65816_op_and_addrxb, g65816_op_rol_addrxb, g65816_op_and_longxb,
|
||||
|
||||
/* 4x */ g65816_op_rtin, g65816_op_eor_idpxb, g65816_op_wdm, g65816_op_eor_srb, /* 4x */ g65816_op_mvp, g65816_op_eor_dpb, g65816_op_lsr_dpb, g65816_op_eor_ildpb, /* 4x */ g65816_op_phab, g65816_op_eor_constb, g65816_op_lsrb, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrb, g65816_op_lsr_addrb, g65816_op_eor_longb,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyb, g65816_op_eor_idpb, g65816_op_eor_isryb, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxb, g65816_op_lsr_dpxb, g65816_op_eor_ildpyb, /* 5x */ g65816_op_cli, g65816_op_eor_addryb, g65816_op_phyw, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxb, g65816_op_lsr_addrxb, g65816_op_eor_longxb,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxb, g65816_op_per, g65816_op_adc_srb, /* 6x */ g65816_op_stz_dpb, g65816_op_adc_dpb, g65816_op_ror_dpb, g65816_op_adc_ildpb, /* 6x */ g65816_op_plab, g65816_op_adc_constb, g65816_op_rorb, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrb, g65816_op_ror_addrb, g65816_op_adc_longb,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyb, g65816_op_adc_idpb, g65816_op_adc_isryb, /* 7x */ g65816_op_stz_dpxb, g65816_op_adc_dpxb, g65816_op_ror_dpxb, g65816_op_adc_ildpyb, /* 7x */ g65816_op_sei, g65816_op_adc_addryb, g65816_op_plyw, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxb, g65816_op_ror_addrxb, g65816_op_adc_longxb,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxb, g65816_op_brl, g65816_op_sta_srb, /* 8x */ g65816_op_sty_dpw, g65816_op_sta_dpb, g65816_op_stx_dpw, g65816_op_sta_ildpb, /* 8x */ g65816_op_deyw, g65816_op_bit_constb, g65816_op_txab, g65816_op_phb, /* 8x */ g65816_op_sty_addrw, g65816_op_sta_addrb, g65816_op_stx_addrw, g65816_op_sta_longb,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyb, g65816_op_sta_idpb, g65816_op_sta_isryb, /* 9x */ g65816_op_sty_dpxw, g65816_op_sta_dpxb, g65816_op_stx_dpyw, g65816_op_sta_ildpyb, /* 9x */ g65816_op_tyab, g65816_op_sta_addryb, g65816_op_txsw, g65816_op_txyw, /* 9x */ g65816_op_stz_addrb, g65816_op_sta_addrxb, g65816_op_stz_addrxb, g65816_op_sta_longxb,
|
||||
/* ax */ g65816_op_ldy_constw, g65816_op_lda_idpxb, g65816_op_ldx_constw, g65816_op_lda_srb, /* ax */ g65816_op_ldy_dpw, g65816_op_lda_dpb, g65816_op_ldx_dpw, g65816_op_lda_ildpb, /* ax */ g65816_op_tayw, g65816_op_lda_constb, g65816_op_taxw, g65816_op_plb, /* ax */ g65816_op_ldy_addrw, g65816_op_lda_addrb, g65816_op_ldx_addrw, g65816_op_lda_longb,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyb, g65816_op_lda_idpb, g65816_op_lda_isryb, /* bx */ g65816_op_ldy_dpxw, g65816_op_lda_dpxb, g65816_op_ldx_dpyw, g65816_op_lda_ildpyb, /* bx */ g65816_op_clv, g65816_op_lda_addryb, g65816_op_tsxw, g65816_op_tyxw, /* bx */ g65816_op_ldy_addrxw, g65816_op_lda_addrxb, g65816_op_ldx_addryw, g65816_op_lda_longxb,
|
||||
|
||||
/* cx */ g65816_op_cpy_constw, g65816_op_cmp_idpxb, g65816_op_rep, g65816_op_cmp_srb, /* cx */ g65816_op_cpy_dpw, g65816_op_cmp_dpb, g65816_op_dec_dpb, g65816_op_cmp_ildpb, /* cx */ g65816_op_inyw, g65816_op_cmp_constb, g65816_op_dexw, g65816_op_wai, /* cx */ g65816_op_cpy_addrw, g65816_op_cmp_addrb, g65816_op_dec_addrb, g65816_op_cmp_longb,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyb, g65816_op_cmp_idpb, g65816_op_cmp_isryb, /* dx */ g65816_op_pei, g65816_op_cmp_dpxb, g65816_op_dec_dpxb, g65816_op_cmp_ildpyb, /* dx */ g65816_op_cld, g65816_op_cmp_addryb, g65816_op_phxw, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxb, g65816_op_dec_addrxb, g65816_op_cmp_longxb,
|
||||
/* ex */ g65816_op_cpx_constw, g65816_op_sbc_idpxb, g65816_op_sep, g65816_op_sbc_srb, /* ex */ g65816_op_cpx_dpw, g65816_op_sbc_dpb, g65816_op_inc_dpb, g65816_op_sbc_ildpb, /* ex */ g65816_op_inxw, g65816_op_sbc_constb, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrw, g65816_op_sbc_addrb, g65816_op_inc_addrb, g65816_op_sbc_longb,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyb, g65816_op_sbc_idpb, g65816_op_sbc_isryb, /* fx */ g65816_op_pea, g65816_op_sbc_dpxb, g65816_op_inc_dpxb, g65816_op_sbc_ildpyb, /* fx */ g65816_op_sed, g65816_op_sbc_addryb, g65816_op_plxw, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxb, g65816_op_inc_addrxb, g65816_op_sbc_longxb
|
||||
};
|
||||
|
||||
vfunc g65816_optbl_mX[256] = { // g65816_optbl_mX, g65816_optbl_mX, g65816_optbl_mX,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxw, g65816_op_cop, g65816_op_ora_srw, /* 0x */ g65816_op_tsb_dpw, g65816_op_ora_dpw, g65816_op_asl_dpw, g65816_op_ora_ildpw, /* 0x */ g65816_op_php, g65816_op_ora_constw, g65816_op_aslw, g65816_op_phd, /* 0x */ g65816_op_tsb_addrw, g65816_op_ora_addrw, g65816_op_asl_addrw, g65816_op_ora_longw,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyw, g65816_op_ora_idpw, g65816_op_ora_isryw, /* 1x */ g65816_op_trb_dpw, g65816_op_ora_dpxw, g65816_op_asl_dpxw, g65816_op_ora_ildpyw, /* 1x */ g65816_op_clc, g65816_op_ora_addryw, g65816_op_incw, g65816_op_tcsn, /* 1x */ g65816_op_trb_addrw, g65816_op_ora_addrxw, g65816_op_asl_addrxw, g65816_op_ora_longxw,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxw, g65816_op_jsr_long, g65816_op_and_srw, /* 2x */ g65816_op_bit_dpw, g65816_op_and_dpw, g65816_op_rol_dpw, g65816_op_and_ildpw, /* 2x */ g65816_op_plp, g65816_op_and_constw, g65816_op_rolw, g65816_op_pld, /* 2x */ g65816_op_bit_addrw, g65816_op_and_addrw, g65816_op_rol_addrw, g65816_op_and_longw,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyw, g65816_op_and_idpw, g65816_op_and_isryw, /* 3x */ g65816_op_bit_dpxw, g65816_op_and_dpxw, g65816_op_rol_dpxw, g65816_op_and_ildpyw, /* 3x */ g65816_op_sec, g65816_op_and_addryw, g65816_op_decw, g65816_op_tscn, /* 3x */ g65816_op_bit_addrxw, g65816_op_and_addrxw, g65816_op_rol_addrxw, g65816_op_and_longxw,
|
||||
|
||||
/* 4x */ g65816_op_rtin, g65816_op_eor_idpxw, g65816_op_wdm, g65816_op_eor_srw, /* 4x */ g65816_op_mvp, g65816_op_eor_dpw, g65816_op_lsr_dpw, g65816_op_eor_ildpw, /* 4x */ g65816_op_phaw, g65816_op_eor_constw, g65816_op_lsrw, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrw, g65816_op_lsr_addrw, g65816_op_eor_longw,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyw, g65816_op_eor_idpw, g65816_op_eor_isryw, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxw, g65816_op_lsr_dpxw, g65816_op_eor_ildpyw, /* 5x */ g65816_op_cli, g65816_op_eor_addryw, g65816_op_phyb, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxw, g65816_op_lsr_addrxw, g65816_op_eor_longxw,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxw, g65816_op_per, g65816_op_adc_srw, /* 6x */ g65816_op_stz_dpw, g65816_op_adc_dpw, g65816_op_ror_dpw, g65816_op_adc_ildpw, /* 6x */ g65816_op_plaw, g65816_op_adc_constw, g65816_op_rorw, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrw, g65816_op_ror_addrw, g65816_op_adc_longw,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyw, g65816_op_adc_idpw, g65816_op_adc_isryw, /* 7x */ g65816_op_stz_dpxw, g65816_op_adc_dpxw, g65816_op_ror_dpxw, g65816_op_adc_ildpyw, /* 7x */ g65816_op_sei, g65816_op_adc_addryw, g65816_op_plyb, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxw, g65816_op_ror_addrxw, g65816_op_adc_longxw,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxw, g65816_op_brl, g65816_op_sta_srw, /* 8x */ g65816_op_sty_dpb, g65816_op_sta_dpw, g65816_op_stx_dpb, g65816_op_sta_ildpw, /* 8x */ g65816_op_deyb, g65816_op_bit_constw, g65816_op_txaw, g65816_op_phb, /* 8x */ g65816_op_sty_addrb, g65816_op_sta_addrw, g65816_op_stx_addrb, g65816_op_sta_longw,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyw, g65816_op_sta_idpw, g65816_op_sta_isryw, /* 9x */ g65816_op_sty_dpxb, g65816_op_sta_dpxw, g65816_op_stx_dpyb, g65816_op_sta_ildpyw, /* 9x */ g65816_op_tyaw, g65816_op_sta_addryw, g65816_op_txsb, g65816_op_txyb, /* 9x */ g65816_op_stz_addrw, g65816_op_sta_addrxw, g65816_op_stz_addrxw, g65816_op_sta_longxw,
|
||||
/* ax */ g65816_op_ldy_constb, g65816_op_lda_idpxw, g65816_op_ldx_constb, g65816_op_lda_srw, /* ax */ g65816_op_ldy_dpb, g65816_op_lda_dpw, g65816_op_ldx_dpb, g65816_op_lda_ildpw, /* ax */ g65816_op_tayb, g65816_op_lda_constw, g65816_op_taxb, g65816_op_plb, /* ax */ g65816_op_ldy_addrb, g65816_op_lda_addrw, g65816_op_ldx_addrb, g65816_op_lda_longw,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyw, g65816_op_lda_idpw, g65816_op_lda_isryw, /* bx */ g65816_op_ldy_dpxb, g65816_op_lda_dpxw, g65816_op_ldx_dpyb, g65816_op_lda_ildpyw, /* bx */ g65816_op_clv, g65816_op_lda_addryw, g65816_op_tsxb, g65816_op_tyxb, /* bx */ g65816_op_ldy_addrxb, g65816_op_lda_addrxw, g65816_op_ldx_addryb, g65816_op_lda_longxw,
|
||||
|
||||
/* cx */ g65816_op_cpy_constb, g65816_op_cmp_idpxw, g65816_op_rep, g65816_op_cmp_srw, /* cx */ g65816_op_cpy_dpb, g65816_op_cmp_dpw, g65816_op_dec_dpw, g65816_op_cmp_ildpw, /* cx */ g65816_op_inyb, g65816_op_cmp_constw, g65816_op_dexb, g65816_op_wai, /* cx */ g65816_op_cpy_addrb, g65816_op_cmp_addrw, g65816_op_dec_addrw, g65816_op_cmp_longw,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyw, g65816_op_cmp_idpw, g65816_op_cmp_isryw, /* dx */ g65816_op_pei, g65816_op_cmp_dpxw, g65816_op_dec_dpxw, g65816_op_cmp_ildpyw, /* dx */ g65816_op_cld, g65816_op_cmp_addryw, g65816_op_phxb, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxw, g65816_op_dec_addrxw, g65816_op_cmp_longxw,
|
||||
/* ex */ g65816_op_cpx_constb, g65816_op_sbc_idpxw, g65816_op_sep, g65816_op_sbc_srw, /* ex */ g65816_op_cpx_dpb, g65816_op_sbc_dpw, g65816_op_inc_dpw, g65816_op_sbc_ildpw, /* ex */ g65816_op_inxb, g65816_op_sbc_constw, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrb, g65816_op_sbc_addrw, g65816_op_inc_addrw, g65816_op_sbc_longw,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyw, g65816_op_sbc_idpw, g65816_op_sbc_isryw, /* fx */ g65816_op_pea, g65816_op_sbc_dpxw, g65816_op_inc_dpxw, g65816_op_sbc_ildpyw, /* fx */ g65816_op_sed, g65816_op_sbc_addryw, g65816_op_plxb, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxw, g65816_op_inc_addrxw, g65816_op_sbc_longxw
|
||||
};
|
||||
|
||||
vfunc g65816_optbl_mx[256] = { // g65816_optbl_mx, g65816_optbl_mx, g65816_optbl_mx,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxw, g65816_op_cop, g65816_op_ora_srw, /* 0x */ g65816_op_tsb_dpw, g65816_op_ora_dpw, g65816_op_asl_dpw, g65816_op_ora_ildpw, /* 0x */ g65816_op_php, g65816_op_ora_constw, g65816_op_aslw, g65816_op_phd, /* 0x */ g65816_op_tsb_addrw, g65816_op_ora_addrw, g65816_op_asl_addrw, g65816_op_ora_longw,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyw, g65816_op_ora_idpw, g65816_op_ora_isryw, /* 1x */ g65816_op_trb_dpw, g65816_op_ora_dpxw, g65816_op_asl_dpxw, g65816_op_ora_ildpyw, /* 1x */ g65816_op_clc, g65816_op_ora_addryw, g65816_op_incw, g65816_op_tcsn, /* 1x */ g65816_op_trb_addrw, g65816_op_ora_addrxw, g65816_op_asl_addrxw, g65816_op_ora_longxw,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxw, g65816_op_jsr_long, g65816_op_and_srw, /* 2x */ g65816_op_bit_dpw, g65816_op_and_dpw, g65816_op_rol_dpw, g65816_op_and_ildpw, /* 2x */ g65816_op_plp, g65816_op_and_constw, g65816_op_rolw, g65816_op_pld, /* 2x */ g65816_op_bit_addrw, g65816_op_and_addrw, g65816_op_rol_addrw, g65816_op_and_longw,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyw, g65816_op_and_idpw, g65816_op_and_isryw, /* 3x */ g65816_op_bit_dpxw, g65816_op_and_dpxw, g65816_op_rol_dpxw, g65816_op_and_ildpyw, /* 3x */ g65816_op_sec, g65816_op_and_addryw, g65816_op_decw, g65816_op_tscn, /* 3x */ g65816_op_bit_addrxw, g65816_op_and_addrxw, g65816_op_rol_addrxw, g65816_op_and_longxw,
|
||||
|
||||
/* 4x */ g65816_op_rtin, g65816_op_eor_idpxw, g65816_op_wdm, g65816_op_eor_srw, /* 4x */ g65816_op_mvp, g65816_op_eor_dpw, g65816_op_lsr_dpw, g65816_op_eor_ildpw, /* 4x */ g65816_op_phaw, g65816_op_eor_constw, g65816_op_lsrw, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrw, g65816_op_lsr_addrw, g65816_op_eor_longw,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyw, g65816_op_eor_idpw, g65816_op_eor_isryw, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxw, g65816_op_lsr_dpxw, g65816_op_eor_ildpyw, /* 5x */ g65816_op_cli, g65816_op_eor_addryw, g65816_op_phyw, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxw, g65816_op_lsr_addrxw, g65816_op_eor_longxw,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxw, g65816_op_per, g65816_op_adc_srw, /* 6x */ g65816_op_stz_dpw, g65816_op_adc_dpw, g65816_op_ror_dpw, g65816_op_adc_ildpw, /* 6x */ g65816_op_plaw, g65816_op_adc_constw, g65816_op_rorw, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrw, g65816_op_ror_addrw, g65816_op_adc_longw,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyw, g65816_op_adc_idpw, g65816_op_adc_isryw, /* 7x */ g65816_op_stz_dpxw, g65816_op_adc_dpxw, g65816_op_ror_dpxw, g65816_op_adc_ildpyw, /* 7x */ g65816_op_sei, g65816_op_adc_addryw, g65816_op_plyw, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxw, g65816_op_ror_addrxw, g65816_op_adc_longxw,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxw, g65816_op_brl, g65816_op_sta_srw, /* 8x */ g65816_op_sty_dpw, g65816_op_sta_dpw, g65816_op_stx_dpw, g65816_op_sta_ildpw, /* 8x */ g65816_op_deyw, g65816_op_bit_constw, g65816_op_txaw, g65816_op_phb, /* 8x */ g65816_op_sty_addrw, g65816_op_sta_addrw, g65816_op_stx_addrw, g65816_op_sta_longw,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyw, g65816_op_sta_idpw, g65816_op_sta_isryw, /* 9x */ g65816_op_sty_dpxw, g65816_op_sta_dpxw, g65816_op_stx_dpyw, g65816_op_sta_ildpyw, /* 9x */ g65816_op_tyaw, g65816_op_sta_addryw, g65816_op_txsw, g65816_op_txyw, /* 9x */ g65816_op_stz_addrw, g65816_op_sta_addrxw, g65816_op_stz_addrxw, g65816_op_sta_longxw,
|
||||
/* ax */ g65816_op_ldy_constw, g65816_op_lda_idpxw, g65816_op_ldx_constw, g65816_op_lda_srw, /* ax */ g65816_op_ldy_dpw, g65816_op_lda_dpw, g65816_op_ldx_dpw, g65816_op_lda_ildpw, /* ax */ g65816_op_tayw, g65816_op_lda_constw, g65816_op_taxw, g65816_op_plb, /* ax */ g65816_op_ldy_addrw, g65816_op_lda_addrw, g65816_op_ldx_addrw, g65816_op_lda_longw,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyw, g65816_op_lda_idpw, g65816_op_lda_isryw, /* bx */ g65816_op_ldy_dpxw, g65816_op_lda_dpxw, g65816_op_ldx_dpyw, g65816_op_lda_ildpyw, /* bx */ g65816_op_clv, g65816_op_lda_addryw, g65816_op_tsxw, g65816_op_tyxw, /* bx */ g65816_op_ldy_addrxw, g65816_op_lda_addrxw, g65816_op_ldx_addryw, g65816_op_lda_longxw,
|
||||
|
||||
/* cx */ g65816_op_cpy_constw, g65816_op_cmp_idpxw, g65816_op_rep, g65816_op_cmp_srw, /* cx */ g65816_op_cpy_dpw, g65816_op_cmp_dpw, g65816_op_dec_dpw, g65816_op_cmp_ildpw, /* cx */ g65816_op_inyw, g65816_op_cmp_constw, g65816_op_dexw, g65816_op_wai, /* cx */ g65816_op_cpy_addrw, g65816_op_cmp_addrw, g65816_op_dec_addrw, g65816_op_cmp_longw,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyw, g65816_op_cmp_idpw, g65816_op_cmp_isryw, /* dx */ g65816_op_pei, g65816_op_cmp_dpxw, g65816_op_dec_dpxw, g65816_op_cmp_ildpyw, /* dx */ g65816_op_cld, g65816_op_cmp_addryw, g65816_op_phxw, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxw, g65816_op_dec_addrxw, g65816_op_cmp_longxw,
|
||||
/* ex */ g65816_op_cpx_constw, g65816_op_sbc_idpxw, g65816_op_sep, g65816_op_sbc_srw, /* ex */ g65816_op_cpx_dpw, g65816_op_sbc_dpw, g65816_op_inc_dpw, g65816_op_sbc_ildpw, /* ex */ g65816_op_inxw, g65816_op_sbc_constw, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrw, g65816_op_sbc_addrw, g65816_op_inc_addrw, g65816_op_sbc_longw,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyw, g65816_op_sbc_idpw, g65816_op_sbc_isryw, /* fx */ g65816_op_pea, g65816_op_sbc_dpxw, g65816_op_inc_dpxw, g65816_op_sbc_ildpyw, /* fx */ g65816_op_sed, g65816_op_sbc_addryw, g65816_op_plxw, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxw, g65816_op_inc_addrxw, g65816_op_sbc_longxw
|
||||
};
|
||||
@@ -0,0 +1,526 @@
|
||||
void g65816_flags_adc_b(void) {
|
||||
int r = gx816->regs.a.b + gx816->op.r.b + (gx816->regs.p & PF_C);
|
||||
//bcd
|
||||
if(gx816->regs.p & PF_D) {
|
||||
if(((r ) & 15) > 9)r += 6;
|
||||
if(((r >> 4) & 15) > 9)r += 6 << 4;
|
||||
}
|
||||
|
||||
g65816_testn(r & 0x80);
|
||||
g65816_testv(~(gx816->regs.a.b ^ gx816->op.r.b) & (gx816->regs.a.b ^ (byte)r) & 0x80);
|
||||
g65816_testz((byte)r == 0);
|
||||
g65816_testc(r > 0xff);
|
||||
gx816->regs.a.b = r;
|
||||
}
|
||||
|
||||
void g65816_flags_adc_w(void) {
|
||||
int r = gx816->regs.a.w + gx816->op.r.w + (gx816->regs.p & PF_C);
|
||||
//bcd
|
||||
if(gx816->regs.p & PF_D) {
|
||||
if(((r ) & 15) > 9)r += 6;
|
||||
if(((r >> 4) & 15) > 9)r += 6 << 4;
|
||||
if(((r >> 8) & 15) > 9)r += 6 << 8;
|
||||
if(((r >> 12) & 15) > 9)r += 6 << 12;
|
||||
}
|
||||
|
||||
g65816_testn(r & 0x8000);
|
||||
g65816_testv(~(gx816->regs.a.w ^ gx816->op.r.w) & (gx816->regs.a.w ^ (word)r) & 0x8000);
|
||||
g65816_testz((word)r == 0);
|
||||
g65816_testc(r > 0xffff);
|
||||
gx816->regs.a.w = r;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x69: adc #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_constb(void) {
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_constw(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x6d: adc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_adc_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7d: adc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_adc_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x65: adc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x72: adc (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x67: adc [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x6f: adc long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_adc_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_adc_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7f: adc long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_adc_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_adc_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x79: adc addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_adc_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x75: adc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_adc_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x61: adc (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x71: adc (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x77: adc [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x63: adc sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x73: adc (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,504 @@
|
||||
void g65816_flags_and_b() {
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
}
|
||||
|
||||
void g65816_flags_and_w() {
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x29: and #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_constb(void) {
|
||||
gx816->regs.a.b &= gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_constw(void) {
|
||||
gx816->regs.a.w &= gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2d: and addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_and_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3d: and addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_and_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x25: and dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x32: and (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x27: and [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2f: and long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_and_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_and_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3f: and long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_and_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_and_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x39: and addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_and_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x35: and dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_and_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x21: and (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x31: and (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x37: and [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x23: and sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x33: and (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
void g65816_flags_cmp_b() {
|
||||
int r = gx816->regs.a.b - gx816->op.r.b;
|
||||
g65816_testn(r & 0x80);
|
||||
g65816_testz((byte)r == 0);
|
||||
g65816_testc(r >= 0);
|
||||
}
|
||||
|
||||
void g65816_flags_cmp_w() {
|
||||
int r = gx816->regs.a.w - gx816->op.r.w;
|
||||
g65816_testn(r & 0x8000);
|
||||
g65816_testz((word)r == 0);
|
||||
g65816_testc(r >= 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xc9: cmp #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_constb(void) {
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_constw(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xcd: cmp addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdd: cmp addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xc5: cmp dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd2: cmp (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xc7: cmp [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xcf: cmp long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdf: cmp long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd9: cmp addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd5: cmp dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xc1: cmp (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd1: cmp (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd7: cmp [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xc3: cmp sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xd3: cmp (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,504 @@
|
||||
void g65816_flags_eor_b() {
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
}
|
||||
|
||||
void g65816_flags_eor_w() {
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x49: eor #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_constb(void) {
|
||||
gx816->regs.a.b ^= gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_constw(void) {
|
||||
gx816->regs.a.w ^= gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x4d: eor addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_eor_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5d: eor addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_eor_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x45: eor dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x52: eor (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x47: eor [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x4f: eor long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_eor_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_eor_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5f: eor long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_eor_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_eor_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x59: eor addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_eor_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x55: eor dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_eor_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x41: eor (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x51: eor (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x57: eor [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x43: eor sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x53: eor (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,511 @@
|
||||
/*****************
|
||||
*** 0x1a: inc ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_incb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.a.b++;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_incw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.a.w++;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xee: inc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_inc_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.b++;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_inc_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.w++;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xfe: inc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_inc_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b++;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_inc_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.w++;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xe6: inc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_inc_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b++;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_inc_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.w++;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf6: inc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_inc_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.b++;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_inc_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.w++;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xe8: inx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_inxb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.x++;
|
||||
gx816->regs.x &= 0xff;
|
||||
g65816_testn(gx816->regs.x & 0x80);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_inxw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.x++;
|
||||
g65816_testn(gx816->regs.x & 0x8000);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xc8: iny ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_inyb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.y++;
|
||||
gx816->regs.y &= 0xff;
|
||||
g65816_testn(gx816->regs.y & 0x80);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_inyw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.y++;
|
||||
g65816_testn(gx816->regs.y & 0x8000);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x3a: dec ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_decb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.a.b--;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_decw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.a.w--;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xce: dec addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_dec_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.b--;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_dec_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.w--;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xde: dec addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_dec_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b--;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_dec_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.w--;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xc6: dec dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_dec_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b--;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_dec_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.w--;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd6: dec dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_dec_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.b--;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_dec_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.w--;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xca: dex ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_dexb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.x--;
|
||||
gx816->regs.x &= 0xff;
|
||||
g65816_testn(gx816->regs.x & 0x80);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_dexw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.x--;
|
||||
g65816_testn(gx816->regs.x & 0x8000);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x88: dey ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_deyb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.y--;
|
||||
gx816->regs.y &= 0xff;
|
||||
g65816_testn(gx816->regs.y & 0x80);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_deyw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.y--;
|
||||
g65816_testn(gx816->regs.y & 0x8000);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
@@ -0,0 +1,504 @@
|
||||
void g65816_flags_lda_b(void) {
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
}
|
||||
|
||||
void g65816_flags_lda_w(void) {
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xa9: lda #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_constb(void) {
|
||||
gx816->regs.a.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_constw(void) {
|
||||
gx816->regs.a.w = gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xad: lda addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lda_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xbd: lda addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lda_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xa5: lda dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb2: lda (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xa7: lda [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xaf: lda long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_lda_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_lda_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xbf: lda long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_lda_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_lda_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb9: lda addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lda_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb5: lda dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_lda_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xa1: lda (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb1: lda (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb7: lda [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xa3: lda sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xb3: lda (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,504 @@
|
||||
void g65816_flags_ora_b() {
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
}
|
||||
|
||||
void g65816_flags_ora_w() {
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x09: ora #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_constb(void) {
|
||||
gx816->regs.a.b |= gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_constw(void) {
|
||||
gx816->regs.a.w |= gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0d: ora addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ora_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1d: ora addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ora_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x05: ora dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x12: ora (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x07: ora [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0f: ora long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_ora_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_ora_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1f: ora long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_ora_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_ora_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x19: ora addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ora_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x15: ora dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_ora_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x01: ora (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x11: ora (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x17: ora [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x03: ora sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x13: ora (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
/**********************
|
||||
*** 0x4c: jmp addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_addr(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x5c: jml long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] pbr,pc+3 ; new pbr
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_long(void) {
|
||||
gx816->regs.pc = gx816->read_operand(3); //1-4 [op fetch]
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x6c: jmp (addr) ***
|
||||
************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,aa ; new pcl
|
||||
[5] 0,aa+1 ; new pch
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_iaddr(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 1); //5 [read high]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x7c: jmp (addr,x) ***
|
||||
**************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] pbr,aa+x ; new pcl
|
||||
[6] pbr,aa+x+1 ; new pch
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_iaddrx(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x + 1); //6 [read high]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdc: jmp [addr] ***
|
||||
************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,aa ; new pcl
|
||||
[5] 0,aa+1 ; new pch
|
||||
[6] 0,aa+2 ; new pbr
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_iladdr(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 1); //5 [read high]
|
||||
gx816->op.r.p.b = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 2); //6 [read bank]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.l;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x20: jsr addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] 0,s ; pch
|
||||
[6] 0,s-1 ; pcl
|
||||
*/
|
||||
|
||||
void g65816_op_jsr_addr(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->regs.pc += 2;
|
||||
gx816->stack_write(gx816->regs.pc >> 8); //5 [write high]
|
||||
gx816->stack_write(gx816->regs.pc); //6 [write low]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x22: jsl long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] 0,s ; pbr
|
||||
[5] 0,s ; io
|
||||
[6] pbr,pc+3 ; new pbr
|
||||
[7] 0,s-1 ; pch
|
||||
[8] 0,s-2 ; pcl
|
||||
*/
|
||||
|
||||
void g65816_op_jsr_long(void) {
|
||||
gx816->op.r.l = gx816->read_operand(3); //1-3,6 [op fetch]
|
||||
gx816->regs.pc += 3;
|
||||
gx816->stack_write(gx816->regs.pc >> 16); //4 [write bank]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->stack_write(gx816->regs.pc >> 8); //7 [write high]
|
||||
gx816->stack_write(gx816->regs.pc); //8 [write low]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.l;
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xfc: jsr (addr,x) ***
|
||||
**************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] 0,s ; pch
|
||||
[4] 0,s-1 ; pcl
|
||||
[5] pbr,pc+2 ; aah
|
||||
[6] pbr,pc+2 ; io
|
||||
[7] pbr,aa+x ; new pcl
|
||||
[8] pbr,aa+x+1 ; new pch
|
||||
*/
|
||||
|
||||
void g65816_op_jsr_iaddrx(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1,2,5 [op fetch]
|
||||
gx816->regs.pc += 2;
|
||||
gx816->stack_write(gx816->regs.pc >> 8); //3 [write high]
|
||||
gx816->stack_write(gx816->regs.pc); //4 [write low]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x + 1); //8 [read high]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x40: rti ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; p
|
||||
[5] 0,s+2 ; new pcl
|
||||
[6] 0,s+3 ; new pch
|
||||
[7] 0,s+4 ; pbr [7]
|
||||
*/
|
||||
|
||||
void g65816_op_rtie(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.p = gx816->stack_read(); //4 [read p]
|
||||
gx816->op.r.p.l = gx816->stack_read(); //5 [read pcl]
|
||||
gx816->op.r.p.h = gx816->stack_read(); //6 [read pch]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
|
||||
gx816->regs.p &= ~ PF_I;
|
||||
}
|
||||
|
||||
void g65816_op_rtin(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.p = gx816->stack_read(); //4 [read p]
|
||||
gx816->op.r.p.l = gx816->stack_read(); //5 [read pcl]
|
||||
gx816->op.r.p.h = gx816->stack_read(); //6 [read pch]
|
||||
gx816->op.r.p.b = gx816->stack_read(); //7 [read pbr]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.l;
|
||||
if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
|
||||
gx816->regs.p &= ~ PF_I;
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x60: rts ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; pcl
|
||||
[5] 0,s+2 ; pch
|
||||
[6] 0,s+2 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_rts(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->op.r.p.l = gx816->stack_read(); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->stack_read(); //5 [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x6b: rtl ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; pcl
|
||||
[5] 0,s+2 ; pch
|
||||
[6] 0,s+3 ; pbr
|
||||
*/
|
||||
|
||||
void g65816_op_rtl(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->op.r.p.l = gx816->stack_read(); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->stack_read(); //5 [read high]
|
||||
gx816->op.r.p.b = gx816->stack_read(); //6 [read bank]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.l;
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x80: bra near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bra(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*********************
|
||||
*** 0x82: brl far ***
|
||||
*********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; offset low
|
||||
[3] pbr,pc+2 ; offset high
|
||||
[4] pbr,pc+2 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_brl(void) {
|
||||
word r;
|
||||
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
r = gx816->regs.pc + (signed short)gx816->op.r.w;
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x90: bcc near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bcc(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(!(gx816->regs.p & PF_C)) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb0: bcs near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bcs(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(gx816->regs.p & PF_C) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd0: bne near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bne(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(!(gx816->regs.p & PF_Z)) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf0: beq near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_beq(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(gx816->regs.p & PF_Z) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x10: bpl near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bpl(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(!(gx816->regs.p & PF_N)) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x30: bmi near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bmi(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(gx816->regs.p & PF_N) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x50: bvc near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bvc(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(!(gx816->regs.p & PF_V)) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x70: bvs near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bvs(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(gx816->regs.p & PF_V) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
void g65816_flags_sbc_b() {
|
||||
int r = gx816->regs.a.b - gx816->op.r.b - !(gx816->regs.p & PF_C);
|
||||
//bcd
|
||||
if(gx816->regs.p & PF_D) {
|
||||
if(((r ) & 15) > 9)r -= 6;
|
||||
if(((r >> 4) & 15) > 9)r -= 6 << 4;
|
||||
}
|
||||
|
||||
g65816_testn(r & 0x80);
|
||||
g65816_testv((gx816->regs.a.b ^ gx816->op.r.b) & (gx816->regs.a.b ^ (byte)r) & 0x80);
|
||||
g65816_testz((byte)r == 0);
|
||||
g65816_testc(r >= 0);
|
||||
gx816->regs.a.b = r;
|
||||
}
|
||||
|
||||
void g65816_flags_sbc_w() {
|
||||
int r = gx816->regs.a.w - gx816->op.r.w - !(gx816->regs.p & PF_C);
|
||||
//bcd
|
||||
if(gx816->regs.p & PF_D) {
|
||||
if(((r ) & 15) > 9)r -= 6;
|
||||
if(((r >> 4) & 15) > 9)r -= 6 << 4;
|
||||
if(((r >> 8) & 15) > 9)r -= 6 << 8;
|
||||
if(((r >> 12) & 15) > 9)r -= 6 << 12;
|
||||
}
|
||||
|
||||
g65816_testn(r & 0x8000);
|
||||
g65816_testv((gx816->regs.a.w ^ gx816->op.r.w) & (gx816->regs.a.w ^ (word)r) & 0x8000);
|
||||
g65816_testz((word)r == 0);
|
||||
g65816_testc(r >= 0);
|
||||
gx816->regs.a.w = r;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xe9: sbc #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_constb(void) {
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_constw(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xed: sbc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xfd: sbc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xe5: sbc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf2: sbc (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xe7: sbc [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xef: sbc long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xff: sbc long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf9: sbc addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf5: sbc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xe1: sbc (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf1: sbc (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf7: sbc [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xe3: sbc sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xf3: sbc (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,873 @@
|
||||
/*****************
|
||||
*** 0x0a: asl ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_aslb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.b & 0x80);
|
||||
gx816->regs.a.b <<= 1;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_aslw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.w & 0x8000);
|
||||
gx816->regs.a.w <<= 1;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0e: asl addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_asl_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_asl_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1e: asl addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_asl_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_asl_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x06: asl dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_asl_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_asl_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x16: asl dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_asl_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_asl_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x4a: lsr ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_lsrb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.b & 0x01);
|
||||
gx816->regs.a.b >>= 1;
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_lsrw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.w & 0x0001);
|
||||
gx816->regs.a.w >>= 1;
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
*** 0x4e: lsr addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_lsr_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lsr_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5e: lsr addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_lsr_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lsr_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x46: lsr dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_lsr_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lsr_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x56: lsr dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_lsr_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lsr_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x2a: rol ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_rolb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.b & 0x80);
|
||||
gx816->regs.a.b <<= 1;
|
||||
gx816->regs.a.b |= c;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_rolw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.w & 0x8000);
|
||||
gx816->regs.a.w <<= 1;
|
||||
gx816->regs.a.w |= c;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2e: rol addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_rol_addrb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_rol_addrw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3e: rol addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_rol_addrxb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_rol_addrxw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x26: rol dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_rol_dpb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_rol_dpw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x36: rol dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_rol_dpxb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_rol_dpxw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x6a: ror ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_rorb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.b & 0x01);
|
||||
gx816->regs.a.b >>= 1;
|
||||
gx816->regs.a.b |= c;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_rorw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.w & 0x0001);
|
||||
gx816->regs.a.w >>= 1;
|
||||
gx816->regs.a.w |= c;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
*** 0x6e: ror addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_ror_addrb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ror_addrw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7e: ror addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_ror_addrxb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ror_addrxw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x66: ror dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_ror_dpb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ror_dpw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x76: ror dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_ror_dpxb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ror_dpxw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,443 @@
|
||||
/**********************
|
||||
*** 0x8d: sta addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sta_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x9d: sta addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sta_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x85: sta dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->regs.a.b); //3 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->regs.a.p.l); //3 [write low]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->regs.a.p.h); //3a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x92: sta (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //5 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //5 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //5a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x87: sta [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.b); //6 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.p.l); //6 [write low]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + 1, gx816->regs.a.p.h); //6a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x8f: sta long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sta_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.b); //5 [write]
|
||||
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_sta_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.p.l); //5 [write]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + 1, gx816->regs.a.p.h); //5a [write]
|
||||
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x9f: sta long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sta_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x, gx816->regs.a.b); //5 [write]
|
||||
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_sta_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x, gx816->regs.a.p.l); //5 [write]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1, gx816->regs.a.p.h); //5a [write]
|
||||
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x99: sta addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sta_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x95: sta dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sta_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x81: sta (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //6 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //6 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //6 [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x91: sta (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
snes_time->add_cpu_icycles(1); //4a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //5 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
snes_time->add_cpu_icycles(1); //4a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //5 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //5a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x97: sta [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y, gx816->regs.a.b); //6 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y, gx816->regs.a.p.l); //6 [write low]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1, gx816->regs.a.p.h); //6a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x83: sta sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op_write(OPMODE_SP, gx816->op.sp, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op_write(OPMODE_SP, gx816->op.sp, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_SP, gx816->op.sp + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x93: sta (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //7 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //7 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //7a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
/*****************
|
||||
*** 0x48: pha ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phab(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.a.b); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_phaw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.a.p.h); //3a [reg high]
|
||||
gx816->stack_write(gx816->regs.a.p.l); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x8b: phb ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.db); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x0b: phd ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phd(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.d >> 8); //3a [reg high]
|
||||
gx816->stack_write(gx816->regs.d); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x4b: phk ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phk(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.pc >> 16); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x08: php ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_php(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.p); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xda: phx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phxb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.x); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_phxw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.x >> 8); //3a [reg high]
|
||||
gx816->stack_write(gx816->regs.x); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x5a: phy ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phyb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.y); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_phyw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.y >> 8); //3a [reg high]
|
||||
gx816->stack_write(gx816->regs.y); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x68: pla ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plab(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.a.b = gx816->stack_read(); //4 [reg low]
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_plaw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.a.p.l = gx816->stack_read(); //4 [reg low]
|
||||
gx816->regs.a.p.h = gx816->stack_read(); //4a [reg high]
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xab: plb ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.db = gx816->stack_read(); //4 [reg low]
|
||||
g65816_testn(gx816->regs.db & 0x80);
|
||||
g65816_testz(gx816->regs.db == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x2b: pld ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_pld(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.d = gx816->stack_read(); //4 [reg low]
|
||||
gx816->regs.d |= gx816->stack_read() << 8; //4a [reg high]
|
||||
g65816_testn(gx816->regs.d & 0x8000);
|
||||
g65816_testz(gx816->regs.d == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x28: plp ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plp(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.p = gx816->stack_read(); //4 [reg low]
|
||||
g65816_incpc(1);
|
||||
if(gx816->regs.e == true)gx816->regs.p |= 0x30;
|
||||
if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xfa: plx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plxb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.x = gx816->stack_read(); //4 [reg low]
|
||||
g65816_testn(gx816->regs.x & 0x80);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_plxw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.x = gx816->stack_read(); //4 [reg low]
|
||||
gx816->regs.x |= gx816->stack_read() << 8; //4a [reg high]
|
||||
g65816_testn(gx816->regs.x & 0x8000);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x7a: ply ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plyb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.y = gx816->stack_read(); //4 [reg low]
|
||||
g65816_testn(gx816->regs.y & 0x80);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_plyw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.y = gx816->stack_read(); //4 [reg low]
|
||||
gx816->regs.y |= gx816->stack_read() << 8; //4a [reg high]
|
||||
g65816_testn(gx816->regs.y & 0x8000);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf4: pea addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,s ; aah
|
||||
[5] 0,s-1 ; aal
|
||||
*/
|
||||
|
||||
void g65816_op_pea(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->stack_write(gx816->op.aa.p.h); //4 [write high]
|
||||
gx816->stack_write(gx816->op.aa.p.l); //5 [write low]
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd4: pei (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,s ; aah
|
||||
[6 ] 0,s-1 ; aal
|
||||
*/
|
||||
|
||||
void g65816_op_pei(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [read aah]
|
||||
gx816->stack_write(gx816->op.aa.p.h); //5 [write aah]
|
||||
gx816->stack_write(gx816->op.aa.p.l); //6 [write aal]
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x62: per addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; offset low
|
||||
[3] pbr,pc+2 ; offset high
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] 0,s ; pch+offset
|
||||
[6] 0,s-1 ; pcl+offset
|
||||
*/
|
||||
|
||||
void g65816_op_per(void) {
|
||||
word r;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
r = (gx816->regs.pc + (signed short)gx816->op.aa.w + 3);
|
||||
gx816->stack_write(r >> 8); //5 [write pch]
|
||||
gx816->stack_write(r); //6 [write pcl]
|
||||
g65816_incpc(3);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity type="win32" name="bsnes" version="1.0.0.0" processorArchitecture="*"/>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
||||
@@ -1,8 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=bsnes
|
||||
Comment=SNES emulator
|
||||
Exec=bsnes
|
||||
Icon=bsnes
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Game;Emulator;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB |
-105898
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,136 +0,0 @@
|
||||
#ifndef EMULATOR_HPP
|
||||
#define EMULATOR_HPP
|
||||
|
||||
namespace Emulator {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "089";
|
||||
static const char Author[] = "byuu";
|
||||
static const char License[] = "GPLv3";
|
||||
}
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/dsp.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/priorityqueue.hpp>
|
||||
#include <nall/property.hpp>
|
||||
#include <nall/random.hpp>
|
||||
#include <nall/serializer.hpp>
|
||||
#include <nall/sha256.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
#include <nall/varint.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
#include <nall/stream/memory.hpp>
|
||||
#include <nall/stream/vector.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#include "interface.hpp"
|
||||
|
||||
//debugging function hook:
|
||||
//no overhead (and no debugger invocation) if not compiled with -DDEBUGGER
|
||||
//wraps testing of function to allow invocation without a defined callback
|
||||
template<typename T> struct hook;
|
||||
template<typename R, typename... P> struct hook<R (P...)> {
|
||||
function<R (P...)> callback;
|
||||
|
||||
R operator()(P... p) const {
|
||||
#if defined(DEBUGGER)
|
||||
if(callback) return callback(std::forward<P>(p)...);
|
||||
#endif
|
||||
return R();
|
||||
}
|
||||
|
||||
hook() {}
|
||||
hook(const hook &hook) { callback = hook.callback; }
|
||||
hook(void *function) { callback = function; }
|
||||
hook(R (*function)(P...)) { callback = function; }
|
||||
template<typename C> hook(R (C::*function)(P...), C *object) { callback = {function, object}; }
|
||||
template<typename C> hook(R (C::*function)(P...) const, C *object) { callback = {function, object}; }
|
||||
template<typename L> hook(const L& function) { callback = function; }
|
||||
|
||||
hook& operator=(const hook& hook) { callback = hook.callback; return *this; }
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#define privileged public
|
||||
#else
|
||||
#define privileged private
|
||||
#endif
|
||||
|
||||
typedef int1_t int1;
|
||||
typedef int2_t int2;
|
||||
typedef int3_t int3;
|
||||
typedef int4_t int4;
|
||||
typedef int5_t int5;
|
||||
typedef int6_t int6;
|
||||
typedef int7_t int7;
|
||||
typedef int8_t int8;
|
||||
typedef int9_t int9;
|
||||
typedef int10_t int10;
|
||||
typedef int11_t int11;
|
||||
typedef int12_t int12;
|
||||
typedef int13_t int13;
|
||||
typedef int14_t int14;
|
||||
typedef int15_t int15;
|
||||
typedef int16_t int16;
|
||||
typedef int17_t int17;
|
||||
typedef int18_t int18;
|
||||
typedef int19_t int19;
|
||||
typedef int20_t int20;
|
||||
typedef int21_t int21;
|
||||
typedef int22_t int22;
|
||||
typedef int23_t int23;
|
||||
typedef int24_t int24;
|
||||
typedef int25_t int25;
|
||||
typedef int26_t int26;
|
||||
typedef int27_t int27;
|
||||
typedef int28_t int28;
|
||||
typedef int29_t int29;
|
||||
typedef int30_t int30;
|
||||
typedef int31_t int31;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
|
||||
typedef uint1_t uint1;
|
||||
typedef uint2_t uint2;
|
||||
typedef uint3_t uint3;
|
||||
typedef uint4_t uint4;
|
||||
typedef uint5_t uint5;
|
||||
typedef uint6_t uint6;
|
||||
typedef uint7_t uint7;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint9_t uint9;
|
||||
typedef uint10_t uint10;
|
||||
typedef uint11_t uint11;
|
||||
typedef uint12_t uint12;
|
||||
typedef uint13_t uint13;
|
||||
typedef uint14_t uint14;
|
||||
typedef uint15_t uint15;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint17_t uint17;
|
||||
typedef uint18_t uint18;
|
||||
typedef uint19_t uint19;
|
||||
typedef uint20_t uint20;
|
||||
typedef uint21_t uint21;
|
||||
typedef uint22_t uint22;
|
||||
typedef uint23_t uint23;
|
||||
typedef uint24_t uint24;
|
||||
typedef uint25_t uint25;
|
||||
typedef uint26_t uint26;
|
||||
typedef uint27_t uint27;
|
||||
typedef uint28_t uint28;
|
||||
typedef uint29_t uint29;
|
||||
typedef uint30_t uint30;
|
||||
typedef uint31_t uint31;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint_t<33> uint33;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
typedef varuint_t<unsigned> varuint;
|
||||
|
||||
#endif
|
||||
@@ -1,108 +0,0 @@
|
||||
#ifndef EMULATOR_INTERFACE_HPP
|
||||
#define EMULATOR_INTERFACE_HPP
|
||||
|
||||
namespace Emulator {
|
||||
|
||||
struct Interface {
|
||||
struct Information {
|
||||
string name;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
bool overscan;
|
||||
double aspectRatio;
|
||||
bool resettable;
|
||||
} information;
|
||||
|
||||
struct Media {
|
||||
unsigned id;
|
||||
string name;
|
||||
string type;
|
||||
string path;
|
||||
string extension;
|
||||
};
|
||||
|
||||
vector<Media> firmware;
|
||||
vector<Media> media;
|
||||
|
||||
struct Memory {
|
||||
unsigned id;
|
||||
string name;
|
||||
};
|
||||
vector<Memory> memory;
|
||||
|
||||
struct Device {
|
||||
unsigned id;
|
||||
unsigned portmask;
|
||||
string name;
|
||||
struct Input {
|
||||
unsigned id;
|
||||
unsigned type; //0 = digital, 1 = analog
|
||||
string name;
|
||||
unsigned guid;
|
||||
};
|
||||
vector<Input> input;
|
||||
vector<unsigned> order;
|
||||
};
|
||||
|
||||
struct Port {
|
||||
unsigned id;
|
||||
string name;
|
||||
vector<Device> device;
|
||||
};
|
||||
vector<Port> port;
|
||||
|
||||
struct Bind {
|
||||
virtual void loadRequest(unsigned, const string&) {}
|
||||
virtual void loadRequest(unsigned, const string&, const string&, const string&) {}
|
||||
virtual uint32_t videoColor(unsigned, uint16_t, uint16_t, uint16_t) { return 0u; }
|
||||
virtual void videoRefresh(const uint32_t*, unsigned, unsigned, unsigned) {}
|
||||
virtual void audioSample(int16_t, int16_t) {}
|
||||
virtual int16_t inputPoll(unsigned, unsigned, unsigned) { return 0; }
|
||||
virtual unsigned dipSettings(const XML::Node&) { return 0; }
|
||||
virtual string path(unsigned) { return ""; }
|
||||
} *bind;
|
||||
|
||||
//callback bindings (provided by user interface)
|
||||
void loadRequest(unsigned id, const string &path) { return bind->loadRequest(id, path); }
|
||||
void loadRequest(unsigned id, const string &name, const string &type, const string &path) { return bind->loadRequest(id, name, type, path); }
|
||||
uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { return bind->videoColor(source, red, green, blue); }
|
||||
void videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height) { return bind->videoRefresh(data, pitch, width, height); }
|
||||
void audioSample(int16_t lsample, int16_t rsample) { return bind->audioSample(lsample, rsample); }
|
||||
int16_t inputPoll(unsigned port, unsigned device, unsigned input) { return bind->inputPoll(port, device, input); }
|
||||
unsigned dipSettings(const XML::Node &node) { return bind->dipSettings(node); }
|
||||
string path(unsigned group) { return bind->path(group); }
|
||||
|
||||
//information
|
||||
virtual double videoFrequency() = 0;
|
||||
virtual double audioFrequency() = 0;
|
||||
|
||||
//media interface
|
||||
virtual bool loaded() { return false; }
|
||||
virtual string sha256() { return ""; }
|
||||
virtual unsigned group(unsigned id) { return 0u; }
|
||||
virtual void load(unsigned id, const stream &memory, const string &markup = "") {}
|
||||
virtual void save(unsigned id, const stream &memory) {}
|
||||
virtual void unload() {}
|
||||
|
||||
//system interface
|
||||
virtual void connect(unsigned port, unsigned device) {}
|
||||
virtual void power() {}
|
||||
virtual void reset() {}
|
||||
virtual void run() {}
|
||||
|
||||
//state functions
|
||||
virtual serializer serialize() = 0;
|
||||
virtual bool unserialize(serializer&) = 0;
|
||||
|
||||
//cheat functions
|
||||
virtual void cheatSet(const lstring& = lstring{}) {}
|
||||
|
||||
//utility functions
|
||||
virtual void updatePalette() {}
|
||||
|
||||
Interface() : bind(nullptr) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
fc_objects := fc-interface fc-system fc-scheduler fc-input
|
||||
fc_objects += fc-memory fc-cartridge fc-cpu fc-apu fc-ppu
|
||||
fc_objects += fc-cheat fc-video
|
||||
objects += $(fc_objects)
|
||||
|
||||
obj/fc-interface.o: $(fc)/interface/interface.cpp $(call rwildcard,$(fc)/interface/)
|
||||
obj/fc-system.o: $(fc)/system/system.cpp $(call rwildcard,$(fc)/system/)
|
||||
obj/fc-scheduler.o: $(fc)/scheduler/scheduler.cpp $(call rwildcard,$(fc)/scheduler/)
|
||||
obj/fc-input.o: $(fc)/input/input.cpp $(call rwildcard,$(fc)/input/)
|
||||
obj/fc-memory.o: $(fc)/memory/memory.cpp $(call rwildcard,$(fc)/memory/)
|
||||
obj/fc-cartridge.o: $(fc)/cartridge/cartridge.cpp $(call rwildcard,$(fc)/cartridge/)
|
||||
obj/fc-cpu.o: $(fc)/cpu/cpu.cpp $(call rwildcard,$(fc)/cpu/)
|
||||
obj/fc-apu.o: $(fc)/apu/apu.cpp $(call rwildcard,$(fc)/apu/)
|
||||
obj/fc-ppu.o: $(fc)/ppu/ppu.cpp $(call rwildcard,$(fc)/ppu/)
|
||||
obj/fc-cheat.o: $(fc)/cheat/cheat.cpp $(call rwildcard,$(fc)/cheat/)
|
||||
obj/fc-video.o: $(fc)/video/video.cpp $(call rwildcard,$(fc)/video/)
|
||||
@@ -1,329 +0,0 @@
|
||||
#include <fc/fc.hpp>
|
||||
|
||||
namespace Famicom {
|
||||
|
||||
#include "envelope.cpp"
|
||||
#include "sweep.cpp"
|
||||
#include "pulse.cpp"
|
||||
#include "triangle.cpp"
|
||||
#include "noise.cpp"
|
||||
#include "dmc.cpp"
|
||||
#include "serialization.cpp"
|
||||
APU apu;
|
||||
|
||||
const uint8 APU::length_counter_table[32] = {
|
||||
0x0a, 0xfe, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06, 0xa0, 0x08, 0x3c, 0x0a, 0x0e, 0x0c, 0x1a, 0x0e,
|
||||
0x0c, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16, 0xc0, 0x18, 0x48, 0x1a, 0x10, 0x1c, 0x20, 0x1e,
|
||||
};
|
||||
|
||||
const uint16 APU::ntsc_noise_period_table[16] = {
|
||||
4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068,
|
||||
};
|
||||
|
||||
const uint16 APU::pal_noise_period_table[16] = {
|
||||
4, 7, 14, 30, 60, 88, 118, 148, 188, 236, 354, 472, 708, 944, 1890, 3778,
|
||||
};
|
||||
|
||||
const uint16 APU::ntsc_dmc_period_table[16] = {
|
||||
428, 380, 340, 320, 286, 254, 226, 214, 190, 160, 142, 128, 106, 84, 72, 54,
|
||||
};
|
||||
|
||||
const uint16 APU::pal_dmc_period_table[16] = {
|
||||
398, 354, 316, 298, 276, 236, 210, 198, 176, 148, 132, 118, 98, 78, 66, 50,
|
||||
};
|
||||
|
||||
void APU::Main() {
|
||||
apu.main();
|
||||
}
|
||||
|
||||
void APU::main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
unsigned pulse_output, triangle_output, noise_output, dmc_output;
|
||||
|
||||
pulse_output = pulse[0].clock();
|
||||
pulse_output += pulse[1].clock();
|
||||
triangle_output = triangle.clock();
|
||||
noise_output = noise.clock();
|
||||
dmc_output = dmc.clock();
|
||||
|
||||
clock_frame_counter_divider();
|
||||
|
||||
signed output = pulse_dac[pulse_output] + dmc_triangle_noise_dac[dmc_output][triangle_output][noise_output];
|
||||
|
||||
output = filter.run_hipass_strong(output);
|
||||
output += cartridge_sample;
|
||||
output = filter.run_hipass_weak(output);
|
||||
//output = filter.run_lopass(output);
|
||||
output = sclamp<16>(output);
|
||||
|
||||
interface->audioSample(output, output);
|
||||
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
void APU::tick() {
|
||||
clock += 12;
|
||||
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
|
||||
}
|
||||
|
||||
void APU::set_irq_line() {
|
||||
cpu.set_irq_apu_line(frame.irq_pending || dmc.irq_pending);
|
||||
}
|
||||
|
||||
void APU::set_sample(int16 sample) {
|
||||
cartridge_sample = sample;
|
||||
}
|
||||
|
||||
void APU::power() {
|
||||
filter.hipass_strong = 0;
|
||||
filter.hipass_weak = 0;
|
||||
filter.lopass = 0;
|
||||
|
||||
pulse[0].power();
|
||||
pulse[1].power();
|
||||
triangle.power();
|
||||
noise.power();
|
||||
dmc.power();
|
||||
}
|
||||
|
||||
void APU::reset() {
|
||||
create(APU::Main, 21477272);
|
||||
|
||||
pulse[0].reset();
|
||||
pulse[1].reset();
|
||||
triangle.reset();
|
||||
noise.reset();
|
||||
dmc.reset();
|
||||
|
||||
frame.irq_pending = 0;
|
||||
|
||||
frame.mode = 0;
|
||||
frame.counter = 0;
|
||||
frame.divider = 1;
|
||||
|
||||
enabled_channels = 0;
|
||||
cartridge_sample = 0;
|
||||
|
||||
set_irq_line();
|
||||
}
|
||||
|
||||
uint8 APU::read(uint16 addr) {
|
||||
if(addr == 0x4015) {
|
||||
uint8 result = 0x00;
|
||||
result |= pulse[0].length_counter ? 0x01 : 0;
|
||||
result |= pulse[1].length_counter ? 0x02 : 0;
|
||||
result |= triangle.length_counter ? 0x04 : 0;
|
||||
result |= noise.length_counter ? 0x08 : 0;
|
||||
result |= dmc.length_counter ? 0x10 : 0;
|
||||
result |= frame.irq_pending ? 0x40 : 0;
|
||||
result |= dmc.irq_pending ? 0x80 : 0;
|
||||
|
||||
frame.irq_pending = false;
|
||||
set_irq_line();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void APU::write(uint16 addr, uint8 data) {
|
||||
const unsigned n = (addr >> 2) & 1; //pulse#
|
||||
|
||||
switch(addr) {
|
||||
case 0x4000: case 0x4004:
|
||||
pulse[n].duty = data >> 6;
|
||||
pulse[n].envelope.loop_mode = data & 0x20;
|
||||
pulse[n].envelope.use_speed_as_volume = data & 0x10;
|
||||
pulse[n].envelope.speed = data & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x4001: case 0x4005:
|
||||
pulse[n].sweep.enable = data & 0x80;
|
||||
pulse[n].sweep.period = (data & 0x70) >> 4;
|
||||
pulse[n].sweep.decrement = data & 0x08;
|
||||
pulse[n].sweep.shift = data & 0x07;
|
||||
pulse[n].sweep.reload = true;
|
||||
break;
|
||||
|
||||
case 0x4002: case 0x4006:
|
||||
pulse[n].period = (pulse[n].period & 0x0700) | (data << 0);
|
||||
pulse[n].sweep.pulse_period = (pulse[n].sweep.pulse_period & 0x0700) | (data << 0);
|
||||
break;
|
||||
|
||||
case 0x4003: case 0x4007:
|
||||
pulse[n].period = (pulse[n].period & 0x00ff) | (data << 8);
|
||||
pulse[n].sweep.pulse_period = (pulse[n].sweep.pulse_period & 0x00ff) | (data << 8);
|
||||
|
||||
pulse[n].duty_counter = 7;
|
||||
pulse[n].envelope.reload_decay = true;
|
||||
|
||||
if(enabled_channels & (1 << n)) {
|
||||
pulse[n].length_counter = length_counter_table[(data >> 3) & 0x1f];
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4008:
|
||||
triangle.halt_length_counter = data & 0x80;
|
||||
triangle.linear_length = data & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x400a:
|
||||
triangle.period = (triangle.period & 0x0700) | (data << 0);
|
||||
break;
|
||||
|
||||
case 0x400b:
|
||||
triangle.period = (triangle.period & 0x00ff) | (data << 8);
|
||||
|
||||
triangle.reload_linear = true;
|
||||
|
||||
if(enabled_channels & (1 << 2)) {
|
||||
triangle.length_counter = length_counter_table[(data >> 3) & 0x1f];
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x400c:
|
||||
noise.envelope.loop_mode = data & 0x20;
|
||||
noise.envelope.use_speed_as_volume = data & 0x10;
|
||||
noise.envelope.speed = data & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x400e:
|
||||
noise.short_mode = data & 0x80;
|
||||
noise.period = data & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x400f:
|
||||
noise.envelope.reload_decay = true;
|
||||
|
||||
if(enabled_channels & (1 << 3)) {
|
||||
noise.length_counter = length_counter_table[(data >> 3) & 0x1f];
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4010:
|
||||
dmc.irq_enable = data & 0x80;
|
||||
dmc.loop_mode = data & 0x40;
|
||||
dmc.period = data & 0x0f;
|
||||
|
||||
dmc.irq_pending = dmc.irq_pending && dmc.irq_enable && !dmc.loop_mode;
|
||||
set_irq_line();
|
||||
break;
|
||||
|
||||
case 0x4011:
|
||||
dmc.dac_latch = data & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x4012:
|
||||
dmc.addr_latch = data;
|
||||
break;
|
||||
|
||||
case 0x4013:
|
||||
dmc.length_latch = data;
|
||||
break;
|
||||
|
||||
case 0x4015:
|
||||
if((data & 0x01) == 0) pulse[0].length_counter = 0;
|
||||
if((data & 0x02) == 0) pulse[1].length_counter = 0;
|
||||
if((data & 0x04) == 0) triangle.length_counter = 0;
|
||||
if((data & 0x08) == 0) noise.length_counter = 0;
|
||||
|
||||
(data & 0x10) ? dmc.start() : dmc.stop();
|
||||
dmc.irq_pending = false;
|
||||
|
||||
set_irq_line();
|
||||
enabled_channels = data & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x4017:
|
||||
frame.mode = data >> 6;
|
||||
|
||||
frame.counter = 0;
|
||||
if(frame.mode & 2) clock_frame_counter();
|
||||
if(frame.mode & 1) {
|
||||
frame.irq_pending = false;
|
||||
set_irq_line();
|
||||
}
|
||||
frame.divider = FrameCounter::NtscPeriod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
signed APU::Filter::run_hipass_strong(signed sample) {
|
||||
hipass_strong += ((((int64)sample << 16) - (hipass_strong >> 16)) * HiPassStrong) >> 16;
|
||||
return sample - (hipass_strong >> 32);
|
||||
}
|
||||
|
||||
signed APU::Filter::run_hipass_weak(signed sample) {
|
||||
hipass_weak += ((((int64)sample << 16) - (hipass_weak >> 16)) * HiPassWeak) >> 16;
|
||||
return sample - (hipass_weak >> 32);
|
||||
}
|
||||
|
||||
signed APU::Filter::run_lopass(signed sample) {
|
||||
lopass += ((((int64)sample << 16) - (lopass >> 16)) * LoPass) >> 16;
|
||||
return (lopass >> 32);
|
||||
}
|
||||
|
||||
void APU::clock_frame_counter() {
|
||||
frame.counter++;
|
||||
|
||||
if(frame.counter & 1) {
|
||||
pulse[0].clock_length();
|
||||
pulse[0].sweep.clock(0);
|
||||
pulse[1].clock_length();
|
||||
pulse[1].sweep.clock(1);
|
||||
triangle.clock_length();
|
||||
noise.clock_length();
|
||||
}
|
||||
|
||||
pulse[0].envelope.clock();
|
||||
pulse[1].envelope.clock();
|
||||
triangle.clock_linear_length();
|
||||
noise.envelope.clock();
|
||||
|
||||
if(frame.counter == 0) {
|
||||
if(frame.mode & 2) frame.divider += FrameCounter::NtscPeriod;
|
||||
if(frame.mode == 0) {
|
||||
frame.irq_pending = true;
|
||||
set_irq_line();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APU::clock_frame_counter_divider() {
|
||||
frame.divider -= 2;
|
||||
if(frame.divider <= 0) {
|
||||
clock_frame_counter();
|
||||
frame.divider += FrameCounter::NtscPeriod;
|
||||
}
|
||||
}
|
||||
|
||||
APU::APU() {
|
||||
for(unsigned amp = 0; amp < 32; amp++) {
|
||||
if(amp == 0) {
|
||||
pulse_dac[amp] = 0;
|
||||
} else {
|
||||
pulse_dac[amp] = 16384.0 * 95.88 / (8128.0 / amp + 100.0);
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned dmc_amp = 0; dmc_amp < 128; dmc_amp++) {
|
||||
for(unsigned triangle_amp = 0; triangle_amp < 16; triangle_amp++) {
|
||||
for(unsigned noise_amp = 0; noise_amp < 16; noise_amp++) {
|
||||
if(dmc_amp == 0 && triangle_amp == 0 && noise_amp == 0) {
|
||||
dmc_triangle_noise_dac[dmc_amp][triangle_amp][noise_amp] = 0;
|
||||
} else {
|
||||
dmc_triangle_noise_dac[dmc_amp][triangle_amp][noise_amp]
|
||||
= 16384.0 * 159.79 / (100.0 + 1.0 / (triangle_amp / 8227.0 + noise_amp / 12241.0 + dmc_amp / 22638.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
struct APU : Thread {
|
||||
static void Main();
|
||||
void main();
|
||||
void tick();
|
||||
void set_irq_line();
|
||||
void set_sample(int16 sample);
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read(uint16 addr);
|
||||
void write(uint16 addr, uint8 data);
|
||||
|
||||
void serialize(serializer&);
|
||||
APU();
|
||||
|
||||
struct Filter {
|
||||
enum : signed { HiPassStrong = 225574, HiPassWeak = 57593, LoPass = 86322413 };
|
||||
|
||||
int64 hipass_strong;
|
||||
int64 hipass_weak;
|
||||
int64 lopass;
|
||||
|
||||
signed run_hipass_strong(signed sample);
|
||||
signed run_hipass_weak(signed sample);
|
||||
signed run_lopass(signed sample);
|
||||
void serialize(serializer&);
|
||||
} filter;
|
||||
|
||||
#include "envelope.hpp"
|
||||
#include "sweep.hpp"
|
||||
#include "pulse.hpp"
|
||||
#include "triangle.hpp"
|
||||
#include "noise.hpp"
|
||||
#include "dmc.hpp"
|
||||
|
||||
struct FrameCounter {
|
||||
enum : unsigned { NtscPeriod = 14915 }; //~(21.477MHz / 6 / 240hz)
|
||||
|
||||
bool irq_pending;
|
||||
|
||||
uint2 mode;
|
||||
uint2 counter;
|
||||
signed divider;
|
||||
|
||||
void serialize(serializer&);
|
||||
} frame;
|
||||
|
||||
void clock_frame_counter();
|
||||
void clock_frame_counter_divider();
|
||||
|
||||
uint8 enabled_channels;
|
||||
int16 cartridge_sample;
|
||||
|
||||
int16 pulse_dac[32];
|
||||
int16 dmc_triangle_noise_dac[128][16][16];
|
||||
|
||||
static const uint8 length_counter_table[32];
|
||||
static const uint16 ntsc_dmc_period_table[16];
|
||||
static const uint16 pal_dmc_period_table[16];
|
||||
static const uint16 ntsc_noise_period_table[16];
|
||||
static const uint16 pal_noise_period_table[16];
|
||||
};
|
||||
|
||||
extern APU apu;
|
||||
@@ -1,117 +0,0 @@
|
||||
void APU::DMC::start() {
|
||||
if(length_counter == 0) {
|
||||
read_addr = 0x4000 + (addr_latch << 6);
|
||||
length_counter = (length_latch << 4) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void APU::DMC::stop() {
|
||||
length_counter = 0;
|
||||
dma_delay_counter = 0;
|
||||
cpu.set_rdy_line(1);
|
||||
cpu.set_rdy_addr({ false, 0u });
|
||||
}
|
||||
|
||||
uint8 APU::DMC::clock() {
|
||||
uint8 result = dac_latch;
|
||||
|
||||
if(dma_delay_counter > 0) {
|
||||
dma_delay_counter--;
|
||||
|
||||
if(dma_delay_counter == 1) {
|
||||
cpu.set_rdy_addr({ true, uint16(0x8000 | read_addr) });
|
||||
} else if(dma_delay_counter == 0) {
|
||||
cpu.set_rdy_line(1);
|
||||
cpu.set_rdy_addr({ false, 0u });
|
||||
|
||||
dma_buffer = cpu.mdr();
|
||||
have_dma_buffer = true;
|
||||
length_counter--;
|
||||
read_addr++;
|
||||
|
||||
if(length_counter == 0) {
|
||||
if(loop_mode) {
|
||||
start();
|
||||
} else if(irq_enable) {
|
||||
irq_pending = true;
|
||||
apu.set_irq_line();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(--period_counter == 0) {
|
||||
if(have_sample) {
|
||||
signed delta = (((sample >> bit_counter) & 1) << 2) - 2;
|
||||
unsigned data = dac_latch + delta;
|
||||
if((data & 0x80) == 0) dac_latch = data;
|
||||
}
|
||||
|
||||
if(++bit_counter == 0) {
|
||||
if(have_dma_buffer) {
|
||||
have_sample = true;
|
||||
sample = dma_buffer;
|
||||
have_dma_buffer = false;
|
||||
} else {
|
||||
have_sample = false;
|
||||
}
|
||||
}
|
||||
|
||||
period_counter = ntsc_dmc_period_table[period];
|
||||
}
|
||||
|
||||
if(length_counter > 0 && have_dma_buffer == false && dma_delay_counter == 0) {
|
||||
cpu.set_rdy_line(0);
|
||||
dma_delay_counter = 4;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void APU::DMC::power() {
|
||||
}
|
||||
|
||||
void APU::DMC::reset() {
|
||||
length_counter = 0;
|
||||
irq_pending = 0;
|
||||
|
||||
period = 0;
|
||||
period_counter = ntsc_dmc_period_table[0];
|
||||
irq_enable = 0;
|
||||
loop_mode = 0;
|
||||
dac_latch = 0;
|
||||
addr_latch = 0;
|
||||
length_latch = 0;
|
||||
read_addr = 0;
|
||||
dma_delay_counter = 0;
|
||||
bit_counter = 0;
|
||||
have_dma_buffer = 0;
|
||||
dma_buffer = 0;
|
||||
have_sample = 0;
|
||||
sample = 0;
|
||||
}
|
||||
|
||||
void APU::DMC::serialize(serializer &s) {
|
||||
s.integer(length_counter);
|
||||
s.integer(irq_pending);
|
||||
|
||||
s.integer(period);
|
||||
s.integer(period_counter);
|
||||
|
||||
s.integer(irq_enable);
|
||||
s.integer(loop_mode);
|
||||
|
||||
s.integer(dac_latch);
|
||||
s.integer(addr_latch);
|
||||
s.integer(length_latch);
|
||||
|
||||
s.integer(read_addr);
|
||||
s.integer(dma_delay_counter);
|
||||
|
||||
s.integer(bit_counter);
|
||||
s.integer(have_dma_buffer);
|
||||
s.integer(dma_buffer);
|
||||
|
||||
s.integer(have_sample);
|
||||
s.integer(sample);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
struct DMC {
|
||||
unsigned length_counter;
|
||||
bool irq_pending;
|
||||
|
||||
uint4 period;
|
||||
unsigned period_counter;
|
||||
|
||||
bool irq_enable;
|
||||
bool loop_mode;
|
||||
|
||||
uint8 dac_latch;
|
||||
uint8 addr_latch;
|
||||
uint8 length_latch;
|
||||
|
||||
uint15 read_addr;
|
||||
unsigned dma_delay_counter;
|
||||
|
||||
uint3 bit_counter;
|
||||
bool have_dma_buffer;
|
||||
uint8 dma_buffer;
|
||||
|
||||
bool have_sample;
|
||||
uint8 sample;
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
uint8 clock();
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
void serialize(serializer&);
|
||||
} dmc;
|
||||
@@ -1,39 +0,0 @@
|
||||
unsigned APU::Envelope::volume() const {
|
||||
return use_speed_as_volume ? speed : decay_volume;
|
||||
}
|
||||
|
||||
void APU::Envelope::clock() {
|
||||
if(reload_decay) {
|
||||
reload_decay = false;
|
||||
decay_volume = 0x0f;
|
||||
decay_counter = speed + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(--decay_counter == 0) {
|
||||
decay_counter = speed + 1;
|
||||
if(decay_volume || loop_mode) decay_volume--;
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Envelope::power() {
|
||||
}
|
||||
|
||||
void APU::Envelope::reset() {
|
||||
speed = 0;
|
||||
use_speed_as_volume = 0;
|
||||
loop_mode = 0;
|
||||
reload_decay = 0;
|
||||
decay_counter = 0;
|
||||
decay_volume = 0;
|
||||
}
|
||||
|
||||
void APU::Envelope::serialize(serializer &s) {
|
||||
s.integer(speed);
|
||||
s.integer(use_speed_as_volume);
|
||||
s.integer(loop_mode);
|
||||
|
||||
s.integer(reload_decay);
|
||||
s.integer(decay_counter);
|
||||
s.integer(decay_volume);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
struct Envelope {
|
||||
uint4 speed;
|
||||
bool use_speed_as_volume;
|
||||
bool loop_mode;
|
||||
|
||||
bool reload_decay;
|
||||
uint8 decay_counter;
|
||||
uint4 decay_volume;
|
||||
|
||||
unsigned volume() const;
|
||||
void clock();
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
void APU::Noise::clock_length() {
|
||||
if(envelope.loop_mode == 0) {
|
||||
if(length_counter > 0) length_counter--;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 APU::Noise::clock() {
|
||||
if(length_counter == 0) return 0;
|
||||
|
||||
uint8 result = (lfsr & 1) ? envelope.volume() : 0;
|
||||
|
||||
if(--period_counter == 0) {
|
||||
unsigned feedback;
|
||||
|
||||
if(short_mode) {
|
||||
feedback = ((lfsr >> 0) & 1) ^ ((lfsr >> 6) & 1);
|
||||
} else {
|
||||
feedback = ((lfsr >> 0) & 1) ^ ((lfsr >> 1) & 1);
|
||||
}
|
||||
|
||||
lfsr = (lfsr >> 1) | (feedback << 14);
|
||||
period_counter = apu.ntsc_noise_period_table[period];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void APU::Noise::power() {
|
||||
}
|
||||
|
||||
void APU::Noise::reset() {
|
||||
length_counter = 0;
|
||||
|
||||
envelope.speed = 0;
|
||||
envelope.use_speed_as_volume = 0;
|
||||
envelope.loop_mode = 0;
|
||||
envelope.reload_decay = 0;
|
||||
envelope.decay_counter = 0;
|
||||
envelope.decay_volume = 0;
|
||||
|
||||
period = 0;
|
||||
period_counter = 1;
|
||||
short_mode = 0;
|
||||
lfsr = 1;
|
||||
}
|
||||
|
||||
void APU::Noise::serialize(serializer &s) {
|
||||
s.integer(length_counter);
|
||||
|
||||
envelope.serialize(s);
|
||||
|
||||
s.integer(period);
|
||||
s.integer(period_counter);
|
||||
|
||||
s.integer(short_mode);
|
||||
s.integer(lfsr);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
struct Noise {
|
||||
unsigned length_counter;
|
||||
|
||||
Envelope envelope;
|
||||
|
||||
uint4 period;
|
||||
unsigned period_counter;
|
||||
|
||||
bool short_mode;
|
||||
uint15 lfsr;
|
||||
|
||||
void clock_length();
|
||||
uint8 clock();
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
void serialize(serializer&);
|
||||
} noise;
|
||||
@@ -1,51 +0,0 @@
|
||||
void APU::Pulse::clock_length() {
|
||||
if(envelope.loop_mode == 0) {
|
||||
if(length_counter) length_counter--;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 APU::Pulse::clock() {
|
||||
if(sweep.check_period() == false) return 0;
|
||||
if(length_counter == 0) return 0;
|
||||
|
||||
static const unsigned duty_table[] = { 1, 2, 4, 6 };
|
||||
uint8 result = (duty_counter < duty_table[duty]) ? envelope.volume() : 0;
|
||||
if(sweep.pulse_period < 0x008) result = 0;
|
||||
|
||||
if(--period_counter == 0) {
|
||||
period_counter = (sweep.pulse_period + 1) * 2;
|
||||
duty_counter++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void APU::Pulse::power() {
|
||||
envelope.power();
|
||||
sweep.power();
|
||||
}
|
||||
|
||||
void APU::Pulse::reset() {
|
||||
envelope.reset();
|
||||
sweep.reset();
|
||||
|
||||
length_counter = 0;
|
||||
|
||||
duty = 0;
|
||||
duty_counter = 0;
|
||||
period = 0;
|
||||
period_counter = 1;
|
||||
}
|
||||
|
||||
void APU::Pulse::serialize(serializer &s) {
|
||||
s.integer(length_counter);
|
||||
|
||||
envelope.serialize(s);
|
||||
sweep.serialize(s);
|
||||
|
||||
s.integer(duty);
|
||||
s.integer(duty_counter);
|
||||
|
||||
s.integer(period);
|
||||
s.integer(period_counter);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
struct Pulse {
|
||||
unsigned length_counter;
|
||||
|
||||
Envelope envelope;
|
||||
Sweep sweep;
|
||||
|
||||
uint2 duty;
|
||||
uint3 duty_counter;
|
||||
|
||||
uint11 period;
|
||||
unsigned period_counter;
|
||||
|
||||
void clock_length();
|
||||
bool check_period();
|
||||
uint8 clock();
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
void serialize(serializer&);
|
||||
} pulse[2];
|
||||
@@ -1,28 +0,0 @@
|
||||
void APU::serialize(serializer &s) {
|
||||
Thread::serialize(s);
|
||||
|
||||
filter.serialize(s);
|
||||
|
||||
pulse[0].serialize(s);
|
||||
pulse[1].serialize(s);
|
||||
triangle.serialize(s);
|
||||
dmc.serialize(s);
|
||||
frame.serialize(s);
|
||||
|
||||
s.integer(enabled_channels);
|
||||
s.integer(cartridge_sample);
|
||||
}
|
||||
|
||||
void APU::Filter::serialize(serializer &s) {
|
||||
s.integer(hipass_strong);
|
||||
s.integer(hipass_weak);
|
||||
s.integer(lopass);
|
||||
}
|
||||
|
||||
void APU::FrameCounter::serialize(serializer &s) {
|
||||
s.integer(irq_pending);
|
||||
|
||||
s.integer(mode);
|
||||
s.integer(counter);
|
||||
s.integer(divider);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
bool APU::Sweep::check_period() {
|
||||
if(pulse_period > 0x7ff) return false;
|
||||
|
||||
if(decrement == 0) {
|
||||
if((pulse_period + (pulse_period >> shift)) & 0x800) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void APU::Sweep::clock(unsigned channel) {
|
||||
if(--counter == 0) {
|
||||
counter = period + 1;
|
||||
if(enable && shift && pulse_period > 8) {
|
||||
signed delta = pulse_period >> shift;
|
||||
|
||||
if(decrement) {
|
||||
pulse_period -= delta;
|
||||
if(channel == 0) pulse_period--;
|
||||
} else if((pulse_period + delta) < 0x800) {
|
||||
pulse_period += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(reload) {
|
||||
reload = false;
|
||||
counter = period + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Sweep::power() {
|
||||
shift = 0;
|
||||
decrement = 0;
|
||||
period = 0;
|
||||
counter = 1;
|
||||
enable = 0;
|
||||
reload = 0;
|
||||
pulse_period = 0;
|
||||
}
|
||||
|
||||
void APU::Sweep::reset() {
|
||||
}
|
||||
|
||||
void APU::Sweep::serialize(serializer &s) {
|
||||
s.integer(shift);
|
||||
s.integer(decrement);
|
||||
s.integer(period);
|
||||
s.integer(counter);
|
||||
s.integer(enable);
|
||||
s.integer(reload);
|
||||
s.integer(pulse_period);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
struct Sweep {
|
||||
uint8 shift;
|
||||
bool decrement;
|
||||
uint3 period;
|
||||
uint8 counter;
|
||||
bool enable;
|
||||
bool reload;
|
||||
uint11 pulse_period;
|
||||
|
||||
bool check_period();
|
||||
void clock(unsigned channel);
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
void APU::Triangle::clock_length() {
|
||||
if(halt_length_counter == 0) {
|
||||
if(length_counter > 0) length_counter--;
|
||||
}
|
||||
}
|
||||
|
||||
void APU::Triangle::clock_linear_length() {
|
||||
if(reload_linear) {
|
||||
linear_length_counter = linear_length;
|
||||
} else if(linear_length_counter) {
|
||||
linear_length_counter--;
|
||||
}
|
||||
|
||||
if(halt_length_counter == 0) reload_linear = false;
|
||||
}
|
||||
|
||||
uint8 APU::Triangle::clock() {
|
||||
uint8 result = step_counter & 0x0f;
|
||||
if((step_counter & 0x10) == 0) result ^= 0x0f;
|
||||
if(length_counter == 0 || linear_length_counter == 0) return result;
|
||||
|
||||
if(--period_counter == 0) {
|
||||
step_counter++;
|
||||
period_counter = period + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void APU::Triangle::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void APU::Triangle::reset() {
|
||||
length_counter = 0;
|
||||
|
||||
linear_length = 0;
|
||||
halt_length_counter = 0;
|
||||
period = 0;
|
||||
period_counter = 1;
|
||||
step_counter = 0;
|
||||
linear_length_counter = 0;
|
||||
reload_linear = 0;
|
||||
}
|
||||
|
||||
void APU::Triangle::serialize(serializer &s) {
|
||||
s.integer(length_counter);
|
||||
|
||||
s.integer(linear_length);
|
||||
s.integer(halt_length_counter);
|
||||
|
||||
s.integer(period);
|
||||
s.integer(period_counter);
|
||||
|
||||
s.integer(step_counter);
|
||||
s.integer(linear_length_counter);
|
||||
s.integer(reload_linear);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
struct Triangle {
|
||||
unsigned length_counter;
|
||||
|
||||
uint8 linear_length;
|
||||
bool halt_length_counter;
|
||||
|
||||
uint11 period;
|
||||
unsigned period_counter;
|
||||
|
||||
uint5 step_counter;
|
||||
uint8 linear_length_counter;
|
||||
bool reload_linear;
|
||||
|
||||
void clock_length();
|
||||
void clock_linear_length();
|
||||
uint8 clock();
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
void serialize(serializer&);
|
||||
} triangle;
|
||||
@@ -1,117 +0,0 @@
|
||||
//BANDAI-FCG
|
||||
|
||||
struct BandaiFCG : Board {
|
||||
|
||||
uint8 chr_bank[8];
|
||||
uint8 prg_bank;
|
||||
uint2 mirror;
|
||||
bool irq_counter_enable;
|
||||
uint16 irq_counter;
|
||||
uint16 irq_latch;
|
||||
|
||||
void main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(irq_counter_enable) {
|
||||
if(--irq_counter == 0xffff) {
|
||||
cpu.set_irq_line(1);
|
||||
irq_counter_enable = false;
|
||||
}
|
||||
}
|
||||
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) const {
|
||||
switch(mirror) {
|
||||
case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff);
|
||||
case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
case 2: return 0x0000 | (addr & 0x03ff);
|
||||
case 3: return 0x0400 | (addr & 0x03ff);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr & 0x8000) {
|
||||
bool region = addr & 0x4000;
|
||||
unsigned bank = (region == 0 ? prg_bank : 0x0f);
|
||||
return prgrom.read((bank << 14) | (addr & 0x3fff));
|
||||
}
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr >= 0x6000) {
|
||||
switch(addr & 15) {
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
chr_bank[addr & 7] = data;
|
||||
break;
|
||||
case 0x08:
|
||||
prg_bank = data & 0x0f;
|
||||
break;
|
||||
case 0x09:
|
||||
mirror = data & 0x03;
|
||||
break;
|
||||
case 0x0a:
|
||||
cpu.set_irq_line(0);
|
||||
irq_counter_enable = data & 0x01;
|
||||
irq_counter = irq_latch;
|
||||
break;
|
||||
case 0x0b:
|
||||
irq_latch = (irq_latch & 0xff00) | (data << 0);
|
||||
break;
|
||||
case 0x0c:
|
||||
irq_latch = (irq_latch & 0x00ff) | (data << 8);
|
||||
break;
|
||||
case 0x0d:
|
||||
//TODO: serial EEPROM support
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(ciram_addr(addr));
|
||||
addr = (chr_bank[addr >> 10] << 10) | (addr & 0x03ff);
|
||||
return Board::chr_read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(ciram_addr(addr), data);
|
||||
addr = (chr_bank[addr >> 10] << 10) | (addr & 0x03ff);
|
||||
return Board::chr_write(addr, data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
for(auto &n : chr_bank) n = 0;
|
||||
prg_bank = 0;
|
||||
mirror = 0;
|
||||
irq_counter_enable = 0;
|
||||
irq_counter = 0;
|
||||
irq_latch = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
|
||||
s.array(chr_bank);
|
||||
s.integer(prg_bank);
|
||||
s.integer(mirror);
|
||||
s.integer(irq_counter_enable);
|
||||
s.integer(irq_counter);
|
||||
s.integer(irq_latch);
|
||||
}
|
||||
|
||||
BandaiFCG(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,167 +0,0 @@
|
||||
#include "bandai-fcg.cpp"
|
||||
#include "konami-vrc1.cpp"
|
||||
#include "konami-vrc2.cpp"
|
||||
#include "konami-vrc3.cpp"
|
||||
#include "konami-vrc4.cpp"
|
||||
#include "konami-vrc6.cpp"
|
||||
#include "konami-vrc7.cpp"
|
||||
#include "nes-axrom.cpp"
|
||||
#include "nes-bnrom.cpp"
|
||||
#include "nes-cnrom.cpp"
|
||||
#include "nes-exrom.cpp"
|
||||
#include "nes-fxrom.cpp"
|
||||
#include "nes-gxrom.cpp"
|
||||
#include "nes-hkrom.cpp"
|
||||
#include "nes-nrom.cpp"
|
||||
#include "nes-pxrom.cpp"
|
||||
#include "nes-sxrom.cpp"
|
||||
#include "nes-txrom.cpp"
|
||||
#include "nes-uxrom.cpp"
|
||||
#include "sunsoft-5b.cpp"
|
||||
|
||||
uint8 Board::Memory::read(unsigned addr) const {
|
||||
return data[mirror(addr, size)];
|
||||
}
|
||||
|
||||
void Board::Memory::write(unsigned addr, uint8 byte) {
|
||||
if(writable) data[mirror(addr, size)] = byte;
|
||||
}
|
||||
|
||||
unsigned Board::mirror(unsigned addr, unsigned size) {
|
||||
unsigned base = 0;
|
||||
if(size) {
|
||||
unsigned mask = 1 << 23;
|
||||
while(addr >= size) {
|
||||
while(!(addr & mask)) mask >>= 1;
|
||||
addr -= mask;
|
||||
if(size > mask) {
|
||||
size -= mask;
|
||||
base += mask;
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
base += addr;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
void Board::main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
cartridge.clock += 12 * 4095;
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
void Board::tick() {
|
||||
cartridge.clock += 12;
|
||||
if(cartridge.clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
|
||||
}
|
||||
|
||||
uint8 Board::chr_read(unsigned addr) {
|
||||
if(chrram.size) return chrram.data[mirror(addr, chrram.size)];
|
||||
if(chrrom.size) return chrrom.data[mirror(addr, chrrom.size)];
|
||||
return 0u;
|
||||
}
|
||||
|
||||
void Board::chr_write(unsigned addr, uint8 data) {
|
||||
if(chrram.size) chrram.data[mirror(addr, chrram.size)] = data;
|
||||
}
|
||||
|
||||
Board::Memory& Board::memory() {
|
||||
return prgram;
|
||||
}
|
||||
|
||||
void Board::power() {
|
||||
}
|
||||
|
||||
void Board::reset() {
|
||||
}
|
||||
|
||||
void Board::serialize(serializer &s) {
|
||||
if(prgram.size) s.array(prgram.data, prgram.size);
|
||||
if(chrram.size) s.array(chrram.data, chrram.size);
|
||||
}
|
||||
|
||||
Board::Board(XML::Document &document, const stream &memory) {
|
||||
auto &cartridge = document["cartridge"];
|
||||
|
||||
information.type = cartridge["board"]["type"].data;
|
||||
information.battery = cartridge["prg"]["ram"]["nonvolatile"].data == "true";
|
||||
|
||||
prgrom.size = numeral(cartridge["prg"]["rom"]["size"].data);
|
||||
prgram.size = numeral(cartridge["prg"]["ram"]["size"].data);
|
||||
chrrom.size = numeral(cartridge["chr"]["rom"]["size"].data);
|
||||
chrram.size = numeral(cartridge["chr"]["ram"]["size"].data);
|
||||
|
||||
if(prgrom.size) prgrom.data = new uint8[prgrom.size]();
|
||||
if(prgram.size) prgram.data = new uint8[prgram.size]();
|
||||
if(chrrom.size) chrrom.data = new uint8[chrrom.size]();
|
||||
if(chrram.size) chrram.data = new uint8[chrram.size]();
|
||||
|
||||
if(prgrom.size) memory.read(prgrom.data, prgrom.size);
|
||||
if(chrrom.size) memory.read(chrrom.data, chrrom.size);
|
||||
|
||||
prgram.writable = true;
|
||||
chrram.writable = true;
|
||||
}
|
||||
|
||||
Board::~Board() {
|
||||
}
|
||||
|
||||
Board* Board::load(const string &markup, const stream &memory) {
|
||||
XML::Document document(markup);
|
||||
string type = document["cartridge"]["board"]["type"].data;
|
||||
|
||||
if(type == "BANDAI-FCG") return new BandaiFCG(document, memory);
|
||||
|
||||
if(type == "KONAMI-VRC-1") return new KonamiVRC1(document, memory);
|
||||
if(type == "KONAMI-VRC-2") return new KonamiVRC2(document, memory);
|
||||
if(type == "KONAMI-VRC-3") return new KonamiVRC3(document, memory);
|
||||
if(type == "KONAMI-VRC-4") return new KonamiVRC4(document, memory);
|
||||
if(type == "KONAMI-VRC-6") return new KonamiVRC6(document, memory);
|
||||
if(type == "KONAMI-VRC-7") return new KonamiVRC7(document, memory);
|
||||
|
||||
if(type == "NES-AMROM" ) return new NES_AxROM(document, memory);
|
||||
if(type == "NES-ANROM" ) return new NES_AxROM(document, memory);
|
||||
if(type == "NES-AN1ROM" ) return new NES_AxROM(document, memory);
|
||||
if(type == "NES-AOROM" ) return new NES_AxROM(document, memory);
|
||||
|
||||
if(type == "NES-BNROM" ) return new NES_BNROM(document, memory);
|
||||
|
||||
if(type == "NES-CNROM" ) return new NES_CNROM(document, memory);
|
||||
|
||||
if(type == "NES-EKROM" ) return new NES_ExROM(document, memory);
|
||||
if(type == "NES-ELROM" ) return new NES_ExROM(document, memory);
|
||||
if(type == "NES-ETROM" ) return new NES_ExROM(document, memory);
|
||||
if(type == "NES-EWROM" ) return new NES_ExROM(document, memory);
|
||||
|
||||
if(type == "NES-FJROM" ) return new NES_FxROM(document, memory);
|
||||
if(type == "NES-FKROM" ) return new NES_FxROM(document, memory);
|
||||
|
||||
if(type == "NES-GNROM" ) return new NES_GxROM(document, memory);
|
||||
if(type == "NES-MHROM" ) return new NES_GxROM(document, memory);
|
||||
|
||||
if(type == "NES-HKROM" ) return new NES_HKROM(document, memory);
|
||||
|
||||
if(type == "NES-NROM-128") return new NES_NROM(document, memory);
|
||||
if(type == "NES-NROM-256") return new NES_NROM(document, memory);
|
||||
|
||||
if(type == "NES-PEEOROM" ) return new NES_PxROM(document, memory);
|
||||
if(type == "NES-PNROM" ) return new NES_PxROM(document, memory);
|
||||
|
||||
if(type == "NES-SNROM" ) return new NES_SxROM(document, memory);
|
||||
if(type == "NES-SXROM" ) return new NES_SxROM(document, memory);
|
||||
|
||||
if(type == "NES-TLROM" ) return new NES_TxROM(document, memory);
|
||||
|
||||
if(type == "NES-UNROM" ) return new NES_UxROM(document, memory);
|
||||
if(type == "NES-UOROM" ) return new NES_UxROM(document, memory);
|
||||
|
||||
if(type == "SUNSOFT-5B" ) return new Sunsoft5B(document, memory);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
struct Board {
|
||||
struct Memory {
|
||||
uint8_t *data;
|
||||
unsigned size;
|
||||
bool writable;
|
||||
|
||||
inline uint8 read(unsigned addr) const;
|
||||
inline void write(unsigned addr, uint8 data);
|
||||
|
||||
inline Memory(uint8_t *data, unsigned size) : data(data), size(size) {}
|
||||
inline Memory() : data(nullptr), size(0u), writable(false) {}
|
||||
inline ~Memory() { if(data) delete[] data; }
|
||||
};
|
||||
|
||||
static unsigned mirror(unsigned addr, unsigned size);
|
||||
|
||||
virtual void main();
|
||||
virtual void tick();
|
||||
|
||||
virtual uint8 prg_read(unsigned addr) = 0;
|
||||
virtual void prg_write(unsigned addr, uint8 data) = 0;
|
||||
|
||||
virtual uint8 chr_read(unsigned addr);
|
||||
virtual void chr_write(unsigned addr, uint8 data);
|
||||
|
||||
virtual inline void scanline(unsigned y) {}
|
||||
|
||||
virtual Memory& memory();
|
||||
|
||||
virtual void power();
|
||||
virtual void reset();
|
||||
|
||||
virtual void serialize(serializer&);
|
||||
Board(XML::Document &document, const stream &memory);
|
||||
virtual ~Board();
|
||||
|
||||
static Board* load(const string &markup, const stream &memory);
|
||||
|
||||
struct Information {
|
||||
string type;
|
||||
bool battery;
|
||||
} information;
|
||||
|
||||
Memory prgrom;
|
||||
Memory prgram;
|
||||
Memory chrrom;
|
||||
Memory chrram;
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
struct KonamiVRC1 : Board {
|
||||
|
||||
VRC1 vrc1;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr & 0x8000) return prgrom.read(vrc1.prg_addr(addr));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x8000) return vrc1.reg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(vrc1.ciram_addr(addr));
|
||||
return Board::chr_read(vrc1.chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(vrc1.ciram_addr(addr), data);
|
||||
return Board::chr_write(vrc1.chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
vrc1.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
vrc1.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
vrc1.serialize(s);
|
||||
}
|
||||
|
||||
KonamiVRC1(XML::Document &document, const stream &memory) : Board(document, memory), vrc1(*this) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
struct KonamiVRC2 : Board {
|
||||
|
||||
struct Settings {
|
||||
struct Pinout {
|
||||
unsigned a0;
|
||||
unsigned a1;
|
||||
} pinout;
|
||||
} settings;
|
||||
|
||||
VRC2 vrc2;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr < 0x6000) return cpu.mdr();
|
||||
if(addr < 0x8000) return vrc2.ram_read(addr);
|
||||
return prgrom.read(vrc2.prg_addr(addr));
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr < 0x6000) return;
|
||||
if(addr < 0x8000) return vrc2.ram_write(addr, data);
|
||||
|
||||
bool a0 = (addr & settings.pinout.a0);
|
||||
bool a1 = (addr & settings.pinout.a1);
|
||||
addr &= 0xfff0;
|
||||
addr |= (a0 << 0) | (a1 << 1);
|
||||
return vrc2.reg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(vrc2.ciram_addr(addr));
|
||||
return Board::chr_read(vrc2.chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(vrc2.ciram_addr(addr), data);
|
||||
return Board::chr_write(vrc2.chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
vrc2.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
vrc2.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
vrc2.serialize(s);
|
||||
}
|
||||
|
||||
KonamiVRC2(XML::Document &document, const stream &memory) : Board(document, memory), vrc2(*this) {
|
||||
settings.pinout.a0 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a0"].data);
|
||||
settings.pinout.a1 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a1"].data);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
struct KonamiVRC3 : Board {
|
||||
|
||||
struct Settings {
|
||||
bool mirror; //0 = horizontal, 1 = vertical
|
||||
} settings;
|
||||
|
||||
VRC3 vrc3;
|
||||
|
||||
void main() {
|
||||
vrc3.main();
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if((addr & 0xe000) == 0x6000) return prgram.read(addr & 0x1fff);
|
||||
if(addr & 0x8000) return prgrom.read(vrc3.prg_addr(addr));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0xe000) == 0x6000) return prgram.write(addr & 0x1fff, data);
|
||||
if(addr & 0x8000) return vrc3.reg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_read(addr & 0x07ff);
|
||||
}
|
||||
return chrram.read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_write(addr & 0x07ff, data);
|
||||
}
|
||||
return chrram.write(addr, data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
vrc3.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
vrc3.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
vrc3.serialize(s);
|
||||
}
|
||||
|
||||
KonamiVRC3(XML::Document &document, const stream &memory) : Board(document, memory), vrc3(*this) {
|
||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,61 +0,0 @@
|
||||
struct KonamiVRC4 : Board {
|
||||
|
||||
struct Settings {
|
||||
struct Pinout {
|
||||
unsigned a0;
|
||||
unsigned a1;
|
||||
} pinout;
|
||||
} settings;
|
||||
|
||||
VRC4 vrc4;
|
||||
|
||||
void main() {
|
||||
return vrc4.main();
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr < 0x6000) return cpu.mdr();
|
||||
if(addr < 0x8000) return prgram.read(addr);
|
||||
return prgrom.read(vrc4.prg_addr(addr));
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr < 0x6000) return;
|
||||
if(addr < 0x8000) return prgram.write(addr, data);
|
||||
|
||||
bool a0 = (addr & settings.pinout.a0);
|
||||
bool a1 = (addr & settings.pinout.a1);
|
||||
addr &= 0xfff0;
|
||||
addr |= (a1 << 1) | (a0 << 0);
|
||||
return vrc4.reg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(vrc4.ciram_addr(addr));
|
||||
return Board::chr_read(vrc4.chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(vrc4.ciram_addr(addr), data);
|
||||
return Board::chr_write(vrc4.chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
vrc4.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
vrc4.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
vrc4.serialize(s);
|
||||
}
|
||||
|
||||
KonamiVRC4(XML::Document &document, const stream &memory) : Board(document, memory), vrc4(*this) {
|
||||
settings.pinout.a0 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a0"].data);
|
||||
settings.pinout.a1 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a1"].data);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
struct KonamiVRC6 : Board {
|
||||
|
||||
VRC6 vrc6;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if((addr & 0xe000) == 0x6000) return vrc6.ram_read(addr);
|
||||
if(addr & 0x8000) return prgrom.read(vrc6.prg_addr(addr));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0xe000) == 0x6000) return vrc6.ram_write(addr, data);
|
||||
if(addr & 0x8000) {
|
||||
addr = (addr & 0xf003);
|
||||
if(prgram.size) addr = (addr & ~3) | ((addr & 2) >> 1) | ((addr & 1) << 1);
|
||||
return vrc6.reg_write(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(vrc6.ciram_addr(addr));
|
||||
return Board::chr_read(vrc6.chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(vrc6.ciram_addr(addr), data);
|
||||
return Board::chr_write(vrc6.chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
vrc6.serialize(s);
|
||||
}
|
||||
|
||||
void main() { vrc6.main(); }
|
||||
void power() { vrc6.power(); }
|
||||
void reset() { vrc6.reset(); }
|
||||
|
||||
KonamiVRC6(XML::Document &document, const stream &memory) : Board(document, memory), vrc6(*this) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,47 +0,0 @@
|
||||
struct KonamiVRC7 : Board {
|
||||
|
||||
VRC7 vrc7;
|
||||
|
||||
void main() {
|
||||
return vrc7.main();
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr < 0x6000) return cpu.mdr();
|
||||
if(addr < 0x8000) return prgram.read(addr);
|
||||
return prgrom.read(vrc7.prg_addr(addr));
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr < 0x6000) return;
|
||||
if(addr < 0x8000) return prgram.write(addr, data);
|
||||
return vrc7.reg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(vrc7.ciram_addr(addr));
|
||||
return chrram.read(vrc7.chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(vrc7.ciram_addr(addr), data);
|
||||
return chrram.write(vrc7.chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
vrc7.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
vrc7.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
vrc7.serialize(s);
|
||||
}
|
||||
|
||||
KonamiVRC7(XML::Document &document, const stream &memory) : Board(document, memory), vrc7(*this) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,51 +0,0 @@
|
||||
//NES-AMROM
|
||||
//NES-ANROM
|
||||
//NES-AN1ROM
|
||||
//NES-AOROM
|
||||
|
||||
struct NES_AxROM : Board {
|
||||
|
||||
uint4 prg_bank;
|
||||
bool mirror_select;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr & 0x8000) return prgrom.read((prg_bank << 15) | (addr & 0x7fff));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x8000) {
|
||||
prg_bank = data & 0x0f;
|
||||
mirror_select = data & 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read((mirror_select << 10) | (addr & 0x03ff));
|
||||
return Board::chr_read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write((mirror_select << 10) | (addr & 0x03ff), data);
|
||||
return Board::chr_write(addr, data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
prg_bank = 0x0f;
|
||||
mirror_select = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
|
||||
s.integer(prg_bank);
|
||||
s.integer(mirror_select);
|
||||
}
|
||||
|
||||
NES_AxROM(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
//NES-BN-ROM-01
|
||||
|
||||
struct NES_BNROM : Board {
|
||||
|
||||
struct Settings {
|
||||
bool mirror; //0 = horizontal, 1 = vertical
|
||||
} settings;
|
||||
|
||||
uint2 prg_bank;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr & 0x8000) return prgrom.read((prg_bank << 15) | (addr & 0x7fff));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x8000) prg_bank = data & 0x03;
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_read(addr);
|
||||
}
|
||||
return Board::chr_read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_write(addr, data);
|
||||
}
|
||||
return Board::chr_write(addr, data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
prg_bank = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
s.integer(prg_bank);
|
||||
}
|
||||
|
||||
NES_BNROM(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
//NES-CNROM
|
||||
|
||||
struct NES_CNROM : Board {
|
||||
|
||||
struct Settings {
|
||||
bool mirror; //0 = horizontal, 1 = vertical
|
||||
} settings;
|
||||
|
||||
uint2 chr_bank;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr & 0x8000) return prgrom.read(addr & 0x7fff);
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x8000) chr_bank = data & 0x03;
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_read(addr & 0x07ff);
|
||||
}
|
||||
addr = (chr_bank * 0x2000) + (addr & 0x1fff);
|
||||
return Board::chr_read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_write(addr & 0x07ff, data);
|
||||
}
|
||||
addr = (chr_bank * 0x2000) + (addr & 0x1fff);
|
||||
Board::chr_write(addr, data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
chr_bank = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
s.integer(chr_bank);
|
||||
}
|
||||
|
||||
NES_CNROM(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
struct NES_ExROM : Board {
|
||||
|
||||
enum class Revision : unsigned {
|
||||
EKROM,
|
||||
ELROM,
|
||||
ETROM,
|
||||
EWROM,
|
||||
} revision;
|
||||
|
||||
MMC5 mmc5;
|
||||
|
||||
void main() {
|
||||
mmc5.main();
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
return mmc5.prg_read(addr);
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
mmc5.prg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
return mmc5.chr_read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
mmc5.chr_write(addr, data);
|
||||
}
|
||||
|
||||
void scanline(unsigned y) {
|
||||
mmc5.scanline(y);
|
||||
}
|
||||
|
||||
void power() {
|
||||
mmc5.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mmc5.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
mmc5.serialize(s);
|
||||
}
|
||||
|
||||
NES_ExROM(XML::Document &document, const stream &memory) : Board(document, memory), mmc5(*this) {
|
||||
revision = Revision::ELROM;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,91 +0,0 @@
|
||||
//MMC4
|
||||
|
||||
struct NES_FxROM : Board {
|
||||
|
||||
enum Revision : unsigned {
|
||||
FJROM,
|
||||
FKROM,
|
||||
} revision;
|
||||
|
||||
uint4 prg_bank;
|
||||
uint5 chr_bank[2][2];
|
||||
bool mirror;
|
||||
bool latch[2];
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr < 0x6000) return cpu.mdr();
|
||||
if(addr < 0x8000) return prgram.read(addr);
|
||||
unsigned bank = addr < 0xc000 ? prg_bank : (uint4)0x0f;
|
||||
return prgrom.read((bank * 0x4000) | (addr & 0x3fff));
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr < 0x6000) return;
|
||||
if(addr < 0x8000) return prgram.write(addr, data);
|
||||
|
||||
switch(addr & 0xf000) {
|
||||
case 0xa000: prg_bank = data & 0x0f; break;
|
||||
case 0xb000: chr_bank[0][0] = data & 0x1f; break;
|
||||
case 0xc000: chr_bank[0][1] = data & 0x1f; break;
|
||||
case 0xd000: chr_bank[1][0] = data & 0x1f; break;
|
||||
case 0xe000: chr_bank[1][1] = data & 0x1f; break;
|
||||
case 0xf000: mirror = data & 0x01; break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) const {
|
||||
switch(mirror) {
|
||||
case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical mirroring
|
||||
case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal mirroring
|
||||
}
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(ciram_addr(addr));
|
||||
bool region = addr & 0x1000;
|
||||
unsigned bank = chr_bank[region][latch[region]];
|
||||
if((addr & 0x0ff8) == 0x0fd8) latch[region] = 0;
|
||||
if((addr & 0x0ff8) == 0x0fe8) latch[region] = 1;
|
||||
return Board::chr_read((bank * 0x1000) | (addr & 0x0fff));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(ciram_addr(addr), data);
|
||||
bool region = addr & 0x1000;
|
||||
unsigned bank = chr_bank[region][latch[region]];
|
||||
if((addr & 0x0ff8) == 0x0fd8) latch[region] = 0;
|
||||
if((addr & 0x0ff8) == 0x0fe8) latch[region] = 1;
|
||||
return Board::chr_write((bank * 0x1000) | (addr & 0x0fff), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
prg_bank = 0;
|
||||
chr_bank[0][0] = 0;
|
||||
chr_bank[0][1] = 0;
|
||||
chr_bank[1][0] = 0;
|
||||
chr_bank[1][1] = 0;
|
||||
mirror = 0;
|
||||
latch[0] = 0;
|
||||
latch[1] = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
|
||||
s.integer(prg_bank);
|
||||
s.integer(chr_bank[0][0]);
|
||||
s.integer(chr_bank[0][1]);
|
||||
s.integer(chr_bank[1][0]);
|
||||
s.integer(chr_bank[1][1]);
|
||||
s.integer(mirror);
|
||||
s.array(latch);
|
||||
}
|
||||
|
||||
NES_FxROM(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
revision = Revision::FKROM;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,61 +0,0 @@
|
||||
//NES-GNROM
|
||||
//NES-MHROM
|
||||
|
||||
struct NES_GxROM : Board {
|
||||
|
||||
struct Settings {
|
||||
bool mirror; //0 = horizontal, 1 = vertical
|
||||
} settings;
|
||||
|
||||
uint2 prg_bank;
|
||||
uint2 chr_bank;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr & 0x8000) return prgrom.read((prg_bank << 15) | (addr & 0x7fff));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x8000) {
|
||||
prg_bank = (data & 0x30) >> 4;
|
||||
chr_bank = (data & 0x03) >> 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_read(addr & 0x07ff);
|
||||
}
|
||||
addr = (chr_bank * 0x2000) + (addr & 0x1fff);
|
||||
return Board::chr_read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_write(addr & 0x07ff, data);
|
||||
}
|
||||
addr = (chr_bank * 0x2000) + (addr & 0x1fff);
|
||||
Board::chr_write(addr, data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
prg_bank = 0;
|
||||
chr_bank = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
s.integer(prg_bank);
|
||||
s.integer(chr_bank);
|
||||
}
|
||||
|
||||
NES_GxROM(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,48 +0,0 @@
|
||||
struct NES_HKROM : Board {
|
||||
|
||||
MMC6 mmc6;
|
||||
|
||||
void main() {
|
||||
mmc6.main();
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if((addr & 0xf000) == 0x7000) return mmc6.ram_read(addr);
|
||||
if(addr & 0x8000) return prgrom.read(mmc6.prg_addr(addr));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0xf000) == 0x7000) return mmc6.ram_write(addr, data);
|
||||
if(addr & 0x8000) return mmc6.reg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
mmc6.irq_test(addr);
|
||||
if(addr & 0x2000) return ppu.ciram_read(mmc6.ciram_addr(addr));
|
||||
return Board::chr_read(mmc6.chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
mmc6.irq_test(addr);
|
||||
if(addr & 0x2000) return ppu.ciram_write(mmc6.ciram_addr(addr), data);
|
||||
return Board::chr_write(mmc6.chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
mmc6.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mmc6.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
mmc6.serialize(s);
|
||||
}
|
||||
|
||||
NES_HKROM(XML::Document &document, const stream &memory) : Board(document, memory), mmc6(*this) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
//NES-NROM-128
|
||||
//NES-NROM-256
|
||||
|
||||
struct NES_NROM : Board {
|
||||
|
||||
struct Settings {
|
||||
bool mirror; //0 = horizontal, 1 = vertical
|
||||
} settings;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr & 0x8000) return prgrom.read(addr);
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_read(addr & 0x07ff);
|
||||
}
|
||||
if(chrram.size) return chrram.read(addr);
|
||||
return chrrom.read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_write(addr & 0x07ff, data);
|
||||
}
|
||||
if(chrram.size) return chrram.write(addr, data);
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
}
|
||||
|
||||
NES_NROM(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,97 +0,0 @@
|
||||
//MMC2
|
||||
|
||||
struct NES_PxROM : Board {
|
||||
|
||||
enum Revision : unsigned {
|
||||
PEEOROM,
|
||||
PNROM,
|
||||
} revision;
|
||||
|
||||
uint4 prg_bank;
|
||||
uint5 chr_bank[2][2];
|
||||
bool mirror;
|
||||
bool latch[2];
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr < 0x6000) return cpu.mdr();
|
||||
if(addr < 0x8000) return prgram.read(addr);
|
||||
unsigned bank = 0;
|
||||
switch((addr / 0x2000) & 3) {
|
||||
case 0: bank = prg_bank; break;
|
||||
case 1: bank = 0x0d; break;
|
||||
case 2: bank = 0x0e; break;
|
||||
case 3: bank = 0x0f; break;
|
||||
}
|
||||
return prgrom.read((bank * 0x2000) | (addr & 0x1fff));
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr < 0x6000) return;
|
||||
if(addr < 0x8000) return prgram.write(addr, data);
|
||||
|
||||
switch(addr & 0xf000) {
|
||||
case 0xa000: prg_bank = data & 0x0f; break;
|
||||
case 0xb000: chr_bank[0][0] = data & 0x1f; break;
|
||||
case 0xc000: chr_bank[0][1] = data & 0x1f; break;
|
||||
case 0xd000: chr_bank[1][0] = data & 0x1f; break;
|
||||
case 0xe000: chr_bank[1][1] = data & 0x1f; break;
|
||||
case 0xf000: mirror = data & 0x01; break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) const {
|
||||
switch(mirror) {
|
||||
case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical mirroring
|
||||
case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal mirroring
|
||||
}
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(ciram_addr(addr));
|
||||
bool region = addr & 0x1000;
|
||||
unsigned bank = chr_bank[region][latch[region]];
|
||||
if((addr & 0x0ff8) == 0x0fd8) latch[region] = 0;
|
||||
if((addr & 0x0ff8) == 0x0fe8) latch[region] = 1;
|
||||
return Board::chr_read((bank * 0x1000) | (addr & 0x0fff));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(ciram_addr(addr), data);
|
||||
bool region = addr & 0x1000;
|
||||
unsigned bank = chr_bank[region][latch[region]];
|
||||
if((addr & 0x0ff8) == 0x0fd8) latch[region] = 0;
|
||||
if((addr & 0x0ff8) == 0x0fe8) latch[region] = 1;
|
||||
return Board::chr_write((bank * 0x1000) | (addr & 0x0fff), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
prg_bank = 0;
|
||||
chr_bank[0][0] = 0;
|
||||
chr_bank[0][1] = 0;
|
||||
chr_bank[1][0] = 0;
|
||||
chr_bank[1][1] = 0;
|
||||
mirror = 0;
|
||||
latch[0] = 0;
|
||||
latch[1] = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
|
||||
s.integer(prg_bank);
|
||||
s.integer(chr_bank[0][0]);
|
||||
s.integer(chr_bank[0][1]);
|
||||
s.integer(chr_bank[1][0]);
|
||||
s.integer(chr_bank[1][1]);
|
||||
s.integer(mirror);
|
||||
s.array(latch);
|
||||
}
|
||||
|
||||
NES_PxROM(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
revision = Revision::PNROM;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,101 +0,0 @@
|
||||
struct NES_SxROM : Board {
|
||||
|
||||
enum class Revision : unsigned {
|
||||
SAROM,
|
||||
SBROM,
|
||||
SCROM,
|
||||
SC1ROM,
|
||||
SEROM,
|
||||
SFROM,
|
||||
SGROM,
|
||||
SHROM,
|
||||
SH1ROM,
|
||||
SIROM,
|
||||
SJROM,
|
||||
SKROM,
|
||||
SLROM,
|
||||
SL1ROM,
|
||||
SL2ROM,
|
||||
SL3ROM,
|
||||
SLRROM,
|
||||
SMROM,
|
||||
SNROM,
|
||||
SOROM,
|
||||
SUROM,
|
||||
SXROM,
|
||||
} revision;
|
||||
|
||||
MMC1 mmc1;
|
||||
|
||||
void main() {
|
||||
return mmc1.main();
|
||||
}
|
||||
|
||||
unsigned ram_addr(unsigned addr) {
|
||||
unsigned bank = 0;
|
||||
if(revision == Revision::SOROM) bank = (mmc1.chr_bank[0] & 0x08) >> 3;
|
||||
if(revision == Revision::SUROM) bank = (mmc1.chr_bank[0] & 0x0c) >> 2;
|
||||
if(revision == Revision::SXROM) bank = (mmc1.chr_bank[0] & 0x0c) >> 2;
|
||||
return (bank << 13) | (addr & 0x1fff);
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if((addr & 0xe000) == 0x6000) {
|
||||
if(revision == Revision::SNROM) {
|
||||
if(mmc1.chr_bank[0] & 0x10) return cpu.mdr();
|
||||
}
|
||||
if(mmc1.ram_disable) return 0x00;
|
||||
return prgram.read(ram_addr(addr));
|
||||
}
|
||||
|
||||
if(addr & 0x8000) {
|
||||
addr = mmc1.prg_addr(addr);
|
||||
if(revision == Revision::SXROM) {
|
||||
addr |= ((mmc1.chr_bank[0] & 0x10) >> 4) << 18;
|
||||
}
|
||||
return prgrom.read(addr);
|
||||
}
|
||||
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0xe000) == 0x6000) {
|
||||
if(revision == Revision::SNROM) {
|
||||
if(mmc1.chr_bank[0] & 0x10) return;
|
||||
}
|
||||
if(mmc1.ram_disable) return;
|
||||
return prgram.write(ram_addr(addr), data);
|
||||
}
|
||||
|
||||
if(addr & 0x8000) return mmc1.mmio_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(mmc1.ciram_addr(addr));
|
||||
return Board::chr_read(mmc1.chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(mmc1.ciram_addr(addr), data);
|
||||
return Board::chr_write(mmc1.chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
mmc1.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mmc1.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
mmc1.serialize(s);
|
||||
}
|
||||
|
||||
NES_SxROM(XML::Document &document, const stream &memory) : Board(document, memory), mmc1(*this) {
|
||||
revision = Revision::SXROM;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
struct NES_TxROM : Board {
|
||||
|
||||
enum class Revision : unsigned {
|
||||
TBROM,
|
||||
TEROM,
|
||||
TFROM,
|
||||
TGROM,
|
||||
TKROM,
|
||||
TKSROM,
|
||||
TLROM,
|
||||
TL1ROM,
|
||||
TL2ROM,
|
||||
TLSROM,
|
||||
TNROM,
|
||||
TQROM,
|
||||
TR1ROM,
|
||||
TSROM,
|
||||
TVROM,
|
||||
} revision;
|
||||
|
||||
MMC3 mmc3;
|
||||
|
||||
void main() {
|
||||
mmc3.main();
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if((addr & 0xe000) == 0x6000) return mmc3.ram_read(addr);
|
||||
if(addr & 0x8000) return prgrom.read(mmc3.prg_addr(addr));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0xe000) == 0x6000) return mmc3.ram_write(addr, data);
|
||||
if(addr & 0x8000) return mmc3.reg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
mmc3.irq_test(addr);
|
||||
if(addr & 0x2000) return ppu.ciram_read(mmc3.ciram_addr(addr));
|
||||
return Board::chr_read(mmc3.chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
mmc3.irq_test(addr);
|
||||
if(addr & 0x2000) return ppu.ciram_write(mmc3.ciram_addr(addr), data);
|
||||
return Board::chr_write(mmc3.chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
mmc3.power();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mmc3.reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
mmc3.serialize(s);
|
||||
}
|
||||
|
||||
NES_TxROM(XML::Document &document, const stream &memory) : Board(document, memory), mmc3(*this) {
|
||||
revision = Revision::TLROM;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
//NES-UNROM
|
||||
//NES-UOROM
|
||||
|
||||
struct NES_UxROM : Board {
|
||||
|
||||
struct Settings {
|
||||
bool mirror; //0 = horizontal, 1 = vertical
|
||||
} settings;
|
||||
|
||||
uint4 prg_bank;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if((addr & 0xc000) == 0x8000) return prgrom.read((prg_bank << 14) | (addr & 0x3fff));
|
||||
if((addr & 0xc000) == 0xc000) return prgrom.read(( 0x0f << 14) | (addr & 0x3fff));
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x8000) prg_bank = data & 0x0f;
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_read(addr);
|
||||
}
|
||||
return Board::chr_read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_write(addr, data);
|
||||
}
|
||||
return Board::chr_write(addr, data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
prg_bank = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
|
||||
s.integer(prg_bank);
|
||||
}
|
||||
|
||||
NES_UxROM(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,226 +0,0 @@
|
||||
//SUNSOFT-5B
|
||||
|
||||
struct Sunsoft5B : Board {
|
||||
|
||||
uint4 mmu_port;
|
||||
uint4 apu_port;
|
||||
|
||||
uint8 prg_bank[4];
|
||||
uint8 chr_bank[8];
|
||||
uint2 mirror;
|
||||
bool irq_enable;
|
||||
bool irq_counter_enable;
|
||||
uint16 irq_counter;
|
||||
|
||||
int16 dac[16];
|
||||
|
||||
struct Pulse {
|
||||
bool disable;
|
||||
uint12 frequency;
|
||||
uint4 volume;
|
||||
|
||||
uint16 counter; //12-bit countdown + 4-bit phase
|
||||
uint1 duty;
|
||||
uint4 output;
|
||||
|
||||
void clock() {
|
||||
if(--counter == 0) {
|
||||
counter = frequency << 4;
|
||||
duty ^= 1;
|
||||
}
|
||||
output = duty ? volume : (uint4)0;
|
||||
if(disable) output = 0;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
disable = 1;
|
||||
frequency = 1;
|
||||
volume = 0;
|
||||
|
||||
counter = 0;
|
||||
duty = 0;
|
||||
output = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
s.integer(disable);
|
||||
s.integer(frequency);
|
||||
s.integer(volume);
|
||||
|
||||
s.integer(counter);
|
||||
s.integer(duty);
|
||||
s.integer(output);
|
||||
}
|
||||
} pulse[3];
|
||||
|
||||
void main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(irq_counter_enable) {
|
||||
if(--irq_counter == 0xffff) {
|
||||
cpu.set_irq_line(irq_enable);
|
||||
}
|
||||
}
|
||||
|
||||
pulse[0].clock();
|
||||
pulse[1].clock();
|
||||
pulse[2].clock();
|
||||
int16 output = dac[pulse[0].output] + dac[pulse[1].output] + dac[pulse[2].output];
|
||||
apu.set_sample(-output);
|
||||
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr < 0x6000) return cpu.mdr();
|
||||
|
||||
uint8 bank = 0x3f; //((addr & 0xe000) == 0xe000
|
||||
if((addr & 0xe000) == 0x6000) bank = prg_bank[0];
|
||||
if((addr & 0xe000) == 0x8000) bank = prg_bank[1];
|
||||
if((addr & 0xe000) == 0xa000) bank = prg_bank[2];
|
||||
if((addr & 0xe000) == 0xc000) bank = prg_bank[3];
|
||||
|
||||
bool ram_enable = bank & 0x80;
|
||||
bool ram_select = bank & 0x40;
|
||||
bank &= 0x3f;
|
||||
|
||||
if(ram_select) {
|
||||
if(ram_enable == false) return cpu.mdr();
|
||||
return prgram.data[addr & 0x1fff];
|
||||
}
|
||||
|
||||
addr = (bank << 13) | (addr & 0x1fff);
|
||||
return prgrom.read(addr);
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0xe000) == 0x6000) {
|
||||
prgram.data[addr & 0x1fff] = data;
|
||||
}
|
||||
|
||||
if(addr == 0x8000) {
|
||||
mmu_port = data & 0x0f;
|
||||
}
|
||||
|
||||
if(addr == 0xa000) {
|
||||
switch(mmu_port) {
|
||||
case 0: chr_bank[0] = data; break;
|
||||
case 1: chr_bank[1] = data; break;
|
||||
case 2: chr_bank[2] = data; break;
|
||||
case 3: chr_bank[3] = data; break;
|
||||
case 4: chr_bank[4] = data; break;
|
||||
case 5: chr_bank[5] = data; break;
|
||||
case 6: chr_bank[6] = data; break;
|
||||
case 7: chr_bank[7] = data; break;
|
||||
case 8: prg_bank[0] = data; break;
|
||||
case 9: prg_bank[1] = data; break;
|
||||
case 10: prg_bank[2] = data; break;
|
||||
case 11: prg_bank[3] = data; break;
|
||||
case 12: mirror = data & 3; break;
|
||||
case 13:
|
||||
irq_enable = data & 0x80;
|
||||
irq_counter_enable = data & 0x01;
|
||||
if(irq_enable == 0) cpu.set_irq_line(0);
|
||||
break;
|
||||
case 14: irq_counter = (irq_counter & 0xff00) | (data << 0); break;
|
||||
case 15: irq_counter = (irq_counter & 0x00ff) | (data << 8); break;
|
||||
}
|
||||
}
|
||||
|
||||
if(addr == 0xc000) {
|
||||
apu_port = data & 0x0f;
|
||||
}
|
||||
|
||||
if(addr == 0xe000) {
|
||||
switch(apu_port) {
|
||||
case 0: pulse[0].frequency = (pulse[0].frequency & 0xff00) | (data << 0); break;
|
||||
case 1: pulse[0].frequency = (pulse[0].frequency & 0x00ff) | (data << 8); break;
|
||||
case 2: pulse[1].frequency = (pulse[1].frequency & 0xff00) | (data << 0); break;
|
||||
case 3: pulse[1].frequency = (pulse[1].frequency & 0x00ff) | (data << 8); break;
|
||||
case 4: pulse[2].frequency = (pulse[2].frequency & 0xff00) | (data << 0); break;
|
||||
case 5: pulse[2].frequency = (pulse[2].frequency & 0x00ff) | (data << 8); break;
|
||||
case 7:
|
||||
pulse[0].disable = data & 0x01;
|
||||
pulse[1].disable = data & 0x02;
|
||||
pulse[2].disable = data & 0x04;
|
||||
break;
|
||||
case 8: pulse[0].volume = data & 0x0f; break;
|
||||
case 9: pulse[1].volume = data & 0x0f; break;
|
||||
case 10: pulse[2].volume = data & 0x0f; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned chr_addr(unsigned addr) {
|
||||
uint8 bank = (addr >> 10) & 7;
|
||||
return (chr_bank[bank] << 10) | (addr & 0x03ff);
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) {
|
||||
switch(mirror) {
|
||||
case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical
|
||||
case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal
|
||||
case 2: return 0x0000 | (addr & 0x03ff); //first
|
||||
case 3: return 0x0400 | (addr & 0x03ff); //second
|
||||
}
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) return ppu.ciram_read(ciram_addr(addr));
|
||||
return Board::chr_read(chr_addr(addr));
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) return ppu.ciram_write(ciram_addr(addr), data);
|
||||
return Board::chr_write(chr_addr(addr), data);
|
||||
}
|
||||
|
||||
void power() {
|
||||
for(signed n = 0; n < 16; n++) {
|
||||
double volume = 1.0 / pow(2, 1.0 / 2 * (15 - n));
|
||||
dac[n] = volume * 8192.0;
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mmu_port = 0;
|
||||
apu_port = 0;
|
||||
|
||||
for(auto &n : prg_bank) n = 0;
|
||||
for(auto &n : chr_bank) n = 0;
|
||||
mirror = 0;
|
||||
irq_enable = 0;
|
||||
irq_counter_enable = 0;
|
||||
irq_counter = 0;
|
||||
|
||||
pulse[0].reset();
|
||||
pulse[1].reset();
|
||||
pulse[2].reset();
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
Board::serialize(s);
|
||||
|
||||
s.integer(mmu_port);
|
||||
s.integer(apu_port);
|
||||
|
||||
s.array(prg_bank);
|
||||
s.array(chr_bank);
|
||||
s.integer(mirror);
|
||||
s.integer(irq_enable);
|
||||
s.integer(irq_counter_enable);
|
||||
s.integer(irq_counter);
|
||||
|
||||
pulse[0].serialize(s);
|
||||
pulse[1].serialize(s);
|
||||
pulse[2].serialize(s);
|
||||
}
|
||||
|
||||
Sunsoft5B(XML::Document &document, const stream &memory) : Board(document, memory) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,91 +0,0 @@
|
||||
#include <fc/fc.hpp>
|
||||
|
||||
namespace Famicom {
|
||||
|
||||
#include "chip/chip.cpp"
|
||||
#include "board/board.cpp"
|
||||
Cartridge cartridge;
|
||||
|
||||
void Cartridge::Main() {
|
||||
cartridge.main();
|
||||
}
|
||||
|
||||
void Cartridge::main() {
|
||||
board->main();
|
||||
}
|
||||
|
||||
void Cartridge::load(const string &markup, const stream &memory) {
|
||||
information.markup = markup;
|
||||
|
||||
board = Board::load(markup, memory);
|
||||
if(board == nullptr) return;
|
||||
|
||||
interface->memory.append({ID::RAM, "save.ram"});
|
||||
|
||||
sha256_ctx sha;
|
||||
uint8_t hash[32];
|
||||
sha256_init(&sha);
|
||||
sha256_chunk(&sha, board->prgrom.data, board->prgrom.size);
|
||||
sha256_chunk(&sha, board->chrrom.data, board->chrrom.size);
|
||||
sha256_final(&sha);
|
||||
sha256_hash(&sha, hash);
|
||||
string result;
|
||||
for(auto &byte : hash) result.append(hex<2>(byte));
|
||||
sha256 = result;
|
||||
|
||||
system.load();
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
void Cartridge::unload() {
|
||||
if(loaded == false) return;
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
unsigned Cartridge::ram_size() {
|
||||
return board->memory().size;
|
||||
}
|
||||
|
||||
uint8* Cartridge::ram_data() {
|
||||
return board->memory().data;
|
||||
}
|
||||
|
||||
void Cartridge::power() {
|
||||
board->power();
|
||||
}
|
||||
|
||||
void Cartridge::reset() {
|
||||
create(Cartridge::Main, 21477272);
|
||||
board->reset();
|
||||
}
|
||||
|
||||
Cartridge::Cartridge() {
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
uint8 Cartridge::prg_read(unsigned addr) {
|
||||
return board->prg_read(addr);
|
||||
}
|
||||
|
||||
void Cartridge::prg_write(unsigned addr, uint8 data) {
|
||||
return board->prg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 Cartridge::chr_read(unsigned addr) {
|
||||
return board->chr_read(addr);
|
||||
}
|
||||
|
||||
void Cartridge::chr_write(unsigned addr, uint8 data) {
|
||||
return board->chr_write(addr, data);
|
||||
}
|
||||
|
||||
void Cartridge::scanline(unsigned y) {
|
||||
return board->scanline(y);
|
||||
}
|
||||
|
||||
void Cartridge::serialize(serializer &s) {
|
||||
Thread::serialize(s);
|
||||
return board->serialize(s);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#include "chip/chip.hpp"
|
||||
#include "board/board.hpp"
|
||||
|
||||
struct Cartridge : Thread, property<Cartridge> {
|
||||
static void Main();
|
||||
void main();
|
||||
|
||||
void load(const string &markup, const stream &memory);
|
||||
void unload();
|
||||
|
||||
unsigned ram_size();
|
||||
uint8* ram_data();
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
readonly<bool> loaded;
|
||||
readonly<string> sha256;
|
||||
|
||||
struct Information {
|
||||
string markup;
|
||||
} information;
|
||||
|
||||
void serialize(serializer&);
|
||||
Cartridge();
|
||||
|
||||
//privileged:
|
||||
Board *board;
|
||||
|
||||
uint8 prg_read(unsigned addr);
|
||||
void prg_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 chr_read(unsigned addr);
|
||||
void chr_write(unsigned addr, uint8 data);
|
||||
|
||||
//scanline() is for debugging purposes only:
|
||||
//boards must detect scanline edges on their own
|
||||
void scanline(unsigned y);
|
||||
};
|
||||
|
||||
extern Cartridge cartridge;
|
||||
@@ -1,17 +0,0 @@
|
||||
#include "mmc1.cpp"
|
||||
#include "mmc3.cpp"
|
||||
#include "mmc5.cpp"
|
||||
#include "mmc6.cpp"
|
||||
#include "vrc1.cpp"
|
||||
#include "vrc2.cpp"
|
||||
#include "vrc3.cpp"
|
||||
#include "vrc4.cpp"
|
||||
#include "vrc6.cpp"
|
||||
#include "vrc7.cpp"
|
||||
|
||||
void Chip::tick() {
|
||||
board.tick();
|
||||
}
|
||||
|
||||
Chip::Chip(Board &board) : board(board) {
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
struct Board;
|
||||
|
||||
struct Chip {
|
||||
Board &board;
|
||||
void tick();
|
||||
Chip(Board &board);
|
||||
};
|
||||
@@ -1,136 +0,0 @@
|
||||
struct MMC1 : Chip {
|
||||
|
||||
enum class Revision : unsigned {
|
||||
MMC1,
|
||||
MMC1A,
|
||||
MMC1B1,
|
||||
MMC1B2,
|
||||
MMC1B3,
|
||||
MMC1C,
|
||||
} revision;
|
||||
|
||||
unsigned writedelay;
|
||||
unsigned shiftaddr;
|
||||
unsigned shiftdata;
|
||||
|
||||
bool chr_mode;
|
||||
bool prg_size; //0 = 32K, 1 = 16K
|
||||
bool prg_mode;
|
||||
uint2 mirror; //0 = first, 1 = second, 2 = vertical, 3 = horizontal
|
||||
uint5 chr_bank[2];
|
||||
bool ram_disable;
|
||||
uint4 prg_bank;
|
||||
|
||||
void main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(writedelay) writedelay--;
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned prg_addr(unsigned addr) {
|
||||
bool region = addr & 0x4000;
|
||||
unsigned bank = (prg_bank & ~1) + region;
|
||||
|
||||
if(prg_size) {
|
||||
bank = (region == 0 ? 0x0 : 0xf);
|
||||
if(region != prg_mode) bank = prg_bank;
|
||||
}
|
||||
|
||||
return (bank << 14) | (addr & 0x3fff);
|
||||
}
|
||||
|
||||
unsigned chr_addr(unsigned addr) {
|
||||
bool region = addr & 0x1000;
|
||||
unsigned bank = chr_bank[region];
|
||||
if(chr_mode == 0) bank = (chr_bank[0] & ~1) | region;
|
||||
return (bank << 12) | (addr & 0x0fff);
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) {
|
||||
switch(mirror) {
|
||||
case 0: return 0x0000 | (addr & 0x03ff);
|
||||
case 1: return 0x0400 | (addr & 0x03ff);
|
||||
case 2: return ((addr & 0x0400) >> 0) | (addr & 0x03ff);
|
||||
case 3: return ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
}
|
||||
}
|
||||
|
||||
void mmio_write(unsigned addr, uint8 data) {
|
||||
if(writedelay) return;
|
||||
writedelay = 2;
|
||||
|
||||
if(data & 0x80) {
|
||||
shiftaddr = 0;
|
||||
prg_size = 1;
|
||||
prg_mode = 1;
|
||||
} else {
|
||||
shiftdata = ((data & 1) << 4) | (shiftdata >> 1);
|
||||
if(++shiftaddr == 5) {
|
||||
shiftaddr = 0;
|
||||
switch((addr >> 13) & 3) {
|
||||
case 0:
|
||||
chr_mode = (shiftdata & 0x10);
|
||||
prg_size = (shiftdata & 0x08);
|
||||
prg_mode = (shiftdata & 0x04);
|
||||
mirror = (shiftdata & 0x03);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
chr_bank[0] = (shiftdata & 0x1f);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
chr_bank[1] = (shiftdata & 0x1f);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
ram_disable = (shiftdata & 0x10);
|
||||
prg_bank = (shiftdata & 0x0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
writedelay = 0;
|
||||
shiftaddr = 0;
|
||||
shiftdata = 0;
|
||||
|
||||
chr_mode = 0;
|
||||
prg_size = 1;
|
||||
prg_mode = 1;
|
||||
mirror = 0;
|
||||
chr_bank[0] = 0;
|
||||
chr_bank[1] = 1;
|
||||
ram_disable = 0;
|
||||
prg_bank = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
s.integer(writedelay);
|
||||
s.integer(shiftaddr);
|
||||
s.integer(shiftdata);
|
||||
|
||||
s.integer(chr_mode);
|
||||
s.integer(prg_size);
|
||||
s.integer(prg_mode);
|
||||
s.integer(mirror);
|
||||
s.array(chr_bank);
|
||||
s.integer(ram_disable);
|
||||
s.integer(prg_bank);
|
||||
}
|
||||
|
||||
MMC1(Board &board) : Chip(board) {
|
||||
revision = Revision::MMC1B2;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,189 +0,0 @@
|
||||
struct MMC3 : Chip {
|
||||
|
||||
bool chr_mode;
|
||||
bool prg_mode;
|
||||
uint3 bank_select;
|
||||
uint8 prg_bank[2];
|
||||
uint8 chr_bank[6];
|
||||
bool mirror;
|
||||
bool ram_enable;
|
||||
bool ram_write_protect;
|
||||
uint8 irq_latch;
|
||||
uint8 irq_counter;
|
||||
bool irq_enable;
|
||||
unsigned irq_delay;
|
||||
bool irq_line;
|
||||
|
||||
uint16 chr_abus;
|
||||
|
||||
void main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(irq_delay) irq_delay--;
|
||||
cpu.set_irq_line(irq_line);
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
void irq_test(unsigned addr) {
|
||||
if(!(chr_abus & 0x1000) && (addr & 0x1000)) {
|
||||
if(irq_delay == 0) {
|
||||
if(irq_counter == 0) {
|
||||
irq_counter = irq_latch;
|
||||
} else if(--irq_counter == 0) {
|
||||
if(irq_enable) irq_line = 1;
|
||||
}
|
||||
}
|
||||
irq_delay = 6;
|
||||
}
|
||||
chr_abus = addr;
|
||||
}
|
||||
|
||||
unsigned prg_addr(unsigned addr) const {
|
||||
switch((addr >> 13) & 3) {
|
||||
case 0:
|
||||
if(prg_mode == 1) return (0x3e << 13) | (addr & 0x1fff);
|
||||
return (prg_bank[0] << 13) | (addr & 0x1fff);
|
||||
case 1:
|
||||
return (prg_bank[1] << 13) | (addr & 0x1fff);
|
||||
case 2:
|
||||
if(prg_mode == 0) return (0x3e << 13) | (addr & 0x1fff);
|
||||
return (prg_bank[0] << 13) | (addr & 0x1fff);
|
||||
case 3:
|
||||
return (0x3f << 13) | (addr & 0x1fff);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned chr_addr(unsigned addr) const {
|
||||
if(chr_mode == 0) {
|
||||
if(addr <= 0x07ff) return (chr_bank[0] << 10) | (addr & 0x07ff);
|
||||
if(addr <= 0x0fff) return (chr_bank[1] << 10) | (addr & 0x07ff);
|
||||
if(addr <= 0x13ff) return (chr_bank[2] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x17ff) return (chr_bank[3] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x1bff) return (chr_bank[4] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x1fff) return (chr_bank[5] << 10) | (addr & 0x03ff);
|
||||
} else {
|
||||
if(addr <= 0x03ff) return (chr_bank[2] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x07ff) return (chr_bank[3] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x0bff) return (chr_bank[4] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x0fff) return (chr_bank[5] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x17ff) return (chr_bank[0] << 10) | (addr & 0x07ff);
|
||||
if(addr <= 0x1fff) return (chr_bank[1] << 10) | (addr & 0x07ff);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) const {
|
||||
if(mirror == 0) return ((addr & 0x0400) >> 0) | (addr & 0x03ff);
|
||||
if(mirror == 1) return ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
}
|
||||
|
||||
uint8 ram_read(unsigned addr) {
|
||||
if(ram_enable) return board.prgram.data[addr & 0x1fff];
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void ram_write(unsigned addr, uint8 data) {
|
||||
if(ram_enable && !ram_write_protect) board.prgram.data[addr & 0x1fff] = data;
|
||||
}
|
||||
|
||||
void reg_write(unsigned addr, uint8 data) {
|
||||
switch(addr & 0xe001) {
|
||||
case 0x8000:
|
||||
chr_mode = data & 0x80;
|
||||
prg_mode = data & 0x40;
|
||||
bank_select = data & 0x07;
|
||||
break;
|
||||
|
||||
case 0x8001:
|
||||
switch(bank_select) {
|
||||
case 0: chr_bank[0] = data & ~1; break;
|
||||
case 1: chr_bank[1] = data & ~1; break;
|
||||
case 2: chr_bank[2] = data; break;
|
||||
case 3: chr_bank[3] = data; break;
|
||||
case 4: chr_bank[4] = data; break;
|
||||
case 5: chr_bank[5] = data; break;
|
||||
case 6: prg_bank[0] = data & 0x3f; break;
|
||||
case 7: prg_bank[1] = data & 0x3f; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa000:
|
||||
mirror = data & 0x01;
|
||||
break;
|
||||
|
||||
case 0xa001:
|
||||
ram_enable = data & 0x80;
|
||||
ram_write_protect = data & 0x40;
|
||||
break;
|
||||
|
||||
case 0xc000:
|
||||
irq_latch = data;
|
||||
break;
|
||||
|
||||
case 0xc001:
|
||||
irq_counter = 0;
|
||||
break;
|
||||
|
||||
case 0xe000:
|
||||
irq_enable = false;
|
||||
irq_line = 0;
|
||||
break;
|
||||
|
||||
case 0xe001:
|
||||
irq_enable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
chr_mode = 0;
|
||||
prg_mode = 0;
|
||||
bank_select = 0;
|
||||
prg_bank[0] = 0;
|
||||
prg_bank[1] = 0;
|
||||
chr_bank[0] = 0;
|
||||
chr_bank[1] = 0;
|
||||
chr_bank[2] = 0;
|
||||
chr_bank[3] = 0;
|
||||
chr_bank[4] = 0;
|
||||
chr_bank[5] = 0;
|
||||
mirror = 0;
|
||||
ram_enable = 1;
|
||||
ram_write_protect = 0;
|
||||
irq_latch = 0;
|
||||
irq_counter = 0;
|
||||
irq_enable = false;
|
||||
irq_delay = 0;
|
||||
irq_line = 0;
|
||||
|
||||
chr_abus = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
s.integer(chr_mode);
|
||||
s.integer(prg_mode);
|
||||
s.integer(bank_select);
|
||||
s.array(prg_bank);
|
||||
s.array(chr_bank);
|
||||
s.integer(mirror);
|
||||
s.integer(ram_enable);
|
||||
s.integer(ram_write_protect);
|
||||
s.integer(irq_latch);
|
||||
s.integer(irq_counter);
|
||||
s.integer(irq_enable);
|
||||
s.integer(irq_delay);
|
||||
s.integer(irq_line);
|
||||
|
||||
s.integer(chr_abus);
|
||||
}
|
||||
|
||||
MMC3(Board &board) : Chip(board) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,497 +0,0 @@
|
||||
struct MMC5 : Chip {
|
||||
|
||||
enum class Revision : unsigned {
|
||||
MMC5,
|
||||
MMC5B,
|
||||
} revision;
|
||||
|
||||
uint8 exram[1024];
|
||||
|
||||
//programmable registers
|
||||
|
||||
uint2 prg_mode; //$5100
|
||||
uint2 chr_mode; //$5101
|
||||
|
||||
uint2 prgram_write_protect[2]; //$5102,$5103
|
||||
|
||||
uint2 exram_mode; //$5104
|
||||
uint2 nametable_mode[4]; //$5105
|
||||
uint8 fillmode_tile; //$5106
|
||||
uint8 fillmode_color; //$5107
|
||||
|
||||
bool ram_select; //$5113
|
||||
uint2 ram_bank; //$5113
|
||||
uint8 prg_bank[4]; //$5114-5117
|
||||
uint10 chr_sprite_bank[8]; //$5120-5127
|
||||
uint10 chr_bg_bank[4]; //$5128-512b
|
||||
uint2 chr_bank_hi; //$5130
|
||||
|
||||
bool vs_enable; //$5200
|
||||
bool vs_side; //$5200
|
||||
uint5 vs_tile; //$5200
|
||||
uint8 vs_scroll; //$5201
|
||||
uint8 vs_bank; //$5202
|
||||
|
||||
uint8 irq_line; //$5203
|
||||
bool irq_enable; //$5204
|
||||
|
||||
uint8 multiplicand; //$5205
|
||||
uint8 multiplier; //$5206
|
||||
|
||||
//status registers
|
||||
|
||||
unsigned cpu_cycle_counter;
|
||||
unsigned irq_counter;
|
||||
bool irq_pending;
|
||||
bool in_frame;
|
||||
|
||||
unsigned vcounter;
|
||||
unsigned hcounter;
|
||||
uint16 chr_access[4];
|
||||
bool chr_active;
|
||||
bool sprite_8x16;
|
||||
|
||||
uint8 exbank;
|
||||
uint8 exattr;
|
||||
|
||||
bool vs_fetch;
|
||||
uint8 vs_vpos;
|
||||
uint8 vs_hpos;
|
||||
|
||||
void main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
//scanline() resets this; if no scanlines detected, enter video blanking period
|
||||
if(++cpu_cycle_counter >= 200) blank(); //113-114 normal; ~2500 across Vblank period
|
||||
|
||||
cpu.set_irq_line(irq_enable && irq_pending);
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
void scanline(unsigned y) {
|
||||
//used for testing only, to verify MMC5 scanline detection is accurate:
|
||||
//if(y != vcounter && y <= 240) print(y, " vs ", vcounter, "\n");
|
||||
}
|
||||
|
||||
uint8 prg_access(bool write, unsigned addr, uint8 data = 0x00) {
|
||||
unsigned bank;
|
||||
|
||||
if((addr & 0xe000) == 0x6000) {
|
||||
bank = (ram_select << 2) | ram_bank;
|
||||
addr &= 0x1fff;
|
||||
} else if(prg_mode == 0) {
|
||||
bank = prg_bank[3] & ~3;
|
||||
addr &= 0x7fff;
|
||||
} else if(prg_mode == 1) {
|
||||
if((addr & 0xc000) == 0x8000) bank = (prg_bank[1] & ~1);
|
||||
if((addr & 0xe000) == 0xc000) bank = (prg_bank[3] & ~1);
|
||||
addr &= 0x3fff;
|
||||
} else if(prg_mode == 2) {
|
||||
if((addr & 0xe000) == 0x8000) bank = (prg_bank[1] & ~1) | 0;
|
||||
if((addr & 0xe000) == 0xa000) bank = (prg_bank[1] & ~1) | 1;
|
||||
if((addr & 0xe000) == 0xc000) bank = (prg_bank[2]);
|
||||
if((addr & 0xe000) == 0xe000) bank = (prg_bank[3]);
|
||||
addr &= 0x1fff;
|
||||
} else if(prg_mode == 3) {
|
||||
if((addr & 0xe000) == 0x8000) bank = prg_bank[0];
|
||||
if((addr & 0xe000) == 0xa000) bank = prg_bank[1];
|
||||
if((addr & 0xe000) == 0xc000) bank = prg_bank[2];
|
||||
if((addr & 0xe000) == 0xe000) bank = prg_bank[3];
|
||||
addr &= 0x1fff;
|
||||
}
|
||||
|
||||
bool rom = bank & 0x80;
|
||||
bank &= 0x7f;
|
||||
|
||||
if(write == false) {
|
||||
if(rom) {
|
||||
return board.prgrom.read((bank << 13) | addr);
|
||||
} else {
|
||||
return board.prgram.read((bank << 13) | addr);
|
||||
}
|
||||
} else {
|
||||
if(rom) {
|
||||
board.prgrom.write((bank << 13) | addr, data);
|
||||
} else {
|
||||
if(prgram_write_protect[0] == 2 && prgram_write_protect[1] == 1) {
|
||||
board.prgram.write((bank << 13) | addr, data);
|
||||
}
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if((addr & 0xfc00) == 0x5c00) {
|
||||
if(exram_mode >= 2) return exram[addr & 0x03ff];
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
if(addr >= 0x6000) {
|
||||
return prg_access(0, addr);
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x5204: {
|
||||
uint8 result = (irq_pending << 7) | (in_frame << 6);
|
||||
irq_pending = false;
|
||||
return result;
|
||||
}
|
||||
case 0x5205: return (multiplier * multiplicand) >> 0;
|
||||
case 0x5206: return (multiplier * multiplicand) >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
if((addr & 0xfc00) == 0x5c00) {
|
||||
//writes 0x00 *during* Vblank (not during screen rendering ...)
|
||||
if(exram_mode == 0 || exram_mode == 1) exram[addr & 0x03ff] = in_frame ? data : 0x00;
|
||||
if(exram_mode == 2) exram[addr & 0x03ff] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr >= 0x6000) {
|
||||
prg_access(1, addr, data);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x2000:
|
||||
sprite_8x16 = data & 0x20;
|
||||
break;
|
||||
|
||||
case 0x2001:
|
||||
//if BG+sprites are disabled; enter video blanking period
|
||||
if((data & 0x18) == 0) blank();
|
||||
break;
|
||||
|
||||
case 0x5100: prg_mode = data & 3; break;
|
||||
case 0x5101: chr_mode = data & 3; break;
|
||||
|
||||
case 0x5102: prgram_write_protect[0] = data & 3; break;
|
||||
case 0x5103: prgram_write_protect[1] = data & 3; break;
|
||||
|
||||
case 0x5104:
|
||||
exram_mode = data & 3;
|
||||
break;
|
||||
|
||||
case 0x5105:
|
||||
nametable_mode[0] = (data & 0x03) >> 0;
|
||||
nametable_mode[1] = (data & 0x0c) >> 2;
|
||||
nametable_mode[2] = (data & 0x30) >> 4;
|
||||
nametable_mode[3] = (data & 0xc0) >> 6;
|
||||
break;
|
||||
|
||||
case 0x5106:
|
||||
fillmode_tile = data;
|
||||
break;
|
||||
|
||||
case 0x5107:
|
||||
fillmode_color = data & 3;
|
||||
fillmode_color |= fillmode_color << 2;
|
||||
fillmode_color |= fillmode_color << 4;
|
||||
break;
|
||||
|
||||
case 0x5113:
|
||||
ram_select = data & 0x04;
|
||||
ram_bank = data & 0x03;
|
||||
break;
|
||||
|
||||
case 0x5114: prg_bank[0] = data; break;
|
||||
case 0x5115: prg_bank[1] = data; break;
|
||||
case 0x5116: prg_bank[2] = data; break;
|
||||
case 0x5117: prg_bank[3] = data | 0x80; break;
|
||||
|
||||
case 0x5120: chr_sprite_bank[0] = (chr_bank_hi << 8) | data; chr_active = 0; break;
|
||||
case 0x5121: chr_sprite_bank[1] = (chr_bank_hi << 8) | data; chr_active = 0; break;
|
||||
case 0x5122: chr_sprite_bank[2] = (chr_bank_hi << 8) | data; chr_active = 0; break;
|
||||
case 0x5123: chr_sprite_bank[3] = (chr_bank_hi << 8) | data; chr_active = 0; break;
|
||||
case 0x5124: chr_sprite_bank[4] = (chr_bank_hi << 8) | data; chr_active = 0; break;
|
||||
case 0x5125: chr_sprite_bank[5] = (chr_bank_hi << 8) | data; chr_active = 0; break;
|
||||
case 0x5126: chr_sprite_bank[6] = (chr_bank_hi << 8) | data; chr_active = 0; break;
|
||||
case 0x5127: chr_sprite_bank[7] = (chr_bank_hi << 8) | data; chr_active = 0; break;
|
||||
|
||||
case 0x5128: chr_bg_bank[0] = (chr_bank_hi << 8) | data; chr_active = 1; break;
|
||||
case 0x5129: chr_bg_bank[1] = (chr_bank_hi << 8) | data; chr_active = 1; break;
|
||||
case 0x512a: chr_bg_bank[2] = (chr_bank_hi << 8) | data; chr_active = 1; break;
|
||||
case 0x512b: chr_bg_bank[3] = (chr_bank_hi << 8) | data; chr_active = 1; break;
|
||||
|
||||
case 0x5130:
|
||||
chr_bank_hi = data & 3;
|
||||
break;
|
||||
|
||||
case 0x5200:
|
||||
vs_enable = data & 0x80;
|
||||
vs_side = data & 0x40;
|
||||
vs_tile = data & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x5201:
|
||||
vs_scroll = data;
|
||||
break;
|
||||
|
||||
case 0x5202:
|
||||
vs_bank = data;
|
||||
break;
|
||||
|
||||
case 0x5203:
|
||||
irq_line = data;
|
||||
break;
|
||||
|
||||
case 0x5204:
|
||||
irq_enable = data & 0x80;
|
||||
break;
|
||||
|
||||
case 0x5205:
|
||||
multiplicand = data;
|
||||
break;
|
||||
|
||||
case 0x5206:
|
||||
multiplier = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned chr_sprite_addr(unsigned addr) {
|
||||
if(chr_mode == 0) {
|
||||
auto bank = chr_sprite_bank[7];
|
||||
return (bank * 0x2000) + (addr & 0x1fff);
|
||||
}
|
||||
|
||||
if(chr_mode == 1) {
|
||||
auto bank = chr_sprite_bank[(addr / 0x1000) * 4 + 3];
|
||||
return (bank * 0x1000) + (addr & 0x0fff);
|
||||
}
|
||||
|
||||
if(chr_mode == 2) {
|
||||
auto bank = chr_sprite_bank[(addr / 0x0800) * 2 + 1];
|
||||
return (bank * 0x0800) + (addr & 0x07ff);
|
||||
}
|
||||
|
||||
if(chr_mode == 3) {
|
||||
auto bank = chr_sprite_bank[(addr / 0x0400)];
|
||||
return (bank * 0x0400) + (addr & 0x03ff);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned chr_bg_addr(unsigned addr) {
|
||||
addr &= 0x0fff;
|
||||
|
||||
if(chr_mode == 0) {
|
||||
auto bank = chr_bg_bank[3];
|
||||
return (bank * 0x2000) + (addr & 0x0fff);
|
||||
}
|
||||
|
||||
if(chr_mode == 1) {
|
||||
auto bank = chr_bg_bank[3];
|
||||
return (bank * 0x1000) + (addr & 0x0fff);
|
||||
}
|
||||
|
||||
if(chr_mode == 2) {
|
||||
auto bank = chr_bg_bank[(addr / 0x0800) * 2 + 1];
|
||||
return (bank * 0x0800) + (addr & 0x07ff);
|
||||
}
|
||||
|
||||
if(chr_mode == 3) {
|
||||
auto bank = chr_bg_bank[(addr / 0x0400)];
|
||||
return (bank * 0x0400) + (addr & 0x03ff);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned chr_vs_addr(unsigned addr) {
|
||||
return (vs_bank * 0x1000) + (addr & 0x0ff8) + (vs_vpos & 7);
|
||||
}
|
||||
|
||||
void blank() {
|
||||
in_frame = false;
|
||||
}
|
||||
|
||||
void scanline() {
|
||||
hcounter = 0;
|
||||
|
||||
if(in_frame == false) {
|
||||
in_frame = true;
|
||||
irq_pending = false;
|
||||
vcounter = 0;
|
||||
} else {
|
||||
if(vcounter == irq_line) irq_pending = true;
|
||||
vcounter++;
|
||||
}
|
||||
|
||||
cpu_cycle_counter = 0;
|
||||
}
|
||||
|
||||
uint8 ciram_read(unsigned addr) {
|
||||
if(vs_fetch && (hcounter & 2) == 0) return exram[vs_vpos / 8 * 32 + vs_hpos / 8];
|
||||
if(vs_fetch && (hcounter & 2) != 0) return exram[vs_vpos / 32 * 8 + vs_hpos / 32 + 0x03c0];
|
||||
|
||||
switch(nametable_mode[(addr >> 10) & 3]) {
|
||||
case 0: return ppu.ciram_read(0x0000 | (addr & 0x03ff));
|
||||
case 1: return ppu.ciram_read(0x0400 | (addr & 0x03ff));
|
||||
case 2: return exram_mode < 2 ? exram[addr & 0x03ff] : 0x00;
|
||||
case 3: return (hcounter & 2) == 0 ? fillmode_tile : fillmode_color;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
chr_access[0] = chr_access[1];
|
||||
chr_access[1] = chr_access[2];
|
||||
chr_access[2] = chr_access[3];
|
||||
chr_access[3] = addr;
|
||||
|
||||
//detect two unused nametable fetches at end of each scanline
|
||||
if((chr_access[0] & 0x2000) == 0
|
||||
&& (chr_access[1] & 0x2000)
|
||||
&& (chr_access[2] & 0x2000)
|
||||
&& (chr_access[3] & 0x2000)) scanline();
|
||||
|
||||
if(in_frame == false) {
|
||||
vs_fetch = false;
|
||||
if(addr & 0x2000) return ciram_read(addr);
|
||||
return board.chrrom.read(chr_active ? chr_bg_addr(addr) : chr_sprite_addr(addr));
|
||||
}
|
||||
|
||||
bool bg_fetch = (hcounter < 256 || hcounter >= 320);
|
||||
uint8 result = 0x00;
|
||||
|
||||
if((hcounter & 7) == 0) {
|
||||
vs_hpos = hcounter >= 320 ? hcounter - 320 : hcounter + 16;
|
||||
vs_vpos = vcounter + vs_scroll;
|
||||
vs_fetch = vs_enable && bg_fetch && exram_mode < 2
|
||||
&& (vs_side ? vs_hpos / 8 >= vs_tile : vs_hpos / 8 < vs_tile);
|
||||
if(vs_vpos >= 240) vs_vpos -= 240;
|
||||
|
||||
result = ciram_read(addr);
|
||||
|
||||
exbank = (chr_bank_hi << 6) | (exram[addr & 0x03ff] & 0x3f);
|
||||
exattr = exram[addr & 0x03ff] >> 6;
|
||||
exattr |= exattr << 2;
|
||||
exattr |= exattr << 4;
|
||||
} else if((hcounter & 7) == 2) {
|
||||
result = ciram_read(addr);
|
||||
if(bg_fetch && exram_mode == 1) result = exattr;
|
||||
} else {
|
||||
if(vs_fetch) result = board.chrrom.read(chr_vs_addr(addr));
|
||||
else if(sprite_8x16 ? bg_fetch : chr_active) result = board.chrrom.read(chr_bg_addr(addr));
|
||||
else result = board.chrrom.read(chr_sprite_addr(addr));
|
||||
if(bg_fetch && exram_mode == 1) result = board.chrrom.read(exbank * 0x1000 + (addr & 0x0fff));
|
||||
}
|
||||
|
||||
hcounter += 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) {
|
||||
switch(nametable_mode[(addr >> 10) & 3]) {
|
||||
case 0: return ppu.ciram_write(0x0000 | (addr & 0x03ff), data);
|
||||
case 1: return ppu.ciram_write(0x0400 | (addr & 0x03ff), data);
|
||||
case 2: exram[addr & 0x03ff] = data; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
for(auto &n : exram) n = 0xff;
|
||||
|
||||
prg_mode = 3;
|
||||
chr_mode = 0;
|
||||
for(auto &n : prgram_write_protect) n = 0;
|
||||
exram_mode = 0;
|
||||
for(auto &n : nametable_mode) n = 0;
|
||||
fillmode_tile = 0;
|
||||
fillmode_color = 0;
|
||||
ram_select = 0;
|
||||
ram_bank = 0;
|
||||
prg_bank[0] = 0x00;
|
||||
prg_bank[1] = 0x00;
|
||||
prg_bank[2] = 0x00;
|
||||
prg_bank[3] = 0xff;
|
||||
for(auto &n : chr_sprite_bank) n = 0;
|
||||
for(auto &n : chr_bg_bank) n = 0;
|
||||
chr_bank_hi = 0;
|
||||
vs_enable = 0;
|
||||
vs_side = 0;
|
||||
vs_tile = 0;
|
||||
vs_scroll = 0;
|
||||
vs_bank = 0;
|
||||
irq_line = 0;
|
||||
irq_enable = 0;
|
||||
multiplicand = 0;
|
||||
multiplier = 0;
|
||||
|
||||
cpu_cycle_counter = 0;
|
||||
irq_counter = 0;
|
||||
irq_pending = 0;
|
||||
in_frame = 0;
|
||||
vcounter = 0;
|
||||
hcounter = 0;
|
||||
for(auto &n : chr_access) n = 0;
|
||||
chr_active = 0;
|
||||
sprite_8x16 = 0;
|
||||
|
||||
exbank = 0;
|
||||
exattr = 0;
|
||||
|
||||
vs_fetch = 0;
|
||||
vs_vpos = 0;
|
||||
vs_hpos = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
s.array(exram);
|
||||
|
||||
s.integer(prg_mode);
|
||||
s.integer(chr_mode);
|
||||
for(auto &n : prgram_write_protect) s.integer(n);
|
||||
s.integer(exram_mode);
|
||||
for(auto &n : nametable_mode) s.integer(n);
|
||||
s.integer(fillmode_tile);
|
||||
s.integer(fillmode_color);
|
||||
s.integer(ram_select);
|
||||
s.integer(ram_bank);
|
||||
for(auto &n : prg_bank) s.integer(n);
|
||||
for(auto &n : chr_sprite_bank) s.integer(n);
|
||||
for(auto &n : chr_bg_bank) s.integer(n);
|
||||
s.integer(chr_bank_hi);
|
||||
s.integer(vs_enable);
|
||||
s.integer(vs_side);
|
||||
s.integer(vs_tile);
|
||||
s.integer(vs_scroll);
|
||||
s.integer(vs_bank);
|
||||
s.integer(irq_line);
|
||||
s.integer(irq_enable);
|
||||
s.integer(multiplicand);
|
||||
s.integer(multiplier);
|
||||
|
||||
s.integer(cpu_cycle_counter);
|
||||
s.integer(irq_counter);
|
||||
s.integer(irq_pending);
|
||||
s.integer(in_frame);
|
||||
|
||||
s.integer(vcounter);
|
||||
s.integer(hcounter);
|
||||
for(auto &n : chr_access) s.integer(n);
|
||||
s.integer(chr_active);
|
||||
s.integer(sprite_8x16);
|
||||
|
||||
s.integer(exbank);
|
||||
s.integer(exattr);
|
||||
|
||||
s.integer(vs_fetch);
|
||||
s.integer(vs_vpos);
|
||||
s.integer(vs_hpos);
|
||||
}
|
||||
|
||||
MMC5(Board &board) : Chip(board) {
|
||||
revision = Revision::MMC5;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,200 +0,0 @@
|
||||
struct MMC6 : Chip {
|
||||
|
||||
bool chr_mode;
|
||||
bool prg_mode;
|
||||
bool ram_enable;
|
||||
uint3 bank_select;
|
||||
uint8 prg_bank[2];
|
||||
uint8 chr_bank[6];
|
||||
bool mirror;
|
||||
bool ram_readable[2];
|
||||
bool ram_writable[2];
|
||||
uint8 irq_latch;
|
||||
uint8 irq_counter;
|
||||
bool irq_enable;
|
||||
unsigned irq_delay;
|
||||
bool irq_line;
|
||||
|
||||
uint16 chr_abus;
|
||||
|
||||
void main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(irq_delay) irq_delay--;
|
||||
cpu.set_irq_line(irq_line);
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
void irq_test(unsigned addr) {
|
||||
if(!(chr_abus & 0x1000) && (addr & 0x1000)) {
|
||||
if(irq_delay == 0) {
|
||||
if(irq_counter == 0) {
|
||||
irq_counter = irq_latch;
|
||||
} else if(--irq_counter == 0) {
|
||||
if(irq_enable) irq_line = 1;
|
||||
}
|
||||
}
|
||||
irq_delay = 6;
|
||||
}
|
||||
chr_abus = addr;
|
||||
}
|
||||
|
||||
unsigned prg_addr(unsigned addr) const {
|
||||
switch((addr >> 13) & 3) {
|
||||
case 0:
|
||||
if(prg_mode == 1) return (0x3e << 13) | (addr & 0x1fff);
|
||||
return (prg_bank[0] << 13) | (addr & 0x1fff);
|
||||
case 1:
|
||||
return (prg_bank[1] << 13) | (addr & 0x1fff);
|
||||
case 2:
|
||||
if(prg_mode == 0) return (0x3e << 13) | (addr & 0x1fff);
|
||||
return (prg_bank[0] << 13) | (addr & 0x1fff);
|
||||
case 3:
|
||||
return (0x3f << 13) | (addr & 0x1fff);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned chr_addr(unsigned addr) const {
|
||||
if(chr_mode == 0) {
|
||||
if(addr <= 0x07ff) return (chr_bank[0] << 10) | (addr & 0x07ff);
|
||||
if(addr <= 0x0fff) return (chr_bank[1] << 10) | (addr & 0x07ff);
|
||||
if(addr <= 0x13ff) return (chr_bank[2] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x17ff) return (chr_bank[3] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x1bff) return (chr_bank[4] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x1fff) return (chr_bank[5] << 10) | (addr & 0x03ff);
|
||||
} else {
|
||||
if(addr <= 0x03ff) return (chr_bank[2] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x07ff) return (chr_bank[3] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x0bff) return (chr_bank[4] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x0fff) return (chr_bank[5] << 10) | (addr & 0x03ff);
|
||||
if(addr <= 0x17ff) return (chr_bank[0] << 10) | (addr & 0x07ff);
|
||||
if(addr <= 0x1fff) return (chr_bank[1] << 10) | (addr & 0x07ff);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) const {
|
||||
if(mirror == 0) return ((addr & 0x0400) >> 0) | (addr & 0x03ff);
|
||||
if(mirror == 1) return ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
}
|
||||
|
||||
uint8 ram_read(unsigned addr) {
|
||||
if(ram_enable == false) return cpu.mdr();
|
||||
if(ram_readable[0] == false && ram_readable[1] == false) return cpu.mdr();
|
||||
bool region = addr & 0x0200;
|
||||
if(ram_readable[region] == false) return 0x00;
|
||||
return board.prgram.read((region * 0x0200) + (addr & 0x01ff));
|
||||
}
|
||||
|
||||
void ram_write(unsigned addr, uint8 data) {
|
||||
if(ram_enable == false) return;
|
||||
bool region = addr & 0x0200;
|
||||
if(ram_writable[region] == false) return;
|
||||
return board.prgram.write((region * 0x0200) + (addr & 0x01ff), data);
|
||||
}
|
||||
|
||||
void reg_write(unsigned addr, uint8 data) {
|
||||
switch(addr & 0xe001) {
|
||||
case 0x8000:
|
||||
chr_mode = data & 0x80;
|
||||
prg_mode = data & 0x40;
|
||||
ram_enable = data & 0x20;
|
||||
bank_select = data & 0x07;
|
||||
if(ram_enable == false) {
|
||||
for(auto &n : ram_readable) n = false;
|
||||
for(auto &n : ram_writable) n = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8001:
|
||||
switch(bank_select) {
|
||||
case 0: chr_bank[0] = data & ~1; break;
|
||||
case 1: chr_bank[1] = data & ~1; break;
|
||||
case 2: chr_bank[2] = data; break;
|
||||
case 3: chr_bank[3] = data; break;
|
||||
case 4: chr_bank[4] = data; break;
|
||||
case 5: chr_bank[5] = data; break;
|
||||
case 6: prg_bank[0] = data & 0x3f; break;
|
||||
case 7: prg_bank[1] = data & 0x3f; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa000:
|
||||
mirror = data & 0x01;
|
||||
break;
|
||||
|
||||
case 0xa001:
|
||||
if(ram_enable == false) break;
|
||||
ram_readable[1] = data & 0x80;
|
||||
ram_writable[1] = data & 0x40;
|
||||
ram_readable[0] = data & 0x20;
|
||||
ram_writable[0] = data & 0x10;
|
||||
break;
|
||||
|
||||
case 0xc000:
|
||||
irq_latch = data;
|
||||
break;
|
||||
|
||||
case 0xc001:
|
||||
irq_counter = 0;
|
||||
break;
|
||||
|
||||
case 0xe000:
|
||||
irq_enable = false;
|
||||
irq_line = 0;
|
||||
break;
|
||||
|
||||
case 0xe001:
|
||||
irq_enable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
chr_mode = 0;
|
||||
prg_mode = 0;
|
||||
ram_enable = 0;
|
||||
bank_select = 0;
|
||||
for(auto &n : prg_bank) n = 0;
|
||||
for(auto &n : chr_bank) n = 0;
|
||||
mirror = 0;
|
||||
for(auto &n : ram_readable) n = 0;
|
||||
for(auto &n : ram_writable) n = 0;
|
||||
irq_latch = 0;
|
||||
irq_counter = 0;
|
||||
irq_enable = 0;
|
||||
irq_delay = 0;
|
||||
irq_line = 0;
|
||||
|
||||
chr_abus = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
s.integer(chr_mode);
|
||||
s.integer(prg_mode);
|
||||
s.integer(ram_enable);
|
||||
s.integer(bank_select);
|
||||
for(auto &n : prg_bank) s.integer(n);
|
||||
for(auto &n : chr_bank) s.integer(n);
|
||||
s.integer(mirror);
|
||||
for(auto &n : ram_readable) s.integer(n);
|
||||
for(auto &n : ram_writable) s.integer(n);
|
||||
s.integer(irq_latch);
|
||||
s.integer(irq_counter);
|
||||
s.integer(irq_enable);
|
||||
s.integer(irq_delay);
|
||||
s.integer(irq_line);
|
||||
|
||||
s.integer(chr_abus);
|
||||
}
|
||||
|
||||
MMC6(Board &board) : Chip(board) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,80 +0,0 @@
|
||||
struct VRC1 : Chip {
|
||||
|
||||
uint4 prg_bank[3];
|
||||
uint4 chr_banklo[2];
|
||||
bool chr_bankhi[2];
|
||||
bool mirror;
|
||||
|
||||
unsigned prg_addr(unsigned addr) const {
|
||||
unsigned bank = 0x0f;
|
||||
if((addr & 0xe000) == 0x8000) bank = prg_bank[0];
|
||||
if((addr & 0xe000) == 0xa000) bank = prg_bank[1];
|
||||
if((addr & 0xe000) == 0xc000) bank = prg_bank[2];
|
||||
return (bank * 0x2000) + (addr & 0x1fff);
|
||||
}
|
||||
|
||||
unsigned chr_addr(unsigned addr) const {
|
||||
unsigned bank = chr_banklo[(bool)(addr & 0x1000)];
|
||||
bank |= chr_bankhi[(bool)(addr & 0x1000)] << 4;
|
||||
return (bank * 0x1000) + (addr & 0x0fff);
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) const {
|
||||
switch(mirror) {
|
||||
case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical mirroring
|
||||
case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal mirroring
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
void reg_write(unsigned addr, uint8 data) {
|
||||
switch(addr & 0xf000) {
|
||||
case 0x8000:
|
||||
prg_bank[0] = data & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x9000:
|
||||
chr_bankhi[1] = data & 0x04;
|
||||
chr_bankhi[0] = data & 0x02;
|
||||
mirror = data & 0x01;
|
||||
break;
|
||||
|
||||
case 0xa000:
|
||||
prg_bank[1] = data & 0x0f;
|
||||
break;
|
||||
|
||||
case 0xc000:
|
||||
prg_bank[2] = data & 0x0f;
|
||||
break;
|
||||
|
||||
case 0xe000:
|
||||
chr_banklo[0] = data & 0x0f;
|
||||
break;
|
||||
|
||||
case 0xf000:
|
||||
chr_banklo[1] = data & 0x0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
for(auto &n : prg_bank) n = 0;
|
||||
for(auto &n : chr_banklo) n = 0;
|
||||
for(auto &n : chr_bankhi) n = 0;
|
||||
mirror = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
for(auto &n : prg_bank) s.integer(n);
|
||||
for(auto &n : chr_banklo) s.integer(n);
|
||||
for(auto &n : chr_bankhi) s.integer(n);
|
||||
s.integer(mirror);
|
||||
}
|
||||
|
||||
VRC1(Board &board) : Chip(board) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,110 +0,0 @@
|
||||
struct VRC2 : Chip {
|
||||
|
||||
uint5 prg_bank[2];
|
||||
uint8 chr_bank[8];
|
||||
uint2 mirror;
|
||||
bool latch;
|
||||
|
||||
unsigned prg_addr(unsigned addr) const {
|
||||
unsigned bank;
|
||||
switch(addr & 0xe000) {
|
||||
case 0x8000: bank = prg_bank[0]; break;
|
||||
case 0xa000: bank = prg_bank[1]; break;
|
||||
case 0xc000: bank = 0x1e; break;
|
||||
case 0xe000: bank = 0x1f; break;
|
||||
}
|
||||
return (bank * 0x2000) + (addr & 0x1fff);
|
||||
}
|
||||
|
||||
unsigned chr_addr(unsigned addr) const {
|
||||
unsigned bank = chr_bank[addr / 0x0400];
|
||||
return (bank * 0x0400) + (addr & 0x03ff);
|
||||
}
|
||||
|
||||
unsigned ciram_addr(unsigned addr) const {
|
||||
switch(mirror) {
|
||||
case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical mirroring
|
||||
case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal mirroring
|
||||
case 2: return 0x0000 | (addr & 0x03ff); //one-screen mirroring (first)
|
||||
case 3: return 0x0400 | (addr & 0x03ff); //one-screen mirroring (second)
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
uint8 ram_read(unsigned addr) {
|
||||
if(board.prgram.size == 0) {
|
||||
if((addr & 0xf000) == 0x6000) return cpu.mdr() | latch;
|
||||
return cpu.mdr();
|
||||
}
|
||||
return board.prgram.read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
void ram_write(unsigned addr, uint8 data) {
|
||||
if(board.prgram.size == 0) {
|
||||
if((addr & 0xf000) == 0x6000) latch = data & 0x01;
|
||||
return;
|
||||
}
|
||||
return board.prgram.write(addr & 0x1fff, data);
|
||||
}
|
||||
|
||||
void reg_write(unsigned addr, uint8 data) {
|
||||
switch(addr) {
|
||||
case 0x8000: case 0x8001: case 0x8002: case 0x8003:
|
||||
prg_bank[0] = data & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x9000: case 0x9001: case 0x9002: case 0x9003:
|
||||
mirror = data & 0x03;
|
||||
break;
|
||||
|
||||
case 0xa000: case 0xa001: case 0xa002: case 0xa003:
|
||||
prg_bank[1] = data & 0x1f;
|
||||
break;
|
||||
|
||||
case 0xb000: chr_bank[0] = (chr_bank[0] & 0xf0) | ((data & 0x0f) << 0); break;
|
||||
case 0xb001: chr_bank[0] = (chr_bank[0] & 0x0f) | ((data & 0x0f) << 4); break;
|
||||
|
||||
case 0xb002: chr_bank[1] = (chr_bank[1] & 0xf0) | ((data & 0x0f) << 0); break;
|
||||
case 0xb003: chr_bank[1] = (chr_bank[1] & 0x0f) | ((data & 0x0f) << 4); break;
|
||||
|
||||
case 0xc000: chr_bank[2] = (chr_bank[2] & 0xf0) | ((data & 0x0f) << 0); break;
|
||||
case 0xc001: chr_bank[2] = (chr_bank[2] & 0x0f) | ((data & 0x0f) << 4); break;
|
||||
|
||||
case 0xc002: chr_bank[3] = (chr_bank[3] & 0xf0) | ((data & 0x0f) << 0); break;
|
||||
case 0xc003: chr_bank[3] = (chr_bank[3] & 0x0f) | ((data & 0x0f) << 4); break;
|
||||
|
||||
case 0xd000: chr_bank[4] = (chr_bank[4] & 0xf0) | ((data & 0x0f) << 0); break;
|
||||
case 0xd001: chr_bank[4] = (chr_bank[4] & 0x0f) | ((data & 0x0f) << 4); break;
|
||||
|
||||
case 0xd002: chr_bank[5] = (chr_bank[5] & 0xf0) | ((data & 0x0f) << 0); break;
|
||||
case 0xd003: chr_bank[5] = (chr_bank[5] & 0x0f) | ((data & 0x0f) << 4); break;
|
||||
|
||||
case 0xe000: chr_bank[6] = (chr_bank[6] & 0xf0) | ((data & 0x0f) << 0); break;
|
||||
case 0xe001: chr_bank[6] = (chr_bank[6] & 0x0f) | ((data & 0x0f) << 4); break;
|
||||
|
||||
case 0xe002: chr_bank[7] = (chr_bank[7] & 0xf0) | ((data & 0x0f) << 0); break;
|
||||
case 0xe003: chr_bank[7] = (chr_bank[7] & 0x0f) | ((data & 0x0f) << 4); break;
|
||||
}
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
for(auto &n : prg_bank) n = 0;
|
||||
for(auto &n : chr_bank) n = 0;
|
||||
mirror = 0;
|
||||
latch = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
for(auto &n : prg_bank) s.integer(n);
|
||||
for(auto &n : chr_bank) s.integer(n);
|
||||
s.integer(mirror);
|
||||
s.integer(latch);
|
||||
}
|
||||
|
||||
VRC2(Board &board) : Chip(board) {
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,100 +0,0 @@
|
||||
struct VRC3 : Chip {
|
||||
|
||||
uint4 prg_bank;
|
||||
bool irq_mode;
|
||||
bool irq_enable;
|
||||
bool irq_acknowledge;
|
||||
uint16 irq_latch;
|
||||
struct {
|
||||
union {
|
||||
uint16 w;
|
||||
struct { uint8 order_lsb2(l, h); };
|
||||
};
|
||||
} irq_counter;
|
||||
bool irq_line;
|
||||
|
||||
void main() {
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
if(irq_enable) {
|
||||
if(irq_mode == 0) { //16-bit
|
||||
if(++irq_counter.w == 0) {
|
||||
irq_line = 1;
|
||||
irq_enable = irq_acknowledge;
|
||||
irq_counter.w = irq_latch;
|
||||
}
|
||||
}
|
||||
if(irq_mode == 1) { //8-bit
|
||||
if(++irq_counter.l == 0) {
|
||||
irq_line = 1;
|
||||
irq_enable = irq_acknowledge;
|
||||
irq_counter.l = irq_latch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cpu.set_irq_line(irq_line);
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned prg_addr(unsigned addr) const {
|
||||
unsigned bank = (addr < 0xc000 ? (unsigned)prg_bank : 0x0f);
|
||||
return (bank * 0x4000) + (addr & 0x3fff);
|
||||
}
|
||||
|
||||
void reg_write(unsigned addr, uint8 data) {
|
||||
switch(addr & 0xf000) {
|
||||
case 0x8000: irq_latch = (irq_latch & 0xfff0) | ((data & 0x0f) << 0); break;
|
||||
case 0x9000: irq_latch = (irq_latch & 0xff0f) | ((data & 0x0f) << 4); break;
|
||||
case 0xa000: irq_latch = (irq_latch & 0xf0ff) | ((data & 0x0f) << 8); break;
|
||||
case 0xb000: irq_latch = (irq_latch & 0x0fff) | ((data & 0x0f) << 12); break;
|
||||
|
||||
case 0xc000:
|
||||
irq_mode = data & 0x04;
|
||||
irq_enable = data & 0x02;
|
||||
irq_acknowledge = data & 0x01;
|
||||
if(irq_enable) irq_counter.w = irq_latch;
|
||||
break;
|
||||
|
||||
case 0xd000:
|
||||
irq_line = 0;
|
||||
irq_enable = irq_acknowledge;
|
||||
break;
|
||||
|
||||
case 0xf000:
|
||||
prg_bank = data & 0x0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void power() {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
prg_bank = 0;
|
||||
irq_mode = 0;
|
||||
irq_enable = 0;
|
||||
irq_acknowledge = 0;
|
||||
irq_latch = 0;
|
||||
irq_counter.w = 0;
|
||||
irq_line = 0;
|
||||
}
|
||||
|
||||
void serialize(serializer &s) {
|
||||
s.integer(prg_bank);
|
||||
s.integer(irq_mode);
|
||||
s.integer(irq_enable);
|
||||
s.integer(irq_acknowledge);
|
||||
s.integer(irq_latch);
|
||||
s.integer(irq_counter.w);
|
||||
s.integer(irq_line);
|
||||
}
|
||||
|
||||
VRC3(Board &board) : Chip(board) {
|
||||
}
|
||||
|
||||
};
|
||||
Loaded 100 of 1501 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user