mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-08 01:08:24 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbc77a6cf2 | ||
|
|
ebb9367c68 | ||
|
|
96fe8f760d | ||
|
|
8abd1b2dfe | ||
|
|
f6efcbe6fd | ||
|
|
36859ea52c | ||
|
|
64589148d4 | ||
|
|
89ae1101ee | ||
|
|
340d86845a | ||
|
|
b895f29bed | ||
|
|
1ef279cb83 | ||
|
|
0241dd78b7 | ||
|
|
a13c3aece6 | ||
|
|
20977817ae | ||
|
|
ba25c82939 | ||
|
|
3babe932fd | ||
|
|
6bdeaef0f4 | ||
|
|
9e3827e2a2 | ||
|
|
e499670ad9 | ||
|
|
805398e5a8 | ||
|
|
7e6e3e3a69 | ||
|
|
16ba1d1191 | ||
|
|
29c871ef62 | ||
|
|
42f1d08c02 | ||
|
|
521f4f6952 | ||
|
|
92cfb1268a | ||
|
|
4d922ba17c | ||
|
|
3b2918791c | ||
|
|
b7d34a8aa3 | ||
|
|
8fd90cc123 | ||
|
|
e651beb72e | ||
|
|
4cbba77fc7 | ||
|
|
1194d3f9dc | ||
|
|
89a1b3d65f | ||
|
|
5a82cdf978 | ||
|
|
52be510d2b | ||
|
|
8b7219bdef | ||
|
|
926ffd9695 | ||
|
|
a1389a2ba3 | ||
|
|
5263ffb7aa | ||
|
|
1744bcb99c | ||
|
|
6362044c05 | ||
|
|
319b244af4 | ||
|
|
a3f1802845 | ||
|
|
4370acae2e | ||
|
|
5a804eac58 | ||
|
|
3b65b50aea | ||
|
|
a85ff8c437 | ||
|
|
a15d15047c | ||
|
|
f77aca7172 | ||
|
|
c32195cbd6 | ||
|
|
161366df9b | ||
|
|
4c43e85141 | ||
|
|
9da42c18c3 | ||
|
|
d115c7f6aa | ||
|
|
2efce0fd83 | ||
|
|
f6732133e7 | ||
|
|
95547f4ff8 | ||
|
|
4f5bdfe347 | ||
|
|
49b0bed1a6 | ||
|
|
1554170312 | ||
|
|
ec137d6fb9 | ||
|
|
aee683a475 | ||
|
|
cdbf07b642 | ||
|
|
8a857dada3 | ||
|
|
ab1975a6cb | ||
|
|
476a1c819a | ||
|
|
42d3f2a37f | ||
|
|
c58e3af1b5 | ||
|
|
8226e243b8 | ||
|
|
9ab3fa6227 | ||
|
|
85fa3cc968 | ||
|
|
d1fcddee9c | ||
|
|
9fd379613a | ||
|
|
aabf52d678 | ||
|
|
c9ca01fe20 | ||
|
|
becf122aaa | ||
|
|
1e130d7872 | ||
|
|
c57c733d7d | ||
|
|
e41aa25887 | ||
|
|
435f7d4371 | ||
|
|
a1980fab09 | ||
|
|
ebb234ba5f | ||
|
|
2cc7fe30b4 | ||
|
|
5c3c872b78 | ||
|
|
36bf915244 | ||
|
|
045a0f7e79 | ||
|
|
a209e6ffbe | ||
|
|
3bf672dd97 | ||
|
|
157ddf3e8f | ||
|
|
ea23bf53ae | ||
|
|
d4598e1d01 | ||
|
|
f9a8564af0 | ||
|
|
6d66b1136d | ||
|
|
b01f18c34c | ||
|
|
1ebdb69516 | ||
|
|
add0f74387 | ||
|
|
b20f70f333 | ||
|
|
9aebf7bc6b | ||
|
|
a7bf219d5d | ||
|
|
04118be59a | ||
|
|
f24d17859f | ||
|
|
35fd80bde7 | ||
|
|
ccf1c00b58 | ||
|
|
f4520d41ec | ||
|
|
e308cf4275 | ||
|
|
192e53bb87 | ||
|
|
0ed9edfcdb | ||
|
|
764fe1974a | ||
|
|
a55d640459 | ||
|
|
6010bffe5d | ||
|
|
e492268025 | ||
|
|
a36c26c997 | ||
|
|
a3945e5772 | ||
|
|
6b6233b3af | ||
|
|
9f63cb1b99 | ||
|
|
49c39e0e4d | ||
|
|
7dec0b2a3c | ||
|
|
f288280ceb | ||
|
|
c6c5f4669c | ||
|
|
397b9c4505 | ||
|
|
7e2cfb6d40 | ||
|
|
970dcea0ac | ||
|
|
402c146a53 | ||
|
|
a471c150c9 | ||
|
|
ea38ea2537 | ||
|
|
09b326ae86 | ||
|
|
a60f667b25 |
No files matched your search
@@ -1,43 +0,0 @@
|
||||
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
|
||||
@@ -1,314 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "spc700.h"
|
||||
extern sony_spc700 *spc700;
|
||||
extern debugstate debugger;
|
||||
|
||||
char __disas_spc700_str[256];
|
||||
|
||||
word __disas_spc700_relb(byte arg, byte offset) {
|
||||
word r = spc700->regs.pc + (signed char)arg;
|
||||
r += offset;
|
||||
return r;
|
||||
}
|
||||
|
||||
void __disas_spc700_op(byte op, byte op0, byte op1) {
|
||||
char *s = (char*)__disas_spc700_str;
|
||||
word opw = (op1 << 8) | (op0);
|
||||
switch(op) {
|
||||
case 0x00:sprintf(s, "nop");break;
|
||||
case 0x01:sprintf(s, "tcall 0");break;
|
||||
case 0x02:sprintf(s, "set0 $%0.2x", op0);break;
|
||||
case 0x03:sprintf(s, "bbs0 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x04:sprintf(s, "or a,$%0.2x", op0);break;
|
||||
case 0x05:sprintf(s, "or a,$%0.4x", opw);break;
|
||||
case 0x06:sprintf(s, "or a,(x)");break;
|
||||
case 0x07:sprintf(s, "or a,($%0.2x+x)", op0);break;
|
||||
case 0x08:sprintf(s, "or a,#$%0.2x", op0);break;
|
||||
case 0x09:sprintf(s, "or ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x0a:sprintf(s, "or1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x0b:sprintf(s, "asl $%0.2x", op0);break;
|
||||
case 0x0c:sprintf(s, "mov $%0.4x,y", opw);break;
|
||||
case 0x0d:sprintf(s, "push psw");break;
|
||||
case 0x0e:sprintf(s, "tset1 $%0.4x", opw);break;
|
||||
case 0x0f:sprintf(s, "brk");break;
|
||||
case 0x10:sprintf(s, "bpl $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x11:sprintf(s, "tcall 1");break;
|
||||
case 0x12:sprintf(s, "clr0 $%0.2x", op0);break;
|
||||
case 0x13:sprintf(s, "bbc0 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x14:sprintf(s, "or a,$%0.2x+x", op0);break;
|
||||
case 0x15:sprintf(s, "or a,$%0.4x+x", opw);break;
|
||||
case 0x16:sprintf(s, "or a,$%0.4x+y", opw);break;
|
||||
case 0x17:sprintf(s, "or a,($%0.2x)+y", op0);break;
|
||||
case 0x18:sprintf(s, "or $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x19:sprintf(s, "or (x),(y)");break;
|
||||
case 0x1a:sprintf(s, "decw $%0.2x", op0);break;
|
||||
case 0x1b:sprintf(s, "asl $%0.2x+x", op0);break;
|
||||
case 0x1c:sprintf(s, "asl a");break;
|
||||
case 0x1d:sprintf(s, "dec x");break;
|
||||
case 0x1e:sprintf(s, "cmp x,$%0.4x", opw);break;
|
||||
case 0x1f:sprintf(s, "jmp ($%0.4x+x)", opw);break;
|
||||
case 0x20:sprintf(s, "clrp");break;
|
||||
case 0x21:sprintf(s, "tcall 2");break;
|
||||
case 0x22:sprintf(s, "set1 $%0.2x", op0);break;
|
||||
case 0x23:sprintf(s, "bbs1 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x24:sprintf(s, "and a,$%0.2x", op0);break;
|
||||
case 0x25:sprintf(s, "and a,$%0.4x", opw);break;
|
||||
case 0x26:sprintf(s, "and a,(x)", op0);break;
|
||||
case 0x27:sprintf(s, "and a,($%0.2x+x)", op0);break;
|
||||
case 0x28:sprintf(s, "and a,#$%0.2x", op0);break;
|
||||
case 0x29:sprintf(s, "and ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x2a:sprintf(s, "or1 c,!$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x2b:sprintf(s, "rol $%0.2x", op0);break;
|
||||
case 0x2c:sprintf(s, "rol $%0.4x", opw);break;
|
||||
case 0x2d:sprintf(s, "push a");break;
|
||||
case 0x2e:sprintf(s, "cbne $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x2f:sprintf(s, "bra $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x30:sprintf(s, "bmi $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x31:sprintf(s, "tcall 3");break;
|
||||
case 0x32:sprintf(s, "clr1 $%0.2x", op0);break;
|
||||
case 0x33:sprintf(s, "bbc1 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x34:sprintf(s, "and a,$%0.2x+x", op0);break;
|
||||
case 0x35:sprintf(s, "and a,$%0.4x+x", opw);break;
|
||||
case 0x36:sprintf(s, "and a,$%0.4x+y", opw);break;
|
||||
case 0x37:sprintf(s, "and a,($%0.2x)+y", op0);break;
|
||||
case 0x38:sprintf(s, "and $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x39:sprintf(s, "and (x),(y)");break;
|
||||
case 0x3a:sprintf(s, "incw $%0.2x", op0);break;
|
||||
case 0x3b:sprintf(s, "rol $%0.2x+x", op0);break;
|
||||
case 0x3c:sprintf(s, "rol a");break;
|
||||
case 0x3d:sprintf(s, "inc x");break;
|
||||
case 0x3e:sprintf(s, "cmp x,$%0.2x", op0);break;
|
||||
case 0x3f:sprintf(s, "call $%0.4x", opw);break;
|
||||
case 0x40:sprintf(s, "setp");break;
|
||||
case 0x41:sprintf(s, "tcall 4");break;
|
||||
case 0x42:sprintf(s, "set2 $%0.2x", op0);break;
|
||||
case 0x43:sprintf(s, "bbs2 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x44:sprintf(s, "eor a,$%0.2x", op0);break;
|
||||
case 0x45:sprintf(s, "eor a,$%0.4x", opw);break;
|
||||
case 0x46:sprintf(s, "eor a,(x)");break;
|
||||
case 0x47:sprintf(s, "eor a,($%0.2x+x)", op0);break;
|
||||
case 0x48:sprintf(s, "eor a,#$%0.2x", op0);break;
|
||||
case 0x49:sprintf(s, "eor ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x4a:sprintf(s, "and1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x4b:sprintf(s, "lsr $%0.2x", op0);break;
|
||||
case 0x4c:sprintf(s, "lsr $%0.4x", opw);break;
|
||||
case 0x4d:sprintf(s, "push x");break;
|
||||
case 0x4e:sprintf(s, "tclr1 $%0.4x", opw);break;
|
||||
case 0x4f:sprintf(s, "pcall $%0.2x", op0);break;
|
||||
case 0x50:sprintf(s, "bvc $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x51:sprintf(s, "tcall 5");break;
|
||||
case 0x52:sprintf(s, "clr2 $%0.2x", op0);break;
|
||||
case 0x53:sprintf(s, "bbc2 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x54:sprintf(s, "eor a,$%0.2x+x", op0);break;
|
||||
case 0x55:sprintf(s, "eor a,$%0.4x+x", opw);break;
|
||||
case 0x56:sprintf(s, "eor a,$%0.4x+y", opw);break;
|
||||
case 0x57:sprintf(s, "eor a,($%0.2x)+y", op0);break;
|
||||
case 0x58:sprintf(s, "eor $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x59:sprintf(s, "eor (x),(y)", op0);break;
|
||||
case 0x5a:sprintf(s, "cmpw ya,$%0.2x", op0);break;
|
||||
case 0x5b:sprintf(s, "lsr $%0.2x+x", op0);break;
|
||||
case 0x5c:sprintf(s, "lsr a");break;
|
||||
case 0x5d:sprintf(s, "mov x,a");break;
|
||||
case 0x5e:sprintf(s, "cmp y,$%0.4x", opw);break;
|
||||
case 0x5f:sprintf(s, "jmp $%0.4x", opw);break;
|
||||
case 0x60:sprintf(s, "clrc");break;
|
||||
case 0x61:sprintf(s, "tcall 6");break;
|
||||
case 0x62:sprintf(s, "set3 $%0.2x", op0);break;
|
||||
case 0x63:sprintf(s, "bbs3 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x64:sprintf(s, "cmp a,$%0.2x", op0);break;
|
||||
case 0x65:sprintf(s, "cmp a,$%0.4x", opw);break;
|
||||
case 0x66:sprintf(s, "cmp a,(x)", op0);break;
|
||||
case 0x67:sprintf(s, "cmp a,($%0.2x+x)", op0);break;
|
||||
case 0x68:sprintf(s, "cmp a,#$%0.2x", op0);break;
|
||||
case 0x69:sprintf(s, "cmp ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x6a:sprintf(s, "and1 c,!$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x6b:sprintf(s, "ror $%0.2x", op0);break;
|
||||
case 0x6c:sprintf(s, "ror $%0.4x", opw);break;
|
||||
case 0x6d:sprintf(s, "push y");break;
|
||||
case 0x6e:sprintf(s, "dbnz $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x6f:sprintf(s, "ret");break;
|
||||
case 0x70:sprintf(s, "bvs $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x71:sprintf(s, "tcall 7");break;
|
||||
case 0x72:sprintf(s, "clr3 $%0.2x", op0);break;
|
||||
case 0x73:sprintf(s, "bbc3 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x74:sprintf(s, "cmp a,$%0.2x+x", op0);break;
|
||||
case 0x75:sprintf(s, "cmp a,$%0.4x+x", opw);break;
|
||||
case 0x76:sprintf(s, "cmp a,$%0.4x+y", opw);break;
|
||||
case 0x77:sprintf(s, "cmp a,($%0.2x)+y", op0);break;
|
||||
case 0x78:sprintf(s, "cmp $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x79:sprintf(s, "cmp (x),(y)");break;
|
||||
case 0x7a:sprintf(s, "addw ya,$%0.2x", op0);break;
|
||||
case 0x7b:sprintf(s, "ror $%0.2x+x", op0);break;
|
||||
case 0x7c:sprintf(s, "ror a");break;
|
||||
case 0x7d:sprintf(s, "mov a,x");break;
|
||||
case 0x7e:sprintf(s, "cmp y,$%0.2x", op0);break;
|
||||
case 0x7f:sprintf(s, "reti");break;
|
||||
case 0x80:sprintf(s, "setc");break;
|
||||
case 0x81:sprintf(s, "tcall 8");break;
|
||||
case 0x82:sprintf(s, "set4 $%0.2x", op0);break;
|
||||
case 0x83:sprintf(s, "bbs4 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x84:sprintf(s, "adc a,$%0.2x", op0);break;
|
||||
case 0x85:sprintf(s, "adc a,$%0.4x", opw);break;
|
||||
case 0x86:sprintf(s, "adc a,(x)", op0);break;
|
||||
case 0x87:sprintf(s, "adc a,($%0.2x+x)", op0);break;
|
||||
case 0x88:sprintf(s, "adc a,#$%0.2x", op0);break;
|
||||
case 0x89:sprintf(s, "adc ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0x8a:sprintf(s, "eor1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0x8b:sprintf(s, "dec $%0.2x", op0);break;
|
||||
case 0x8c:sprintf(s, "dec $%0.4x", opw);break;
|
||||
case 0x8d:sprintf(s, "mov y,#$%0.2x", op0);break;
|
||||
case 0x8e:sprintf(s, "pop psw");break;
|
||||
case 0x8f:sprintf(s, "mov $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x90:sprintf(s, "bcc $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0x91:sprintf(s, "tcall 9");break;
|
||||
case 0x92:sprintf(s, "clr4 $%0.2x", op0);break;
|
||||
case 0x93:sprintf(s, "bbc4 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0x94:sprintf(s, "adc a,$%0.2x+x", op0);break;
|
||||
case 0x95:sprintf(s, "adc a,$%0.4x+x", opw);break;
|
||||
case 0x96:sprintf(s, "adc a,$%0.4x+y", opw);break;
|
||||
case 0x97:sprintf(s, "adc a,($%0.2x)+y", op0);break;
|
||||
case 0x98:sprintf(s, "adc $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0x99:sprintf(s, "adc (x),(y)", op0);break;
|
||||
case 0x9a:sprintf(s, "subw ya,$%0.2x", op0);break;
|
||||
case 0x9b:sprintf(s, "dec $%0.2x+x", op0);break;
|
||||
case 0x9c:sprintf(s, "dec a");break;
|
||||
case 0x9d:sprintf(s, "mov x,sp");break;
|
||||
case 0x9e:sprintf(s, "div ya,x");break;
|
||||
case 0x9f:sprintf(s, "xcn a");break;
|
||||
case 0xa0:sprintf(s, "ei");break;
|
||||
case 0xa1:sprintf(s, "tcall 10");break;
|
||||
case 0xa2:sprintf(s, "set5 $%0.2x", op0);break;
|
||||
case 0xa3:sprintf(s, "bbs5 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xa4:sprintf(s, "sbc a,$%0.2x", op0);break;
|
||||
case 0xa5:sprintf(s, "sbc a,$%0.4x", opw);break;
|
||||
case 0xa6:sprintf(s, "sbc a,(x)", op0);break;
|
||||
case 0xa7:sprintf(s, "sbc a,($%0.2x+x)", op0);break;
|
||||
case 0xa8:sprintf(s, "sbc a,#$%0.2x", op0);break;
|
||||
case 0xa9:sprintf(s, "sbc ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0xaa:sprintf(s, "mov1 c,$%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0xab:sprintf(s, "inc $%0.2x", op0);break;
|
||||
case 0xac:sprintf(s, "inc $%0.4x", opw);break;
|
||||
case 0xad:sprintf(s, "cmp y,#$%0.2x", op0);break;
|
||||
case 0xae:sprintf(s, "pop a");break;
|
||||
case 0xaf:sprintf(s, "mov (x)+,a");break;
|
||||
case 0xb0:sprintf(s, "bcs $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0xb1:sprintf(s, "tcall 11");break;
|
||||
case 0xb2:sprintf(s, "clr5 $%0.2x", op0);break;
|
||||
case 0xb3:sprintf(s, "bbc5 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xb4:sprintf(s, "sbc a,$%0.2x+x", op0);break;
|
||||
case 0xb5:sprintf(s, "sbc a,$%0.4x+x", opw);break;
|
||||
case 0xb6:sprintf(s, "sbc a,$%0.4x+y", opw);break;
|
||||
case 0xb7:sprintf(s, "sbc a,($%0.2x)+y", op0);break;
|
||||
case 0xb8:sprintf(s, "sbc $%0.2x,#$%0.2x", op1, op0);break;
|
||||
case 0xb9:sprintf(s, "sbc (x),(y)", op0);break;
|
||||
case 0xba:sprintf(s, "movw ya,$%0.2x", op0);break;
|
||||
case 0xbb:sprintf(s, "inc $%0.2x+x", op0);break;
|
||||
case 0xbc:sprintf(s, "inc a");break;
|
||||
case 0xbd:sprintf(s, "mov sp,x");break;
|
||||
case 0xbe:sprintf(s, "das a");break;
|
||||
case 0xbf:sprintf(s, "mov a,(x)+");break;
|
||||
case 0xc0:sprintf(s, "di");break;
|
||||
case 0xc1:sprintf(s, "tcall 12");break;
|
||||
case 0xc2:sprintf(s, "set6 $%0.2x", op0);break;
|
||||
case 0xc3:sprintf(s, "bbs6 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xc4:sprintf(s, "mov $%0.2x,a", op0);break;
|
||||
case 0xc5:sprintf(s, "mov $%0.4x,a", opw);break;
|
||||
case 0xc6:sprintf(s, "mov (x),a");break;
|
||||
case 0xc7:sprintf(s, "mov ($%0.2x+x),a", op0);break;
|
||||
case 0xc8:sprintf(s, "cmp x,#$%0.2x", op0);break;
|
||||
case 0xc9:sprintf(s, "mov $%0.4x,x", opw);break;
|
||||
case 0xca:sprintf(s, "mov1 $%0.4x,%d,c", opw & 0x1fff, opw >> 13);break;
|
||||
case 0xcb:sprintf(s, "mov $%0.2x,y", op0);break;
|
||||
case 0xcc:sprintf(s, "asl $%0.4x", opw);break;
|
||||
case 0xcd:sprintf(s, "mov x,#$%0.2x", op0);break;
|
||||
case 0xce:sprintf(s, "pop x");break;
|
||||
case 0xcf:sprintf(s, "mul ya");break;
|
||||
case 0xd0:sprintf(s, "bne $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0xd1:sprintf(s, "tcall 13");break;
|
||||
case 0xd2:sprintf(s, "clr6 $%0.2x", op0);break;
|
||||
case 0xd3:sprintf(s, "bbc6 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xd4:sprintf(s, "mov $%0.2x+x,a", op0);break;
|
||||
case 0xd5:sprintf(s, "mov $%0.4x+x,a", opw);break;
|
||||
case 0xd6:sprintf(s, "mov $%0.4x+y,a", opw);break;
|
||||
case 0xd7:sprintf(s, "mov ($%0.2x)+y,a", op0);break;
|
||||
case 0xd8:sprintf(s, "mov $%0.2x,x", op0);break;
|
||||
case 0xd9:sprintf(s, "mov $%0.2x+y,x", op0);break;
|
||||
case 0xda:sprintf(s, "movw $%0.2x,ya", op0);break;
|
||||
case 0xdb:sprintf(s, "mov $%0.2x+x,y", op0);break;
|
||||
case 0xdc:sprintf(s, "dec y");break;
|
||||
case 0xdd:sprintf(s, "mov a,y");break;
|
||||
case 0xde:sprintf(s, "cbne $%0.2x+x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xdf:sprintf(s, "daa a");break;
|
||||
case 0xe0:sprintf(s, "clrv");break;
|
||||
case 0xe1:sprintf(s, "tcall 14");break;
|
||||
case 0xe2:sprintf(s, "set7 $%0.2x", op0);break;
|
||||
case 0xe3:sprintf(s, "bbs7 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xe4:sprintf(s, "mov a,$%0.2x", op0);break;
|
||||
case 0xe5:sprintf(s, "mov a,$%0.4x", opw);break;
|
||||
case 0xe6:sprintf(s, "mov a,(x)");break;
|
||||
case 0xe7:sprintf(s, "mov a,($%0.2x+x)", op0);break;
|
||||
case 0xe8:sprintf(s, "mov a,#$%0.2x", op0);break;
|
||||
case 0xe9:sprintf(s, "mov x,$%0.4x", opw);break;
|
||||
case 0xea:sprintf(s, "not1 $%0.4x,%d", opw & 0x1fff, opw >> 13);break;
|
||||
case 0xeb:sprintf(s, "mov y,$%0.2x", op0);break;
|
||||
case 0xec:sprintf(s, "mov y,$%0.4x", opw);break;
|
||||
case 0xed:sprintf(s, "notc");break;
|
||||
case 0xee:sprintf(s, "pop y");break;
|
||||
case 0xef:sprintf(s, "sleep");break;
|
||||
case 0xf0:sprintf(s, "beq $%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0xf1:sprintf(s, "tcall 15");break;
|
||||
case 0xf2:sprintf(s, "clr7 $%0.2x", op0);break;
|
||||
case 0xf3:sprintf(s, "bbc7 $%0.2x,$%0.4x", op0, __disas_spc700_relb(op1, 3));break;
|
||||
case 0xf4:sprintf(s, "mov a,$%0.2x+x", op0);break;
|
||||
case 0xf5:sprintf(s, "mov a,$%0.4x+x", opw);break;
|
||||
case 0xf6:sprintf(s, "mov a,$%0.4x+y", opw);break;
|
||||
case 0xf7:sprintf(s, "mov a,($%0.2x)+y", op0);break;
|
||||
case 0xf8:sprintf(s, "mov x,$%0.2x", op0);break;
|
||||
case 0xf9:sprintf(s, "mov x,$%0.2x+y", op0);break;
|
||||
case 0xfa:sprintf(s, "mov ($%0.2x),($%0.2x)", op1, op0);break;
|
||||
case 0xfb:sprintf(s, "mov y,$%0.2x+x", op0);break;
|
||||
case 0xfc:sprintf(s, "inc y");break;
|
||||
case 0xfd:sprintf(s, "mov y,a");break;
|
||||
case 0xfe:sprintf(s, "dbnz y,$%0.4x", __disas_spc700_relb(op0, 2));break;
|
||||
case 0xff:sprintf(s, "stop");break;
|
||||
}
|
||||
}
|
||||
|
||||
void disas_spc700_op(void) {
|
||||
byte op;
|
||||
byte op0, op1;
|
||||
word offset;
|
||||
char flags[256];
|
||||
char *s = (char*)__disas_spc700_str;
|
||||
int i;
|
||||
if(debug_write_status() == DEBUGWRITE_NONE)return;
|
||||
|
||||
//use offset instead of spc700->regs.pc + n to avoid going above 65535
|
||||
offset = spc700->regs.pc;
|
||||
op = spc700->ram[offset++];
|
||||
op0 = spc700->ram[offset++];
|
||||
op1 = spc700->ram[offset ];
|
||||
|
||||
strcpy(__disas_spc700_str, "???");
|
||||
__disas_spc700_op(op, op0, op1);
|
||||
i = strlen(s);
|
||||
while(i < 23) {
|
||||
s[i++] = ' ';
|
||||
s[i] = 0;
|
||||
}
|
||||
|
||||
sprintf(flags, "%c%c%c%c%c%c%c%c",
|
||||
(spc700->regs.p & 0x80)?'N':'n',
|
||||
(spc700->regs.p & 0x40)?'V':'v',
|
||||
(spc700->regs.p & 0x20)?'P':'p',
|
||||
(spc700->regs.p & 0x10)?'B':'b',
|
||||
(spc700->regs.p & 0x08)?'H':'h',
|
||||
(spc700->regs.p & 0x04)?'I':'i',
|
||||
(spc700->regs.p & 0x02)?'Z':'z',
|
||||
(spc700->regs.p & 0x01)?'C':'c');
|
||||
|
||||
dprintf(DEBUGMSG_APU, "--%0.4x %s A:%0.2x X:%0.2x Y:%0.2x SP:%0.2x YA:%0.4x %s",
|
||||
spc700->regs.pc, __disas_spc700_str,
|
||||
spc700->regs.a, spc700->regs.x, spc700->regs.y, spc700->regs.sp,
|
||||
(spc700->regs.y << 8) | (spc700->regs.a), flags);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "../timing/timing.h"
|
||||
#include "../bridge/bridge.h"
|
||||
#include "spc700_iplrom.h"
|
||||
#include "spc700.h"
|
||||
|
||||
extern snes_timer *snes_time;
|
||||
extern debugstate debugger;
|
||||
extern port_bridge *cpu_apu_bridge;
|
||||
sony_spc700 *spc700;
|
||||
|
||||
#include "spc700_ops.cpp"
|
||||
|
||||
void sony_spc700::Reset(void) {
|
||||
memset(ram, 0, 65536);
|
||||
memcpy(ram + 0xffc0, spc700_iplrom, 64);
|
||||
regs.pc = 0xffc0;
|
||||
regs.a = regs.x = regs.y = regs.sp = 0x00;
|
||||
regs.p = 0x02;
|
||||
regs.dp = 0x0000;
|
||||
}
|
||||
|
||||
void sony_spc700::exec_op(void) {
|
||||
byte op;
|
||||
op = spc700->ram[spc700->regs.pc];
|
||||
spc700_optbl[op]();
|
||||
debugger.apu_op_executed = true;
|
||||
debugger.disas_apu_op = true;
|
||||
|
||||
debug_test_bp(BPSRC_SPCRAM, BP_EXEC, spc700->regs.pc, 0);
|
||||
}
|
||||
|
||||
void sony_spc700::Run(void) {
|
||||
if(snes_time->bridge.cpu_cycles >= snes_time->bridge.apu_cycles) {
|
||||
exec_op();
|
||||
}
|
||||
if(snes_time->bridge.cpu_cycles >= 65536 && snes_time->bridge.apu_cycles >= 65536) {
|
||||
snes_time->bridge.cpu_cycles &= 65535;
|
||||
snes_time->bridge.apu_cycles &= 65535;
|
||||
}
|
||||
}
|
||||
|
||||
sony_spc700::sony_spc700() {
|
||||
ram = (byte*)malloc(65536);
|
||||
}
|
||||
|
||||
sony_spc700::~sony_spc700() {
|
||||
if(ram)free(ram);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
class sony_spc700 {
|
||||
public:
|
||||
struct {
|
||||
word pc;
|
||||
byte a, x, y, sp, p;
|
||||
word dp;
|
||||
}regs;
|
||||
byte *ram;
|
||||
|
||||
void Reset(void);
|
||||
void Run(void);
|
||||
|
||||
void exec_op(void);
|
||||
word convert_address(byte mode, word addr);
|
||||
byte mem_getbyte(word addr);
|
||||
void mem_putbyte(word addr, byte value);
|
||||
word mem_read(byte mode, byte size, word addr);
|
||||
void mem_write(byte mode, byte size, word addr, word value);
|
||||
byte stack_read(void);
|
||||
void stack_write(byte value);
|
||||
|
||||
sony_spc700();
|
||||
~sony_spc700();
|
||||
};
|
||||
@@ -1,194 +0,0 @@
|
||||
#define spc700_setn() spc700->regs.p |= SPF_N
|
||||
#define spc700_clrn() spc700->regs.p &= ~SPF_N
|
||||
#define spc700_setv() spc700->regs.p |= SPF_V
|
||||
#define spc700_clrv() spc700->regs.p &= ~SPF_V
|
||||
#define spc700_setp() spc700->regs.p |= SPF_P;spc700->regs.dp = 0x0100
|
||||
#define spc700_clrp() spc700->regs.p &= ~SPF_P;spc700->regs.dp = 0x0000
|
||||
#define spc700_setb() spc700->regs.p |= SPF_B
|
||||
#define spc700_clrb() spc700->regs.p &= ~SPF_B
|
||||
#define spc700_seth() spc700->regs.p |= SPF_H
|
||||
#define spc700_clrh() spc700->regs.p &= ~SPF_H
|
||||
#define spc700_seti() spc700->regs.p |= SPF_I
|
||||
#define spc700_clri() spc700->regs.p &= ~SPF_I
|
||||
#define spc700_setz() spc700->regs.p |= SPF_Z
|
||||
#define spc700_clrz() spc700->regs.p &= ~SPF_Z
|
||||
#define spc700_setc() spc700->regs.p |= SPF_C
|
||||
#define spc700_clrc() spc700->regs.p &= ~SPF_C
|
||||
#define spc700_testn(x) if(x)spc700_setn(); else spc700_clrn()
|
||||
#define spc700_testv(x) if(x)spc700_setv(); else spc700_clrv()
|
||||
#define spc700_testp(x) if(x)spc700_setp(); else spc700_clrp()
|
||||
#define spc700_testb(x) if(x)spc700_setb(); else spc700_clrb()
|
||||
#define spc700_testh(x) if(x)spc700_seth(); else spc700_clrh()
|
||||
#define spc700_testi(x) if(x)spc700_seti(); else spc700_clri()
|
||||
#define spc700_testz(x) if(x)spc700_setz(); else spc700_clrz()
|
||||
#define spc700_testc(x) if(x)spc700_setc(); else spc700_clrc()
|
||||
|
||||
#define spc700_incpc(__n) spc700->regs.pc += __n
|
||||
|
||||
#define spc700_prefetchb() \
|
||||
byte arg = spc700->ram[(spc700->regs.pc + 1) & 0xffff]
|
||||
|
||||
#define spc700_prefetch2b() \
|
||||
byte arg0 = spc700->ram[(spc700->regs.pc + 1) & 0xffff]; \
|
||||
byte arg1 = spc700->ram[(spc700->regs.pc + 2) & 0xffff]
|
||||
|
||||
#define spc700_prefetchw() \
|
||||
word arg = spc700->ram[(spc700->regs.pc + 1) & 0xffff] | (spc700->ram[(spc700->regs.pc + 2) & 0xffff] << 8)
|
||||
|
||||
#define APUMODE_NONE 0
|
||||
#define APUMODE_DP 1
|
||||
#define APUMODE_DPX 2
|
||||
#define APUMODE_DPY 3
|
||||
#define APUMODE_IDP 4
|
||||
#define APUMODE_ADDR 5
|
||||
#define APUMODE_IX 6
|
||||
#define APUMODE_ADDRX 7
|
||||
#define APUMODE_ADDRY 8
|
||||
#define APUMODE_IDPX 9
|
||||
#define APUMODE_IDPY 10
|
||||
#define APUMODE_IADDRX 11
|
||||
#define APUMODE_IY 12
|
||||
|
||||
word sony_spc700::convert_address(byte mode, word addr) {
|
||||
word r;
|
||||
switch(mode) {
|
||||
case APUMODE_NONE:
|
||||
r = addr;
|
||||
case APUMODE_DP:
|
||||
r = spc700->regs.dp | (byte)addr;
|
||||
break;
|
||||
case APUMODE_DPX:
|
||||
r = spc700->regs.dp | (byte)(addr + spc700->regs.x);
|
||||
break;
|
||||
case APUMODE_DPY:
|
||||
r = spc700->regs.dp | (byte)(addr + spc700->regs.y);
|
||||
break;
|
||||
case APUMODE_IDP:
|
||||
r = spc700->regs.dp | (byte)addr;
|
||||
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
|
||||
break;
|
||||
case APUMODE_ADDR:
|
||||
r = addr;
|
||||
break;
|
||||
case APUMODE_IX:
|
||||
r = spc700->regs.dp | spc700->regs.x;
|
||||
break;
|
||||
case APUMODE_ADDRX:
|
||||
r = addr + spc700->regs.x;
|
||||
break;
|
||||
case APUMODE_ADDRY:
|
||||
r = addr + spc700->regs.y;
|
||||
break;
|
||||
case APUMODE_IDPX:
|
||||
r = spc700->regs.dp | (byte)(addr + spc700->regs.x);
|
||||
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
|
||||
break;
|
||||
case APUMODE_IDPY:
|
||||
r = spc700->regs.dp | (byte)addr;
|
||||
r = spc700->ram[r] | (spc700->ram[r + 1] << 8);
|
||||
r += spc700->regs.y;
|
||||
break;
|
||||
case APUMODE_IADDRX:
|
||||
r = (spc700->ram[(addr + spc700->regs.x )]) |
|
||||
(spc700->ram[(addr + spc700->regs.x + 1)] << 8);
|
||||
break;
|
||||
case APUMODE_IY:
|
||||
r = spc700->regs.dp | spc700->regs.y;
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
byte sony_spc700::mem_getbyte(word addr) {
|
||||
if(addr >= 0x00f4 && addr <= 0x00f7) {
|
||||
return cpu_apu_bridge->apu_read(addr - 0x00f4);
|
||||
} else {
|
||||
return spc700->ram[addr];
|
||||
}
|
||||
}
|
||||
|
||||
void sony_spc700::mem_putbyte(word addr, byte value) {
|
||||
if(addr >= 0x00f4 && addr <= 0x00f7) {
|
||||
cpu_apu_bridge->apu_write(addr - 0x00f4, value);
|
||||
} else if(addr < 0xffc0) {
|
||||
spc700->ram[addr] = value;
|
||||
}
|
||||
}
|
||||
|
||||
word sony_spc700::mem_read(byte mode, byte size, word addr) {
|
||||
word r;
|
||||
addr = convert_address(mode, addr);
|
||||
switch(size) {
|
||||
case MEMSIZE_BYTE:
|
||||
r = mem_getbyte(addr);
|
||||
break;
|
||||
case MEMSIZE_WORD:
|
||||
r = mem_getbyte(addr) | (mem_getbyte(addr + 1) << 8);
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void sony_spc700::mem_write(byte mode, byte size, word addr, word value) {
|
||||
addr = convert_address(mode, addr);
|
||||
switch(size) {
|
||||
case MEMSIZE_BYTE:
|
||||
mem_putbyte(addr, value);
|
||||
break;
|
||||
case MEMSIZE_WORD:
|
||||
mem_putbyte(addr , value);
|
||||
mem_putbyte(addr + 1, value >> 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
byte sony_spc700::stack_read(void) {
|
||||
word addr;
|
||||
spc700->regs.sp++;
|
||||
addr = 0x0100 | spc700->regs.sp;
|
||||
return mem_getbyte(addr);
|
||||
}
|
||||
|
||||
void sony_spc700::stack_write(byte value) {
|
||||
word addr;
|
||||
addr = 0x0100 | spc700->regs.sp;
|
||||
spc700->regs.sp--;
|
||||
mem_putbyte(addr, value);
|
||||
}
|
||||
|
||||
#include "spc700_ops_adc.cpp"
|
||||
#include "spc700_ops_and.cpp"
|
||||
#include "spc700_ops_cmp.cpp"
|
||||
#include "spc700_ops_eor.cpp"
|
||||
#include "spc700_ops_flags.cpp"
|
||||
#include "spc700_ops_incdec.cpp"
|
||||
#include "spc700_ops_misc.cpp"
|
||||
#include "spc700_ops_mov.cpp"
|
||||
#include "spc700_ops_or.cpp"
|
||||
#include "spc700_ops_pc.cpp"
|
||||
#include "spc700_ops_sbc.cpp"
|
||||
#include "spc700_ops_shift.cpp"
|
||||
#include "spc700_ops_stack.cpp"
|
||||
|
||||
vfunc spc700_optbl[256] = {
|
||||
// -----------------------------x0, -----------------------------x1, -----------------------------x2, -----------------------------x3, -------- -----------------------------x4, -----------------------------x5, -----------------------------x6, -----------------------------x7, -------- -----------------------------x8, -----------------------------x9, -----------------------------xa, -----------------------------xb, -------- -----------------------------xc, -----------------------------xd, -----------------------------xe, -----------------------------xf,
|
||||
/* 0x */ spc700_op_nop, spc700_op_tcall_0, spc700_op_set0_dp, spc700_op_bbc0, /* 0x */ spc700_op_or_a_dp, spc700_op_or_a_addr, spc700_op_or_a_ix, spc700_op_or_a_idpx, /* 0x */ spc700_op_or_a_const, spc700_op_or_dp_dp, spc700_op_or1_bit, spc700_op_asl_dp, /* 0x */ spc700_op_mov_addr_y, spc700_op_push_p, spc700_op_tset1_addr, spc700_op_brk,
|
||||
/* 1x */ spc700_op_bpl, spc700_op_tcall_1, spc700_op_clr0_dp, spc700_op_bbs0, /* 1x */ spc700_op_or_a_dpx, spc700_op_or_a_addrx, spc700_op_or_a_addry, spc700_op_or_a_idpy, /* 1x */ spc700_op_or_dp_imm, spc700_op_or_ix_iy, spc700_op_decw_dp, spc700_op_asl_dpx, /* 1x */ spc700_op_asl_a, spc700_op_dec_x, spc700_op_cmp_x_addr, spc700_op_jmp_iaddrx,
|
||||
/* 2x */ spc700_op_clrp, spc700_op_tcall_2, spc700_op_set1_dp, spc700_op_bbc1, /* 2x */ spc700_op_and_a_dp, spc700_op_and_a_addr, spc700_op_and_a_ix, spc700_op_and_a_idpx, /* 2x */ spc700_op_and_a_const, spc700_op_and_dp_dp, spc700_op_or1_notbit, spc700_op_rol_dp, /* 2x */ spc700_op_rol_addr, spc700_op_push_a, spc700_op_cbne_dp, spc700_op_bra,
|
||||
/* 3x */ spc700_op_bmi, spc700_op_tcall_3, spc700_op_clr1_dp, spc700_op_bbs1, /* 3x */ spc700_op_and_a_dpx, spc700_op_and_a_addrx, spc700_op_and_a_addry, spc700_op_and_a_idpy, /* 3x */ spc700_op_and_dp_imm, spc700_op_and_ix_iy, spc700_op_incw_dp, spc700_op_rol_dpx, /* 3x */ spc700_op_rol_a, spc700_op_inc_x, spc700_op_cmp_x_dp, spc700_op_call,
|
||||
|
||||
/* 4x */ spc700_op_setp, spc700_op_tcall_4, spc700_op_set2_dp, spc700_op_bbc2, /* 4x */ spc700_op_eor_a_dp, spc700_op_eor_a_addr, spc700_op_eor_a_ix, spc700_op_eor_a_idpx, /* 4x */ spc700_op_eor_a_const, spc700_op_eor_dp_dp, spc700_op_and1_bit, spc700_op_lsr_dp, /* 4x */ spc700_op_lsr_addr, spc700_op_push_x, spc700_op_tclr1_addr, spc700_op_pcall,
|
||||
/* 5x */ spc700_op_bvc, spc700_op_tcall_5, spc700_op_clr2_dp, spc700_op_bbs2, /* 5x */ spc700_op_eor_a_dpx, spc700_op_eor_a_addrx, spc700_op_eor_a_addry, spc700_op_eor_a_idpy, /* 5x */ spc700_op_eor_dp_imm, spc700_op_eor_ix_iy, spc700_op_cmpw_ya_dp, spc700_op_lsr_dpx, /* 5x */ spc700_op_lsr_a, spc700_op_mov_x_a, spc700_op_cmp_y_addr, spc700_op_jmp_addr,
|
||||
/* 6x */ spc700_op_clrc, spc700_op_tcall_6, spc700_op_set3_dp, spc700_op_bbc3, /* 6x */ spc700_op_cmp_a_dp, spc700_op_cmp_a_addr, spc700_op_cmp_a_ix, spc700_op_cmp_a_idpx, /* 6x */ spc700_op_cmp_a_const, spc700_op_cmp_dp_dp, spc700_op_and1_notbit, spc700_op_ror_dp, /* 6x */ spc700_op_ror_addr, spc700_op_push_y, spc700_op_dbnz_dp, spc700_op_ret,
|
||||
/* 7x */ spc700_op_bvs, spc700_op_tcall_7, spc700_op_clr3_dp, spc700_op_bbs3, /* 7x */ spc700_op_cmp_a_dpx, spc700_op_cmp_a_addrx, spc700_op_cmp_a_addry, spc700_op_cmp_a_idpy, /* 7x */ spc700_op_cmp_dp_imm, spc700_op_cmp_ix_iy, spc700_op_addw_ya_dp, spc700_op_ror_dpx, /* 7x */ spc700_op_ror_a, spc700_op_mov_a_x, spc700_op_cmp_y_dp, spc700_op_reti,
|
||||
|
||||
/* 8x */ spc700_op_setc, spc700_op_tcall_8, spc700_op_set4_dp, spc700_op_bbc4, /* 8x */ spc700_op_adc_a_dp, spc700_op_adc_a_addr, spc700_op_adc_a_ix, spc700_op_adc_a_idpx, /* 8x */ spc700_op_adc_a_const, spc700_op_adc_dp_dp, spc700_op_eor1_bit, spc700_op_dec_dp, /* 8x */ spc700_op_dec_addr, spc700_op_mov_y_const, spc700_op_pop_p, spc700_op_mov_dp_imm,
|
||||
/* 9x */ spc700_op_bcc, spc700_op_tcall_9, spc700_op_clr4_dp, spc700_op_bbs4, /* 9x */ spc700_op_adc_a_dpx, spc700_op_adc_a_addrx, spc700_op_adc_a_addry, spc700_op_adc_a_idpy, /* 9x */ spc700_op_adc_dp_imm, spc700_op_adc_ix_iy, spc700_op_subw_ya_dp, spc700_op_dec_dpx, /* 9x */ spc700_op_dec_a, spc700_op_mov_x_sp, spc700_op_div_ya_x, spc700_op_xcn_a,
|
||||
/* ax */ spc700_op_ei, spc700_op_tcall_10, spc700_op_set5_dp, spc700_op_bbc5, /* ax */ spc700_op_sbc_a_dp, spc700_op_sbc_a_addr, spc700_op_sbc_a_ix, spc700_op_sbc_a_idpx, /* ax */ spc700_op_sbc_a_const, spc700_op_sbc_dp_dp, spc700_op_mov1_c_bit, spc700_op_inc_dp, /* ax */ spc700_op_inc_addr, spc700_op_cmp_y_const, spc700_op_pop_a, spc700_op_mov_ixinc_a,
|
||||
/* bx */ spc700_op_bcs, spc700_op_tcall_11, spc700_op_clr5_dp, spc700_op_bbs5, /* bx */ spc700_op_sbc_a_dpx, spc700_op_sbc_a_addrx, spc700_op_sbc_a_addry, spc700_op_sbc_a_idpy, /* bx */ spc700_op_sbc_dp_imm, spc700_op_sbc_ix_iy, spc700_op_mov_ya_dp, spc700_op_inc_dpx, /* bx */ spc700_op_inc_a, spc700_op_mov_sp_x, spc700_op_das_a, spc700_op_mov_a_ixinc,
|
||||
|
||||
/* cx */ spc700_op_di, spc700_op_tcall_12, spc700_op_set6_dp, spc700_op_bbc6, /* cx */ spc700_op_mov_dp_a, spc700_op_mov_addr_a, spc700_op_mov_ix_a, spc700_op_mov_idpx_a, /* cx */ spc700_op_cmp_x_const, spc700_op_mov_addr_x, spc700_op_mov1_bit_c, spc700_op_mov_dp_y, /* cx */ spc700_op_asl_addr, spc700_op_mov_x_const, spc700_op_pop_x, spc700_op_mul_ya,
|
||||
/* dx */ spc700_op_bne, spc700_op_tcall_13, spc700_op_clr6_dp, spc700_op_bbs6, /* dx */ spc700_op_mov_dpx_a, spc700_op_mov_addrx_a, spc700_op_mov_addry_a, spc700_op_mov_idpy_a, /* dx */ spc700_op_mov_dp_x, spc700_op_mov_dpy_x, spc700_op_mov_dp_ya, spc700_op_mov_dpx_y, /* dx */ spc700_op_dec_y, spc700_op_mov_a_y, spc700_op_cbne_dpx, spc700_op_daa_a,
|
||||
/* ex */ spc700_op_clrv, spc700_op_tcall_14, spc700_op_set7_dp, spc700_op_bbc7, /* ex */ spc700_op_mov_a_dp, spc700_op_mov_a_addr, spc700_op_mov_a_ix, spc700_op_mov_a_idpx, /* ex */ spc700_op_mov_a_const, spc700_op_mov_x_addr, spc700_op_not1_bit, spc700_op_mov_y_dp, /* ex */ spc700_op_mov_y_addr, spc700_op_notc, spc700_op_pop_y, spc700_op_sleep,
|
||||
/* fx */ spc700_op_beq, spc700_op_tcall_15, spc700_op_clr7_dp, spc700_op_bbs7, /* fx */ spc700_op_mov_a_dpx, spc700_op_mov_a_addrx, spc700_op_mov_a_addry, spc700_op_mov_a_idpy, /* fx */ spc700_op_mov_x_dp, spc700_op_mov_x_dpy, spc700_op_mov_dp_dp, spc700_op_mov_y_dpx, /* fx */ spc700_op_inc_y, spc700_op_mov_y_a, spc700_op_dbnz_y, spc700_op_stop
|
||||
};
|
||||
@@ -1,114 +0,0 @@
|
||||
byte spc700_op_adc(byte x, byte y) {
|
||||
word r = x + y + (spc700->regs.p & SPF_C);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testv((~(x ^ y) & (y ^ (byte)r) & 0x80));
|
||||
spc700_testh((x ^ y ^ (byte)r) & 0x10);
|
||||
spc700_testz((byte)r == 0);
|
||||
spc700_testc(r >= 0x100);
|
||||
return (byte)r;
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_ix(void) {
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a += spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700->regs.a += (spc700->regs.p & PF_C);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_adc_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_adc(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_adc_ix_iy(void) {
|
||||
byte x = spc700_op_adc(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_adc_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x = spc700_op_adc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_adc_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x = spc700_op_adc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_addw_ya_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
|
||||
ulong r = ya + dp;
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testv(~(ya ^ dp) & (dp ^ (word)r) & 0x8000);
|
||||
spc700_testh((ya ^ dp ^ (word)r) & 0x1000);
|
||||
spc700_testz((word)r == 0);
|
||||
spc700_testc(r >= 0x10000);
|
||||
spc700->regs.a = r;
|
||||
spc700->regs.y = r >> 8;
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
void spc700_op_and_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a &= arg;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_ix(void) {
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_and_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a &= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_and_ix_iy(void) {
|
||||
word i;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
x &= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_and_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x &= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_and_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x &= arg0;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_and1_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
if(spc700->regs.p & SPF_C) {
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(!(x & (1 << bit))) {
|
||||
spc700_clrc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_and1_notbit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
if(spc700->regs.p & SPF_C) {
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(x & (1 << bit)) {
|
||||
spc700_clrc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
void spc700_op_cmp(byte x, byte y) {
|
||||
short r = (short)x - (short)y;
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz((byte)r == 0);
|
||||
spc700_testc(r >= 0);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_ix(void) {
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_ix_iy(void) {
|
||||
spc700_op_cmp(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
spc700_op_cmp(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
spc700_op_cmp(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_x_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.x, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_x_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.x, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_x_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.x, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_y_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.y, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_y_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700_op_cmp(spc700->regs.y, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_cmp_y_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700_op_cmp(spc700->regs.y, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_cmpw_ya_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word ya = ((spc700->regs.y << 8) | spc700->regs.a);
|
||||
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
|
||||
long r = (long)ya - (long)dp;
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testz((word)r == 0);
|
||||
spc700_testc(r >= 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
void spc700_op_eor_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a ^= arg;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_ix(void) {
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_eor_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a ^= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_eor_ix_iy(void) {
|
||||
word i;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
x ^= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_eor_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x ^= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_eor_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x ^= arg0;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_eor1_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(spc700->regs.p & SPF_C) {
|
||||
if(x & (1 << bit)) {
|
||||
spc700_clrc();
|
||||
}
|
||||
} else {
|
||||
if(x & (1 << bit)) {
|
||||
spc700_setc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_not1_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
x ^= (1 << bit);
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, addr, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
void spc700_op_clrc(void) {
|
||||
spc700_clrc();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_setc(void) {
|
||||
spc700_setc();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_notc(void) {
|
||||
spc700->regs.p ^= SPF_C;
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_clrv(void) {
|
||||
spc700_clrv();
|
||||
spc700_clrh();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_clrp(void) {
|
||||
spc700_clrp();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_setp(void) {
|
||||
spc700_setp();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_di(void) {
|
||||
spc700_clri();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_ei(void) {
|
||||
spc700_seti();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
void spc700_op_inc_a(void) {
|
||||
spc700->regs.a++;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_inc_x(void) {
|
||||
spc700->regs.x++;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_inc_y(void) {
|
||||
spc700->regs.y++;
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_inc_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg) + 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_inc_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg) + 1;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_inc_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg) + 1;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_dec_a(void) {
|
||||
spc700->regs.a--;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_dec_x(void) {
|
||||
spc700->regs.x--;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_dec_y(void) {
|
||||
spc700->regs.y--;
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_dec_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg) - 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_dec_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg) - 1;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_dec_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg) - 1;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, r);
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_incw_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg) + 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, r);
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_decw_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg) - 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, r);
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testz(r == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
void spc700_op_nop(void) {
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_sleep(void) {
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_stop(void) {
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_xcn_a(void) {
|
||||
spc700->regs.a = (spc700->regs.a >> 4) | (spc700->regs.a << 4);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_daa_a(void) {
|
||||
int a = spc700->regs.a;
|
||||
if(((a ) & 15) > 9)a += 6;
|
||||
if(((a >> 4) & 15) > 9)a += 6 << 4;
|
||||
spc700->regs.a = a;
|
||||
spc700_testn(a & 0x80);
|
||||
spc700_testz(a == 0);
|
||||
spc700_testc(a >= 0x0100);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_das_a(void) {
|
||||
int a = spc700->regs.a;
|
||||
if(((a ) & 15) > 9)a -= 6;
|
||||
if(((a >> 4) & 15) > 9)a -= 6 << 4;
|
||||
spc700->regs.a = a;
|
||||
spc700_testn(a & 0x80);
|
||||
spc700_testz(a == 0);
|
||||
spc700_testc(a < 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_set0_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x01;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr0_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x01;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set1_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x02;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr1_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x02;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set2_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x04;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr2_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x04;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set3_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x08;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr3_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x08;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set4_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x10;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr4_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x10;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set5_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x20;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr5_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x20;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set6_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x40;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr6_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x40;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_set7_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x |= 0x80;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_clr7_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
x &= ~0x80;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_tset1_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
x |= spc700->regs.a;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_tclr1_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
x &= ~spc700->regs.a;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mul_ya(void) {
|
||||
word ya;
|
||||
ya = spc700->regs.y * spc700->regs.a;
|
||||
spc700->regs.a = ya;
|
||||
spc700->regs.y = ya >> 8;
|
||||
spc700_testn(ya & 0x8000);
|
||||
spc700_testz(ya == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(9);
|
||||
}
|
||||
|
||||
/*
|
||||
v/h flags not set, may have result backwards
|
||||
(a and y may need to be swapped)
|
||||
*/
|
||||
void spc700_op_div_ya_x(void) {
|
||||
word ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
if(spc700->regs.x == 0) {
|
||||
spc700->regs.a = 0;
|
||||
spc700->regs.y = 0;
|
||||
} else {
|
||||
spc700->regs.a = ya / spc700->regs.x;
|
||||
spc700->regs.y = ya % spc700->regs.x;
|
||||
}
|
||||
ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
spc700_testn(ya & 0x8000);
|
||||
spc700_testz(ya == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(12);
|
||||
}
|
||||
@@ -1,377 +0,0 @@
|
||||
void spc700_op_mov_a_x(void) {
|
||||
spc700->regs.a = spc700->regs.x;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_y(void) {
|
||||
spc700->regs.a = spc700->regs.y;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_a(void) {
|
||||
spc700->regs.x = spc700->regs.a;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_a(void) {
|
||||
spc700->regs.y = spc700->regs.a;
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_sp(void) {
|
||||
spc700->regs.x = spc700->regs.sp;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_sp_x(void) {
|
||||
spc700->regs.sp = spc700->regs.x;
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, arg0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = arg;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.x = arg;
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.y = arg;
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_mov_ix_a(void) {
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, spc700->regs.a);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_ixinc_a(void) {
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, spc700->regs.a);
|
||||
spc700->regs.x++;
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_a(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dpx_a(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addr_a(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addrx_a(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDRX, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addry_a(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDRY, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mov_idpx_a(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->mem_write(APUMODE_IDPX, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(7);
|
||||
}
|
||||
|
||||
void spc700_op_mov_idpy_a(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->mem_write(APUMODE_IDPY, MEMSIZE_BYTE, arg, spc700->regs.a);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(7);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_x(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dpy_x(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DPY, MEMSIZE_BYTE, arg, spc700->regs.x);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addr_x(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_y(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, spc700->regs.y);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dpx_y(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, spc700->regs.y);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_addr_y(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, spc700->regs.y);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_ix(void) {
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_ixinc(void) {
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700->regs.x++;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mov_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a = spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_dpy(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.x = spc700->mem_read(APUMODE_DPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_x_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.x & 0x80);
|
||||
spc700_testz(spc700->regs.x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.y = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.y = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_y_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.y = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.y & 0x80);
|
||||
spc700_testz(spc700->regs.y == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov_ya_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word ya;
|
||||
ya = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
|
||||
spc700->regs.a = ya;
|
||||
spc700->regs.y = ya >> 8;
|
||||
spc700_testn(ya & 0x8000);
|
||||
spc700_testz(ya == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_mov_dp_ya(void) {
|
||||
spc700_prefetchb();
|
||||
word ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_WORD, arg, ya);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov1_c_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
spc700_testc(x & (1 << bit));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_mov1_bit_c(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(spc700->regs.p & SPF_C) {
|
||||
x |= (1 << bit);
|
||||
} else {
|
||||
x &= ~(1 << bit);
|
||||
}
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, addr, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
void spc700_op_or_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a |= arg;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_ix(void) {
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_or_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a |= spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg);
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_or_ix_iy(void) {
|
||||
word i;
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0);
|
||||
x |= spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0);
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x |= spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_or_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x;
|
||||
x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1);
|
||||
x |= arg0;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or1_bit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
if(!(spc700->regs.p & SPF_C)) {
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(x & (1 << bit)) {
|
||||
spc700_setc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_or1_notbit(void) {
|
||||
spc700_prefetchw();
|
||||
word addr = arg & 0x1fff;
|
||||
byte bit = arg >> 13;
|
||||
byte x;
|
||||
if(!(spc700->regs.p & SPF_C)) {
|
||||
x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, addr);
|
||||
if(!(x & (1 << bit))) {
|
||||
spc700_setc();
|
||||
}
|
||||
}
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -1,342 +0,0 @@
|
||||
void spc700_op_bra(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_bcc(void) {
|
||||
spc700_prefetchb();
|
||||
if(!(spc700->regs.p & SPF_C)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bcs(void) {
|
||||
spc700_prefetchb();
|
||||
if((spc700->regs.p & SPF_C)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_beq(void) {
|
||||
spc700_prefetchb();
|
||||
if((spc700->regs.p & SPF_Z)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bmi(void) {
|
||||
spc700_prefetchb();
|
||||
if((spc700->regs.p & SPF_N)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bne(void) {
|
||||
spc700_prefetchb();
|
||||
if(!(spc700->regs.p & SPF_Z)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bpl(void) {
|
||||
spc700_prefetchb();
|
||||
if(!(spc700->regs.p & SPF_N)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bvc(void) {
|
||||
spc700_prefetchb();
|
||||
if(!(spc700->regs.p & SPF_V)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_bvs(void) {
|
||||
spc700_prefetchb();
|
||||
if((spc700->regs.p & SPF_V)) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(4);
|
||||
} else {
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
#define spc700_op_bbc(__n) \
|
||||
void spc700_op_bbc##__n##(void) { \
|
||||
spc700_prefetch2b(); \
|
||||
byte r; \
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0); \
|
||||
if(!(r & (1 << __n))) { \
|
||||
spc700->regs.pc += (signed char)arg1; \
|
||||
add_apu_cycles(7); \
|
||||
} else { \
|
||||
add_apu_cycles(5); \
|
||||
} \
|
||||
spc700_incpc(3); \
|
||||
}
|
||||
|
||||
#define spc700_op_bbs(__n) \
|
||||
void spc700_op_bbs##__n##(void) { \
|
||||
spc700_prefetch2b(); \
|
||||
byte r; \
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0); \
|
||||
if(r & (1 << __n)) { \
|
||||
spc700->regs.pc += (signed char)arg1; \
|
||||
add_apu_cycles(7); \
|
||||
} else { \
|
||||
add_apu_cycles(5); \
|
||||
} \
|
||||
spc700_incpc(3); \
|
||||
}
|
||||
|
||||
spc700_op_bbc(0)
|
||||
spc700_op_bbc(1)
|
||||
spc700_op_bbc(2)
|
||||
spc700_op_bbc(3)
|
||||
spc700_op_bbc(4)
|
||||
spc700_op_bbc(5)
|
||||
spc700_op_bbc(6)
|
||||
spc700_op_bbc(7)
|
||||
|
||||
spc700_op_bbs(0)
|
||||
spc700_op_bbs(1)
|
||||
spc700_op_bbs(2)
|
||||
spc700_op_bbs(3)
|
||||
spc700_op_bbs(4)
|
||||
spc700_op_bbs(5)
|
||||
spc700_op_bbs(6)
|
||||
spc700_op_bbs(7)
|
||||
|
||||
void spc700_op_cbne_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0);
|
||||
if(r != spc700->regs.a) {
|
||||
spc700->regs.pc += (signed char)arg1;
|
||||
add_apu_cycles(7);
|
||||
} else {
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
spc700_incpc(3);
|
||||
}
|
||||
|
||||
void spc700_op_cbne_dpx(void) {
|
||||
spc700_prefetch2b();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg0);
|
||||
if(r != spc700->regs.a) {
|
||||
spc700->regs.pc += (signed char)arg1;
|
||||
add_apu_cycles(8);
|
||||
} else {
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
spc700_incpc(3);
|
||||
}
|
||||
|
||||
void spc700_op_dbnz_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte r;
|
||||
r = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0) - 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg0, r);
|
||||
if(r != 0) {
|
||||
spc700->regs.pc += (signed char)arg1;
|
||||
add_apu_cycles(7);
|
||||
} else {
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
spc700_incpc(3);
|
||||
}
|
||||
|
||||
void spc700_op_dbnz_y(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.y--;
|
||||
if(spc700->regs.y != 0) {
|
||||
spc700->regs.pc += (signed char)arg;
|
||||
add_apu_cycles(6);
|
||||
} else {
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
spc700_incpc(2);
|
||||
}
|
||||
|
||||
void spc700_op_jmp_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.pc = arg;
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_jmp_iaddrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.pc = spc700->mem_read(APUMODE_IADDRX, MEMSIZE_WORD, arg);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_call(void) {
|
||||
spc700_prefetchw();
|
||||
word r = spc700->regs.pc + 3;
|
||||
spc700_incpc(3);
|
||||
spc700->stack_write(r);
|
||||
spc700->stack_write(r >> 8);
|
||||
spc700->regs.pc = arg;
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_pcall(void) {
|
||||
spc700_prefetchb();
|
||||
word r = spc700->regs.pc + 2;
|
||||
spc700->stack_write(r);
|
||||
spc700->stack_write(r >> 8);
|
||||
spc700->regs.pc = 0xff00 | arg;
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_0(void) {
|
||||
dprintf("* spc700 opcode tcall 0 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_1(void) {
|
||||
dprintf("* spc700 opcode tcall 1 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_2(void) {
|
||||
dprintf("* spc700 opcode tcall 2 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_3(void) {
|
||||
dprintf("* spc700 opcode tcall 3 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_4(void) {
|
||||
dprintf("* spc700 opcode tcall 4 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_5(void) {
|
||||
dprintf("* spc700 opcode tcall 5 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_6(void) {
|
||||
dprintf("* spc700 opcode tcall 6 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_7(void) {
|
||||
dprintf("* spc700 opcode tcall 7 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_8(void) {
|
||||
dprintf("* spc700 opcode tcall 8 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_9(void) {
|
||||
dprintf("* spc700 opcode tcall 9 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_10(void) {
|
||||
dprintf("* spc700 opcode tcall 10 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_11(void) {
|
||||
dprintf("* spc700 opcode tcall 11 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_12(void) {
|
||||
dprintf("* spc700 opcode tcall 12 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_13(void) {
|
||||
dprintf("* spc700 opcode tcall 13 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_14(void) {
|
||||
dprintf("* spc700 opcode tcall 14 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_tcall_15(void) {
|
||||
dprintf("* spc700 opcode tcall 15 not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_brk(void) {
|
||||
dprintf("* spc700 opcode brk not implemented");
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(8);
|
||||
}
|
||||
|
||||
void spc700_op_ret(void) {
|
||||
word r;
|
||||
r = spc700->stack_read();
|
||||
r |= spc700->stack_read() << 8;
|
||||
spc700->regs.pc = r;
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_reti(void) {
|
||||
word r;
|
||||
spc700->regs.p = spc700->stack_read();
|
||||
r = spc700->stack_read();
|
||||
r |= spc700->stack_read() << 8;
|
||||
spc700->regs.pc = r;
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
byte spc700_op_sbc(byte x, byte y) {
|
||||
short r = (short)x - (short)y - (short)(!(spc700->regs.p & SPF_C));
|
||||
spc700_testn(r & 0x80);
|
||||
spc700_testv(((x ^ y) & 0x80) && ((x ^ (byte)r) & 0x80));
|
||||
spc700_testh(((x ^ y ^ (byte)r) & 0x10) == 0);
|
||||
spc700_testz((byte)r == 0);
|
||||
spc700_testc(r >= 0);
|
||||
return (byte)r;
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_const(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, arg);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_ix(void) {
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0));
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_dp(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(3);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_addr(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_addrx(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_addry(void) {
|
||||
spc700_prefetchw();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_ADDRY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_idpx(void) {
|
||||
spc700_prefetchb();
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IDPX, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_a_idpy(void) {
|
||||
spc700_prefetchb();
|
||||
word i;
|
||||
spc700->regs.a = spc700_op_sbc(spc700->regs.a, spc700->mem_read(APUMODE_IDPY, MEMSIZE_BYTE, arg));
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_ix_iy(void) {
|
||||
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_IX, MEMSIZE_BYTE, 0), spc700->mem_read(APUMODE_IY, MEMSIZE_BYTE, 0));
|
||||
spc700->mem_write(APUMODE_IX, MEMSIZE_BYTE, 0, x);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_dp_dp(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg0));
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(6);
|
||||
}
|
||||
|
||||
void spc700_op_sbc_dp_imm(void) {
|
||||
spc700_prefetch2b();
|
||||
byte x = spc700_op_sbc(spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg1), arg0);
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg1, x);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_subw_ya_dp(void) {
|
||||
spc700_prefetchb();
|
||||
word ya = (spc700->regs.y << 8) | spc700->regs.a;
|
||||
word dp = spc700->mem_read(APUMODE_DP, MEMSIZE_WORD, arg);
|
||||
long r = (long)ya - (long)dp;
|
||||
spc700_testn(r & 0x8000);
|
||||
spc700_testv(((ya ^ dp) & 0x8000) && ((ya ^ (word)r) & 0x8000));
|
||||
spc700_testh(((ya ^ dp ^ (word)r) & 0x1000) == 0);
|
||||
spc700_testz((word)r == 0);
|
||||
spc700_testc(r >= 0);
|
||||
spc700->regs.a = r;
|
||||
spc700->regs.y = r >> 8;
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
void spc700_op_asl_a(void) {
|
||||
spc700_testc(spc700->regs.a & 0x80);
|
||||
spc700->regs.a <<= 1;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_asl_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_asl_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_asl_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_lsr_a(void) {
|
||||
spc700_testc(spc700->regs.a & 0x01);
|
||||
spc700->regs.a >>= 1;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_lsr_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_lsr_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_lsr_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_rol_a(void) {
|
||||
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
|
||||
spc700_testc(spc700->regs.a & 0x80);
|
||||
spc700->regs.a <<= 1;
|
||||
spc700->regs.a |= c;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_rol_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_rol_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_rol_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x80:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x80);
|
||||
x <<= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_ror_a(void) {
|
||||
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
|
||||
spc700_testc(spc700->regs.a & 0x01);
|
||||
spc700->regs.a >>= 1;
|
||||
spc700->regs.a |= c;
|
||||
spc700_testn(spc700->regs.a & 0x80);
|
||||
spc700_testz(spc700->regs.a == 0);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(2);
|
||||
}
|
||||
|
||||
void spc700_op_ror_dp(void) {
|
||||
spc700_prefetchb();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_DP, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_DP, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_ror_dpx(void) {
|
||||
spc700_prefetchb();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_DPX, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_DPX, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(2);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
|
||||
void spc700_op_ror_addr(void) {
|
||||
spc700_prefetchw();
|
||||
byte c = (spc700->regs.p & SPF_C)?0x01:0x00;
|
||||
byte x = spc700->mem_read(APUMODE_ADDR, MEMSIZE_BYTE, arg);
|
||||
spc700_testc(x & 0x01);
|
||||
x >>= 1;
|
||||
x |= c;
|
||||
spc700->mem_write(APUMODE_ADDR, MEMSIZE_BYTE, arg, x);
|
||||
spc700_testn(x & 0x80);
|
||||
spc700_testz(x == 0);
|
||||
spc700_incpc(3);
|
||||
add_apu_cycles(5);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
void spc700_op_push_a(void) {
|
||||
spc700->stack_write(spc700->regs.a);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_push_x(void) {
|
||||
spc700->stack_write(spc700->regs.x);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_push_y(void) {
|
||||
spc700->stack_write(spc700->regs.y);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_push_p(void) {
|
||||
spc700->stack_write(spc700->regs.p);
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_pop_a(void) {
|
||||
spc700->regs.a = spc700->stack_read();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_pop_x(void) {
|
||||
spc700->regs.x = spc700->stack_read();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_pop_y(void) {
|
||||
spc700->regs.y = spc700->stack_read();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
}
|
||||
|
||||
void spc700_op_pop_p(void) {
|
||||
spc700->regs.p = spc700->stack_read();
|
||||
spc700_incpc(1);
|
||||
add_apu_cycles(4);
|
||||
spc700->regs.dp = (spc700->regs.p & SPF_P)?0x0100:0x0000;
|
||||
}
|
||||
-424
@@ -1,424 +0,0 @@
|
||||
#define NO_SPC700
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#define null 0xffffffff
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned long ulong;
|
||||
typedef void (*vfunc)(void);
|
||||
|
||||
#define SH_2 1
|
||||
#define SH_4 2
|
||||
#define SH_8 3
|
||||
#define SH_16 4
|
||||
#define SH_32 5
|
||||
#define SH_64 6
|
||||
#define SH_128 7
|
||||
#define SH_256 8
|
||||
#define SH_512 9
|
||||
#define SH_1024 10
|
||||
#define SH_2048 11
|
||||
#define SH_4096 12
|
||||
|
||||
/*************************
|
||||
*** general functions ***
|
||||
************************/
|
||||
|
||||
void alert(char *s, ...);
|
||||
|
||||
/************************
|
||||
*** joypad functions ***
|
||||
***********************/
|
||||
|
||||
void UpdateJoypad(void);
|
||||
|
||||
typedef struct {
|
||||
byte a, b, x, y;
|
||||
byte l, r;
|
||||
byte select, start;
|
||||
byte up, down, left, right;
|
||||
|
||||
byte read_pos;
|
||||
}joypad_state;
|
||||
|
||||
/******************
|
||||
*** deprecated ***
|
||||
*****************/
|
||||
|
||||
typedef struct {
|
||||
bool rom_loaded;
|
||||
ulong sram_save_tick_count;
|
||||
char rom_name[4096], sram_name[4096];
|
||||
}emustate;
|
||||
|
||||
/***********************
|
||||
*** video functions ***
|
||||
**********************/
|
||||
|
||||
void video_setmode(bool fullscreen, word width, word height);
|
||||
void video_setsnesmode(void);
|
||||
|
||||
#define LINE_DOUBLEWIDTH 1
|
||||
#define LINE_DOUBLEHEIGHT 2
|
||||
|
||||
//global export: render
|
||||
typedef struct {
|
||||
word display_width, display_height;
|
||||
word snes_width, snes_height;
|
||||
bool fullscreen;
|
||||
bool show_menu;
|
||||
|
||||
byte frame_skip;
|
||||
byte frame_count;
|
||||
|
||||
bool bg1_enabled[3], bg2_enabled[3], bg3_enabled[3], bg4_enabled[3], oam_enabled[5];
|
||||
|
||||
byte line[239];
|
||||
}videostate;
|
||||
|
||||
/***************************
|
||||
*** debugging functions ***
|
||||
**************************/
|
||||
|
||||
#define DEBUGMSG_INFO 0
|
||||
#define DEBUGMSG_CPU 1
|
||||
#define DEBUGMSG_APU 2
|
||||
|
||||
#define DEBUGWRITE_NONE 0
|
||||
#define DEBUGWRITE_CONSOLE 1
|
||||
#define DEBUGWRITE_TRACE 2
|
||||
|
||||
enum {
|
||||
DEBUGMODE_DISABLED = 0,
|
||||
DEBUGMODE_WAIT,
|
||||
DEBUGMODE_RUN,
|
||||
DEBUGMODE_CPUSTEP,
|
||||
DEBUGMODE_APUSTEP,
|
||||
DEBUGMODE_PROCEED
|
||||
};
|
||||
|
||||
#define DEBUG_BGENABLED_ALL 0
|
||||
#define DEBUG_BGENABLED_PRI0 1
|
||||
#define DEBUG_BGENABLED_PRI1 2
|
||||
#define DEBUG_BGENABLED_PRI2 3
|
||||
#define DEBUG_BGENABLED_PRI3 4
|
||||
|
||||
#define BP_OFF 0
|
||||
#define BP_READ 1
|
||||
#define BP_WRITE 2
|
||||
#define BP_EXEC 4
|
||||
#define BP_VAL 8
|
||||
|
||||
#define BPSRC_MEM 0
|
||||
#define BPSRC_VRAM 1
|
||||
#define BPSRC_CGRAM 2
|
||||
#define BPSRC_OAM 3
|
||||
#define BPSRC_SPCRAM 4
|
||||
|
||||
void debug_test_breakpoint(byte source, byte flag, ulong offset, byte value);
|
||||
#define debug_get_state() debugger.mode
|
||||
#define debugger_enabled() ((debugger.mode == DEBUGMODE_DISABLED)?false:true)
|
||||
#define debug_test_bp(__source, __flag, __offset, __value) \
|
||||
if(debug_get_state() != DEBUGMODE_DISABLED) { \
|
||||
debug_test_breakpoint(__source, __flag, __offset, __value); \
|
||||
}
|
||||
void debug_set_state(byte state);
|
||||
void dprintf(char *s, ...);
|
||||
void dprintf(ulong msg_type, char *s, ...);
|
||||
void debug_refresh_mem(void);
|
||||
void debug_refresh_bp(void);
|
||||
void debug_update_status(void);
|
||||
ulong debug_write_status(void);
|
||||
|
||||
typedef struct {
|
||||
byte mode;
|
||||
|
||||
ulong mem_ptr; //position of wram ptr for debug window
|
||||
bool disas_cpu_op, disas_apu_op;
|
||||
bool refresh_mem;
|
||||
bool refresh_bp;
|
||||
bool refresh_status;
|
||||
|
||||
bool cpu_op_executed;
|
||||
bool apu_op_executed;
|
||||
|
||||
bool output_cpu_instrs;
|
||||
bool output_apu_instrs;
|
||||
bool output_debug_info;
|
||||
bool trace_enabled;
|
||||
bool trace_output_enabled;
|
||||
|
||||
bool lock_up, lock_down, lock_left, lock_right;
|
||||
bool lock_a, lock_b, lock_x, lock_y;
|
||||
bool lock_l, lock_r, lock_select, lock_start;
|
||||
|
||||
struct {
|
||||
ulong offset;
|
||||
byte flags;
|
||||
byte source;
|
||||
byte value;
|
||||
ulong hit_count;
|
||||
}bp_list[16];
|
||||
|
||||
FILE *trace_fp;
|
||||
}debugstate;
|
||||
|
||||
/*********************
|
||||
*** ppu functions ***
|
||||
********************/
|
||||
|
||||
#define BG1 0x00
|
||||
#define BG2 0x01
|
||||
#define BG3 0x02
|
||||
#define BG4 0x03
|
||||
#define OAM 0x04
|
||||
#define SS_BG1 0x80
|
||||
#define SS_BG2 0x81
|
||||
#define SS_BG3 0x82
|
||||
#define SS_BG4 0x83
|
||||
#define SS_OAM 0x84
|
||||
#define BACK 0x05
|
||||
|
||||
#define CLIPMODE_IN 0
|
||||
#define CLIPMODE_OUT 1
|
||||
|
||||
#define WINDOWMASK_OR 0
|
||||
#define WINDOWMASK_AND 1
|
||||
#define WINDOWMASK_XOR 2
|
||||
#define WINDOWMASK_XNOR 3
|
||||
|
||||
#define COLORMODE_ADD 0
|
||||
#define COLORMODE_SUB 1
|
||||
|
||||
typedef struct {
|
||||
word *screen; //internal buffer used to render 512x448 screen
|
||||
byte *vram; //65536 bytes
|
||||
byte *cgram; //512 bytes
|
||||
byte *oam; //544 bytes mirrored as 1024 bytes (512-543 are mirrored to 544-1023)
|
||||
word *light_table; //16 * 32768 -- applies display_brightness to bgr555 color data
|
||||
//ppu.mosaic_table[ppu.mosaic_size][x] == (x / (ppu.mosaic_size + 1)) * (ppu.mosaic_size + 1)
|
||||
word *mosaic_table[16];
|
||||
|
||||
ulong ppu_cycles, ppu_prev_cycles; //used in ppu_update_scanline()
|
||||
|
||||
bool display_disable; //$2100 bit 7
|
||||
byte display_brightness; //$2100 bits 0-3
|
||||
|
||||
bool overscan;
|
||||
byte visible_scanlines;
|
||||
bool sprite_halve;
|
||||
bool interlace, toggle_interlace;
|
||||
byte interlace_frame; //0 or 1, used to alternate between scanlines rendered
|
||||
|
||||
bool bg_enabled[5];
|
||||
bool ss_bg_enabled[5];
|
||||
byte mosaic_size;
|
||||
bool mosaic_enabled[4];
|
||||
word bg_tilemap_loc[4];
|
||||
byte bg_tile_size[4];
|
||||
byte bg_tilemap_size[4];
|
||||
word bg_tiledata_loc[4];
|
||||
word oam_tiledata_loc;
|
||||
byte bg_priority_mode;
|
||||
byte oam_base_size;
|
||||
byte oam_name_sel;
|
||||
byte bg_mode;
|
||||
|
||||
word hline_pos; //0-255: inside vblank, 256-339: outside vblank
|
||||
word vline_pos; //0-223: inside vblank, 224-261: outside vblank, 180 cycles/scanline
|
||||
bool irq_triggered; //for $4211 read
|
||||
bool virq_triggered; //prevent recursive calling
|
||||
bool hirq_triggered; //prevent recursive calling
|
||||
word vram_write_pos; //holds value at $2116
|
||||
word vram_write_buffer;
|
||||
word vram_read_buffer;
|
||||
word vram_remap_mode;
|
||||
word vram_inc_size; //amount to increment vram_write_pos by
|
||||
byte vram_inc_reg; //increment on 2118 (0) or 2119 (1)
|
||||
word cgram_write_pos; //holds value at $2121 (multiplied by 2)
|
||||
word oam_write_pos; //holds value at $2102/$2103 (multiplied by 2)
|
||||
ulong wram_write_pos; //holds value at $2181-$2183
|
||||
|
||||
word bg_hscroll_pos[4]; //$210d-$2114
|
||||
word bg_vscroll_pos[4];
|
||||
word m7hofs, m7vofs;
|
||||
|
||||
byte mul_a, mul_b;
|
||||
word div_a;
|
||||
byte div_b;
|
||||
word r_4214, r_4216;
|
||||
ulong r_2134;
|
||||
|
||||
bool bg_window1_enabled[5];
|
||||
bool bg_window2_enabled[5];
|
||||
byte bg_window1_clipmode[5];
|
||||
byte bg_window2_clipmode[5];
|
||||
|
||||
byte window1_left, window1_right;
|
||||
byte window2_left, window2_right;
|
||||
|
||||
bool bg_windowing_enabled[5];
|
||||
bool ss_bg_windowing_enabled[5];
|
||||
byte bg_window_mask[5];
|
||||
|
||||
bool color_window1_enabled, color_window2_enabled;
|
||||
bool color_window1_clipmode, color_window2_clipmode;
|
||||
byte color_window_mask;
|
||||
byte color_mask, ss_color_mask;
|
||||
byte addsub_mode;
|
||||
byte color_mode, color_halve;
|
||||
bool bg_color_enabled[6];
|
||||
byte color_r, color_g, color_b;
|
||||
|
||||
byte active_hdma_channels;
|
||||
word hdma_scanlines_remaining[8];
|
||||
word hdma_index_pointer[8];
|
||||
bool hdma_completed[8];
|
||||
|
||||
bool vcounter_enabled, hcounter_enabled;
|
||||
word hirq_pos, virq_pos;
|
||||
|
||||
bool auto_joypad_read;
|
||||
byte joypad_strobe_value;
|
||||
|
||||
byte latch_toggle;
|
||||
word latch_vpos, latch_hpos;
|
||||
|
||||
word m7a, m7b, m7c, m7d, m7x, m7y;
|
||||
|
||||
byte mode7_repeat;
|
||||
bool mode7_extbg;
|
||||
bool mode7_vflip, mode7_hflip;
|
||||
|
||||
byte io4201;
|
||||
bool counter_latched;
|
||||
|
||||
byte mmio_mem_43xx[0x80];
|
||||
}ppustate;
|
||||
|
||||
/*********************
|
||||
*** cpu functions ***
|
||||
********************/
|
||||
|
||||
#define CPUSTATE_RUN 0
|
||||
#define CPUSTATE_DMA 1
|
||||
#define CPUSTATE_STP 2
|
||||
|
||||
#define MEMSPEED_SLOWROM 0
|
||||
#define MEMSPEED_FASTROM 1
|
||||
|
||||
void add_apu_cycles(int n);
|
||||
|
||||
//g65816 cpu flags
|
||||
#define PF_N 0x80
|
||||
#define PF_V 0x40
|
||||
#define PF_M 0x20
|
||||
#define PF_X 0x10
|
||||
#define PF_D 0x08
|
||||
#define PF_I 0x04
|
||||
#define PF_Z 0x02
|
||||
#define PF_C 0x01
|
||||
|
||||
//spc700 cpu flags
|
||||
#define SPF_N 0x80
|
||||
#define SPF_V 0x40
|
||||
#define SPF_P 0x20
|
||||
#define SPF_B 0x10
|
||||
#define SPF_H 0x08
|
||||
#define SPF_I 0x04
|
||||
#define SPF_Z 0x02
|
||||
#define SPF_C 0x01
|
||||
|
||||
/************************
|
||||
*** memory functions ***
|
||||
***********************/
|
||||
|
||||
#define MEMSPEED_FAST 6
|
||||
#define MEMSPEED_SLOW 8
|
||||
#define MEMSPEED_XSLOW 12
|
||||
|
||||
#define MEMMAP_HIROM 0x01
|
||||
#define MEMMAP_LOROM 0x02
|
||||
|
||||
#define MEMACCESS_NORMAL 0
|
||||
#define MEMACCESS_CPU 1
|
||||
#define MEMACCESS_DEBUGGER 1
|
||||
|
||||
enum {
|
||||
MEMMODE_NONE = 0, //(no address translation)
|
||||
MEMMODE_DP, //dp
|
||||
MEMMODE_DPX, //dp,x
|
||||
MEMMODE_DPY, //dp,y
|
||||
MEMMODE_IDP, //(dp)
|
||||
MEMMODE_IDPX, //(dp,x)
|
||||
MEMMODE_IDPY, //(dp),y
|
||||
MEMMODE_ILDP, //[dp]
|
||||
MEMMODE_ILDPY, //[dp],y
|
||||
MEMMODE_ADDR, //addr
|
||||
MEMMODE_ADDRX, //addr,x
|
||||
MEMMODE_ADDRY, //addr,y
|
||||
MEMMODE_IADDRX, //(addr,x)
|
||||
MEMMODE_ILADDR, //[addr]
|
||||
MEMMODE_LONG, //long
|
||||
MEMMODE_LONGX, //long, x
|
||||
MEMMODE_SR, //sr,s
|
||||
MEMMODE_ISRY, //(sr,s),y
|
||||
//exchanges pbr for dbr, disables address mirroring
|
||||
MEMMODE_ADDR_PC, //addr
|
||||
MEMMODE_IADDR_PC, //(addr)
|
||||
MEMMODE_IADDRX_PC, //(addr,x)
|
||||
MEMMODE_ILADDR_PC, //[addr]
|
||||
//opcode memory access types
|
||||
OPMODE_DBR,
|
||||
OPMODE_PBR,
|
||||
OPMODE_LONG,
|
||||
OPMODE_DP,
|
||||
OPMODE_SP,
|
||||
OPMODE_ADDR
|
||||
};
|
||||
|
||||
#define MEMSIZE_BYTE 1
|
||||
#define MEMSIZE_WORD 2
|
||||
#define MEMSIZE_LONG 3
|
||||
|
||||
/***********************
|
||||
*** misc. functions ***
|
||||
**********************/
|
||||
|
||||
//main.cpp
|
||||
void InitSNES(void);
|
||||
void RunSNES(void);
|
||||
void ResetSNES(void);
|
||||
|
||||
//cpu/g65816_ops_stack.cpp
|
||||
//ulong g65816_stackread(byte size);
|
||||
//void g65816_stackwrite(byte size, ulong value);
|
||||
|
||||
//cpu/d65816.cpp
|
||||
void disas_g65816_op(void);
|
||||
|
||||
//apu/dspc700.cpp
|
||||
void disas_spc700_op(void);
|
||||
|
||||
//ppu/mmio.cpp
|
||||
byte mmio_read(word addr);
|
||||
void mmio_write(word addr, byte value);
|
||||
|
||||
//ppu/ppu.cpp
|
||||
void ppu_render_scanline(void);
|
||||
void ppu_update_scanline(void);
|
||||
byte oam_read(word addr);
|
||||
void oam_write(word addr, byte value);
|
||||
void PPUInit(byte first_time);
|
||||
void ppu_update_dma(void);
|
||||
|
||||
//win/render.cpp
|
||||
void UpdateDisplay(void);
|
||||
|
||||
//misc/libstr.cpp
|
||||
ulong strhex(char *str);
|
||||
ulong strdec(char *str);
|
||||
@@ -1,26 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "bridge.h"
|
||||
port_bridge *cpu_apu_bridge;
|
||||
|
||||
port_bridge::port_bridge() {
|
||||
cputoapu_port[0] = cputoapu_port[1] =
|
||||
cputoapu_port[2] = cputoapu_port[3] =
|
||||
aputocpu_port[0] = aputocpu_port[1] =
|
||||
aputocpu_port[2] = aputocpu_port[3] = 0;
|
||||
}
|
||||
|
||||
byte port_bridge::cpu_read(byte port) {
|
||||
return aputocpu_port[port & 3];
|
||||
}
|
||||
|
||||
byte port_bridge::apu_read(byte port) {
|
||||
return cputoapu_port[port & 3];
|
||||
}
|
||||
|
||||
void port_bridge::cpu_write(byte port, byte value) {
|
||||
cputoapu_port[port & 3] = value;
|
||||
}
|
||||
|
||||
void port_bridge::apu_write(byte port, byte value) {
|
||||
aputocpu_port[port & 3] = value;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
class port_bridge {
|
||||
public:
|
||||
byte cputoapu_port[4]; //holds values written to CPU at $2140-$2143
|
||||
byte aputocpu_port[4]; //holds values written to APU at $f4-$f7
|
||||
|
||||
port_bridge();
|
||||
byte cpu_read(byte port);
|
||||
byte apu_read(byte port);
|
||||
void cpu_write(byte port, byte value);
|
||||
void apu_write(byte port, byte value);
|
||||
};
|
||||
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
@nmake /NOLOGO
|
||||
@pause
|
||||
@@ -1 +0,0 @@
|
||||
@nmake /NOLOGO clean
|
||||
@@ -1,339 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "g65816.h"
|
||||
extern g65816 *gx816;
|
||||
extern debugstate debugger;
|
||||
|
||||
ulong _disas_relb(byte addr) {
|
||||
return gx816->regs.pc + (signed char)(addr + 2);
|
||||
}
|
||||
|
||||
ulong _disas_relw(word addr) {
|
||||
return gx816->regs.pc + (signed short)(addr + 3);
|
||||
}
|
||||
|
||||
char __disas_op_str[256];
|
||||
void __disas_op(byte op, byte op0, byte op1, byte op2) {
|
||||
char *s = (char*)__disas_op_str;
|
||||
switch(op) {
|
||||
case 0x00:sprintf(s, "brk #$%0.2x ", op0);break;
|
||||
case 0x01:sprintf(s, "ora ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x02:sprintf(s, "cop #$%0.2x ", op0);break;
|
||||
case 0x03:sprintf(s, "ora $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x04:sprintf(s, "tsb $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x05:sprintf(s, "ora $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x06:sprintf(s, "asl $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x07:sprintf(s, "ora [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x08:sprintf(s, "php ");break;
|
||||
case 0x09:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "ora #$%0.2x ", op0);
|
||||
else sprintf(s, "ora #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x0a:sprintf(s, "asl a ");break;
|
||||
case 0x0b:sprintf(s, "phd ");break;
|
||||
case 0x0c:sprintf(s, "tsb $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0d:sprintf(s, "ora $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0e:sprintf(s, "asl $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0f:sprintf(s, "ora $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x10:sprintf(s, "bpl $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x11:sprintf(s, "ora ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x12:sprintf(s, "ora ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x13:sprintf(s, "ora ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x14:sprintf(s, "trb $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x15:sprintf(s, "ora $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x16:sprintf(s, "asl $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x17:sprintf(s, "ora [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x18:sprintf(s, "clc ");break;
|
||||
case 0x19:sprintf(s, "ora $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x1a:sprintf(s, "inc ");break;
|
||||
case 0x1b:sprintf(s, "tcs ");break;
|
||||
case 0x1c:sprintf(s, "trb $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x1d:sprintf(s, "ora $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x1e:sprintf(s, "asl $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x1f:sprintf(s, "ora $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x20:sprintf(s, "jsr $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x21:sprintf(s, "and ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x22:sprintf(s, "jsl $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x23:sprintf(s, "and $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x24:sprintf(s, "bit $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x25:sprintf(s, "and $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x26:sprintf(s, "rol $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x27:sprintf(s, "and [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x28:sprintf(s, "plp ");break;
|
||||
case 0x29:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "and #$%0.2x ", op0);
|
||||
else sprintf(s, "and #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x2a:sprintf(s, "rol a ");break;
|
||||
case 0x2b:sprintf(s, "pld ");break;
|
||||
case 0x2c:sprintf(s, "bit $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2d:sprintf(s, "and $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2e:sprintf(s, "rol $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2f:sprintf(s, "and $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x30:sprintf(s, "bmi $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x31:sprintf(s, "and ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x32:sprintf(s, "and ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x33:sprintf(s, "and ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x34:sprintf(s, "bit $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x35:sprintf(s, "and $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x36:sprintf(s, "rol $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x37:sprintf(s, "and [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x38:sprintf(s, "sec ");break;
|
||||
case 0x39:sprintf(s, "and $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x3a:sprintf(s, "dec ");break;
|
||||
case 0x3b:sprintf(s, "tsc ");break;
|
||||
case 0x3c:sprintf(s, "bit $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3d:sprintf(s, "and $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3e:sprintf(s, "rol $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3f:sprintf(s, "and $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x40:sprintf(s, "rti ");break;
|
||||
case 0x41:sprintf(s, "eor ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x42:sprintf(s, "wdm ");break;
|
||||
case 0x43:sprintf(s, "eor $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x44:sprintf(s, "mvp $%0.2x,$%0.2x ", op1, op0);break;
|
||||
case 0x45:sprintf(s, "eor $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x46:sprintf(s, "lsr $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x47:sprintf(s, "eor [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x48:sprintf(s, "pha ");break;
|
||||
case 0x49:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "eor #$%0.2x ", op0);
|
||||
else sprintf(s, "eor #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x4a:sprintf(s, "lsr a ");break;
|
||||
case 0x4b:sprintf(s, "phk ");break;
|
||||
case 0x4c:sprintf(s, "jmp $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x4d:sprintf(s, "eor $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x4e:sprintf(s, "lsr $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x4f:sprintf(s, "eor $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x50:sprintf(s, "bvc $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x51:sprintf(s, "eor ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x52:sprintf(s, "eor ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x53:sprintf(s, "eor ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x54:sprintf(s, "mvn $%0.2x,$%0.2x ", op1, op0);break;
|
||||
case 0x55:sprintf(s, "eor $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x56:sprintf(s, "lsr $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x57:sprintf(s, "eor [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x58:sprintf(s, "cli ");break;
|
||||
case 0x59:sprintf(s, "eor $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x5a:sprintf(s, "phy ");break;
|
||||
case 0x5b:sprintf(s, "tcd ");break;
|
||||
case 0x5c:sprintf(s, "jml $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x5d:sprintf(s, "eor $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x5e:sprintf(s, "lsr $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x5f:sprintf(s, "eor $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x60:sprintf(s, "rts ");break;
|
||||
case 0x61:sprintf(s, "adc ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x62:sprintf(s, "per $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x63:sprintf(s, "adc $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x64:sprintf(s, "stz $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x65:sprintf(s, "adc $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x66:sprintf(s, "ror $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x67:sprintf(s, "adc [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x68:sprintf(s, "pla ");break;
|
||||
case 0x69:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "adc #$%0.2x ", op0);
|
||||
else sprintf(s, "adc #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x6a:sprintf(s, "ror a ");break;
|
||||
case 0x6b:sprintf(s, "rtl ");break;
|
||||
case 0x6c:sprintf(s, "jmp ($%0.4x) [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x6d:sprintf(s, "adc $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x6e:sprintf(s, "ror $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x6f:sprintf(s, "adc $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x70:sprintf(s, "bvs $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x71:sprintf(s, "adc ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x72:sprintf(s, "adc ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x73:sprintf(s, "adc ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x74:sprintf(s, "stz $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x75:sprintf(s, "adc $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x76:sprintf(s, "ror $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x77:sprintf(s, "adc [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x78:sprintf(s, "sei ");break;
|
||||
case 0x79:sprintf(s, "adc $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x7a:sprintf(s, "ply ");break;
|
||||
case 0x7b:sprintf(s, "tdc ");break;
|
||||
case 0x7c:sprintf(s, "jmp ($%0.4x,x) [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDRX_PC, (op0|op1<<8)));break;
|
||||
case 0x7d:sprintf(s, "adc $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x7e:sprintf(s, "ror $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x7f:sprintf(s, "adc $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x80:sprintf(s, "bra $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x81:sprintf(s, "sta ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0x82:sprintf(s, "brl $%0.4x [$%0.6x]", _disas_relw(op0|op1<<8)&0xffff, _disas_relw(op0|op1<<8)&0xffffff);break;
|
||||
case 0x83:sprintf(s, "sta $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0x84:sprintf(s, "sty $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x85:sprintf(s, "sta $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x86:sprintf(s, "stx $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0x87:sprintf(s, "sta [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0x88:sprintf(s, "dey ");break;
|
||||
case 0x89:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "bit #$%0.2x ", op0);
|
||||
else sprintf(s, "bit #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x8a:sprintf(s, "txa ");break;
|
||||
case 0x8b:sprintf(s, "phb ");break;
|
||||
case 0x8c:sprintf(s, "sty $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8d:sprintf(s, "sta $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8e:sprintf(s, "stx $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8f:sprintf(s, "sta $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x90:sprintf(s, "bcc $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0x91:sprintf(s, "sta ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0x92:sprintf(s, "sta ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0x93:sprintf(s, "sta ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0x94:sprintf(s, "sty $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x95:sprintf(s, "sta $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0x96:sprintf(s, "stx $%0.2x,y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPY, op0));break;
|
||||
case 0x97:sprintf(s, "sta [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0x98:sprintf(s, "tya ");break;
|
||||
case 0x99:sprintf(s, "sta $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x9a:sprintf(s, "txs ");break;
|
||||
case 0x9b:sprintf(s, "txy ");break;
|
||||
case 0x9c:sprintf(s, "stz $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x9d:sprintf(s, "sta $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x9e:sprintf(s, "stz $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x9f:sprintf(s, "sta $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xa0:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "ldy #$%0.2x ", op0);
|
||||
else sprintf(s, "ldy #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xa1:sprintf(s, "lda ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0xa2:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "ldx #$%0.2x ", op0);
|
||||
else sprintf(s, "ldx #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xa3:sprintf(s, "lda $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0xa4:sprintf(s, "ldy $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xa5:sprintf(s, "lda $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xa6:sprintf(s, "ldx $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xa7:sprintf(s, "lda [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0xa8:sprintf(s, "tay ");break;
|
||||
case 0xa9:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "lda #$%0.2x ", op0);
|
||||
else sprintf(s, "lda #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xaa:sprintf(s, "tax ");break;
|
||||
case 0xab:sprintf(s, "plb ");break;
|
||||
case 0xac:sprintf(s, "ldy $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xad:sprintf(s, "lda $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xae:sprintf(s, "ldx $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xaf:sprintf(s, "lda $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xb0:sprintf(s, "bcs $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0xb1:sprintf(s, "lda ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0xb2:sprintf(s, "lda ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0xb3:sprintf(s, "lda ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0xb4:sprintf(s, "ldy $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xb5:sprintf(s, "lda $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xb6:sprintf(s, "ldx $%0.2x,y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPY, op0));break;
|
||||
case 0xb7:sprintf(s, "lda [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0xb8:sprintf(s, "clv ");break;
|
||||
case 0xb9:sprintf(s, "lda $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xba:sprintf(s, "tsx ");break;
|
||||
case 0xbb:sprintf(s, "tyx ");break;
|
||||
case 0xbc:sprintf(s, "ldy $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xbd:sprintf(s, "lda $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xbe:sprintf(s, "ldx $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xbf:sprintf(s, "lda $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xc0:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "cpy #$%0.2x ", op0);
|
||||
else sprintf(s, "cpy #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xc1:sprintf(s, "cmp ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0xc2:sprintf(s, "rep #$%0.2x ", op0);break;
|
||||
case 0xc3:sprintf(s, "cmp $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0xc4:sprintf(s, "cpy $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xc5:sprintf(s, "cmp $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xc6:sprintf(s, "dec $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xc7:sprintf(s, "cmp [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0xc8:sprintf(s, "iny ");break;
|
||||
case 0xc9:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "cmp #$%0.2x ", op0);
|
||||
else sprintf(s, "cmp #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xca:sprintf(s, "dex ");break;
|
||||
case 0xcb:sprintf(s, "wai ");break;
|
||||
case 0xcc:sprintf(s, "cpy $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xcd:sprintf(s, "cmp $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xce:sprintf(s, "dec $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xcf:sprintf(s, "cmp $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xd0:sprintf(s, "bne $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0xd1:sprintf(s, "cmp ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0xd2:sprintf(s, "cmp ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0xd3:sprintf(s, "cmp ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0xd4:sprintf(s, "pei ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0xd5:sprintf(s, "cmp $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xd6:sprintf(s, "dec $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xd7:sprintf(s, "cmp [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0xd8:sprintf(s, "cld ");break;
|
||||
case 0xd9:sprintf(s, "cmp $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xda:sprintf(s, "phx ");break;
|
||||
case 0xdb:sprintf(s, "stp ");break;
|
||||
case 0xdc:sprintf(s, "jmp [$%0.4x] [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ILADDR_PC, (op0|op1<<8)));break;
|
||||
case 0xdd:sprintf(s, "cmp $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xde:sprintf(s, "dec $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xdf:sprintf(s, "cmp $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xe0:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & PF_X)))sprintf(s, "cpx #$%0.2x ", op0);
|
||||
else sprintf(s, "cpx #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xe1:sprintf(s, "sbc ($%0.2x,x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPX, op0));break;
|
||||
case 0xe2:sprintf(s, "sep #$%0.2x ", op0);break;
|
||||
case 0xe3:sprintf(s, "sbc $%0.2x,s [$%0.6x]", op0, gx816->convert_offset(MEMMODE_SR, op0));break;
|
||||
case 0xe4:sprintf(s, "cpx $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xe5:sprintf(s, "sbc $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xe6:sprintf(s, "inc $%0.2x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DP, op0));break;
|
||||
case 0xe7:sprintf(s, "sbc [$%0.2x] [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDP, op0));break;
|
||||
case 0xe8:sprintf(s, "inx ");break;
|
||||
case 0xe9:
|
||||
if(gx816->regs.e == true || (gx816->regs.e == false && (gx816->regs.p & 0x20)))sprintf(s, "sbc #$%0.2x ", op0);
|
||||
else sprintf(s, "sbc #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xea:sprintf(s, "nop ");break;
|
||||
case 0xeb:sprintf(s, "xba ");break;
|
||||
case 0xec:sprintf(s, "cpx $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xed:sprintf(s, "sbc $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xee:sprintf(s, "inc $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xef:sprintf(s, "sbc $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xf0:sprintf(s, "beq $%0.4x [$%0.6x]", _disas_relb(op0)&0xffff, _disas_relb(op0)&0xffffff);break;
|
||||
case 0xf1:sprintf(s, "sbc ($%0.2x),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDPY, op0));break;
|
||||
case 0xf2:sprintf(s, "sbc ($%0.2x) [$%0.6x]", op0, gx816->convert_offset(MEMMODE_IDP, op0));break;
|
||||
case 0xf3:sprintf(s, "sbc ($%0.2x,s),y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ISRY, op0));break;
|
||||
case 0xf4:sprintf(s, "pea $%0.4x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xf5:sprintf(s, "sbc $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xf6:sprintf(s, "inc $%0.2x,x [$%0.6x]", op0, gx816->convert_offset(MEMMODE_DPX, op0));break;
|
||||
case 0xf7:sprintf(s, "sbc [$%0.2x],y [$%0.6x]", op0, gx816->convert_offset(MEMMODE_ILDPY, op0));break;
|
||||
case 0xf8:sprintf(s, "sed ");break;
|
||||
case 0xf9:sprintf(s, "sbc $%0.4x,y [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xfa:sprintf(s, "plx ");break;
|
||||
case 0xfb:sprintf(s, "xce ");break;
|
||||
case 0xfc:sprintf(s, "jsr ($%0.4x,x) [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_IADDRX_PC, (op0|op1<<8)));break;
|
||||
case 0xfd:sprintf(s, "sbc $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xfe:sprintf(s, "inc $%0.4x,x [$%0.6x]", op0|op1<<8, gx816->convert_offset(MEMMODE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xff:sprintf(s, "sbc $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, gx816->convert_offset(MEMMODE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
}
|
||||
}
|
||||
|
||||
void disas_g65816_op(void) {
|
||||
byte op, op0, op1, op2;
|
||||
char str0[256], str1[256], str2[256];
|
||||
if(debug_write_status() == DEBUGWRITE_NONE)return;
|
||||
|
||||
op = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc, MEMACCESS_DEBUGGER);
|
||||
op0 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 1, MEMACCESS_DEBUGGER);
|
||||
op1 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 2, MEMACCESS_DEBUGGER);
|
||||
op2 = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc + 3, MEMACCESS_DEBUGGER);
|
||||
|
||||
strcpy(__disas_op_str, "??? ");
|
||||
__disas_op(op, op0, op1, op2);
|
||||
|
||||
if(gx816->regs.e == true) {
|
||||
sprintf(str1, "%c%c%c%c%c%c%c%c E",
|
||||
(gx816->regs.p & 0x80)?'N':'n',
|
||||
(gx816->regs.p & 0x40)?'V':'v',
|
||||
(gx816->regs.p & 0x20)?'1':'0',
|
||||
(gx816->regs.p & 0x10)?'B':'b',
|
||||
(gx816->regs.p & 0x08)?'D':'d',
|
||||
(gx816->regs.p & 0x04)?'I':'i',
|
||||
(gx816->regs.p & 0x02)?'Z':'z',
|
||||
(gx816->regs.p & 0x01)?'C':'c');
|
||||
} else {
|
||||
sprintf(str1, "%c%c%c%c%c%c%c%c N",
|
||||
(gx816->regs.p & 0x80)?'N':'n',
|
||||
(gx816->regs.p & 0x40)?'V':'v',
|
||||
(gx816->regs.p & 0x20)?'M':'m',
|
||||
(gx816->regs.p & 0x10)?'X':'x',
|
||||
(gx816->regs.p & 0x08)?'D':'d',
|
||||
(gx816->regs.p & 0x04)?'I':'i',
|
||||
(gx816->regs.p & 0x02)?'Z':'z',
|
||||
(gx816->regs.p & 0x01)?'C':'c');
|
||||
}
|
||||
|
||||
dprintf(DEBUGMSG_CPU, "%0.6x %s A:%0.4x X:%0.4x Y:%0.4x S:%0.4x D:%0.4x DB:%0.2x %s", gx816->regs.pc, __disas_op_str,
|
||||
gx816->regs.a.w, gx816->regs.x, gx816->regs.y, gx816->regs.s,
|
||||
gx816->regs.d, gx816->regs.db, str1);
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "../timing/timing.h"
|
||||
#include "g65816.h"
|
||||
|
||||
extern emustate emu_state;
|
||||
extern debugstate debugger;
|
||||
extern ppustate ppu;
|
||||
extern snes_timer *snes_time;
|
||||
g65816 *gx816;
|
||||
|
||||
#include "g65816_ops.cpp"
|
||||
|
||||
void g65816::LoadROM(void) {
|
||||
FILE *fp;
|
||||
ulong fsize;
|
||||
word header_offset = 0;
|
||||
word cksum, icksum;
|
||||
byte t;
|
||||
int i;
|
||||
dprintf("* Loading [%s]...", emu_state.rom_name);
|
||||
|
||||
fp = fopen(emu_state.rom_name, "rb");
|
||||
if(!fp)return;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
fsize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
map = MEMMAP_LOROM;
|
||||
|
||||
if((fsize & 0x000fff) == 0x000200)header_offset = 512;
|
||||
|
||||
fseek(fp, 0x7fdc + header_offset, SEEK_SET);
|
||||
cksum = fgetc(fp) | fgetc(fp) << 8;
|
||||
icksum = fgetc(fp) | fgetc(fp) << 8;
|
||||
if(cksum + icksum == 0xffff)map = MEMMAP_LOROM;
|
||||
|
||||
fseek(fp, 0xffdc + header_offset, SEEK_SET);
|
||||
cksum = fgetc(fp) | fgetc(fp) << 8;
|
||||
icksum = fgetc(fp) | fgetc(fp) << 8;
|
||||
if(cksum + icksum == 0xffff)map = MEMMAP_HIROM;
|
||||
|
||||
fseek(fp, 0 + header_offset, SEEK_SET);
|
||||
fsize -= header_offset;
|
||||
|
||||
dprintf("* ROM detected as: %s", (map == MEMMAP_LOROM)?"LoROM":"HiROM");
|
||||
|
||||
InitializeROM(map);
|
||||
|
||||
fread(rom, 1, fsize, fp);
|
||||
|
||||
t = (mem_read(MEMMODE_NONE, MEMSIZE_BYTE, 0x00ffd8) & 7);
|
||||
switch(t) {
|
||||
case 0: sram_size = 0; break;
|
||||
case 1: sram_size = 2 * 1024;break;
|
||||
case 2: sram_size = 4 * 1024;break;
|
||||
case 3: sram_size = 8 * 1024;break;
|
||||
case 4: sram_size = 16 * 1024;break;
|
||||
case 5: sram_size = 32 * 1024;break;
|
||||
case 6: sram_size = 64 * 1024;break;
|
||||
case 7: sram_size = 128 * 1024;break;
|
||||
default:sram_size = 0; break;
|
||||
}
|
||||
dprintf("* SRAM Size: %dkb", sram_size / 1024);
|
||||
|
||||
//pbr is loaded with 00, and 16-bit pc is loaded with reset vector at 0xfffc
|
||||
//upon power on and at first reset
|
||||
regs.pc = mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00fffc);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(sram_size != 0) {
|
||||
fp = fopen(emu_state.sram_name, "rb");
|
||||
|
||||
//create sram file if it does not exist
|
||||
if(!fp) {
|
||||
fp = fopen(emu_state.sram_name, "wb");
|
||||
for(i=0;i<sram_size;i++) {
|
||||
fputc(0, fp);
|
||||
}
|
||||
fclose(fp);
|
||||
fp = fopen(emu_state.sram_name, "rb");
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
fsize = ftell(fp);
|
||||
|
||||
//fix sram size if it is smaller than actual size
|
||||
if(fsize < sram_size) {
|
||||
fclose(fp);
|
||||
fp = fopen(emu_state.sram_name, "rb+wb");
|
||||
fseek(fp, 0, SEEK_END);
|
||||
while(fsize < sram_size) {
|
||||
fputc(0, fp);
|
||||
fsize++;
|
||||
}
|
||||
fclose(fp);
|
||||
fp = fopen(emu_state.sram_name, "rb");
|
||||
}
|
||||
|
||||
//read file into sram
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(sram, 1, sram_size, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void g65816::PowerOn(byte first_time) {
|
||||
//default register states
|
||||
regs.a.w = regs.x = regs.y = 0x0000;
|
||||
regs.d = 0x0000;
|
||||
regs.s = 0x01ff;
|
||||
regs.db = 0x00;
|
||||
regs.p = 0x34;
|
||||
regs.e = true;
|
||||
snes_time->master_cycles = 0;
|
||||
memory_speed = MEMSPEED_SLOWROM;
|
||||
wai_interrupt_occurred = false;
|
||||
|
||||
InitializeWRAM(0x00);
|
||||
PPUInit(first_time);
|
||||
UpdateDisplay();
|
||||
snes_time->set_speed_map(MEMSPEED_SLOWROM);
|
||||
cpu_state = CPUSTATE_RUN;
|
||||
}
|
||||
|
||||
void g65816::Reset(void) {
|
||||
regs.x &= 0xff;
|
||||
regs.y &= 0xff;
|
||||
regs.s = 0x0100 | (regs.s & 0xff);
|
||||
regs.d = 0x0000;
|
||||
regs.db = 0x00;
|
||||
regs.p = 0x34;
|
||||
regs.e = true;
|
||||
regs.pc = mem_read(MEMMODE_LONG, MEMSIZE_WORD, 0x00fffc);
|
||||
snes_time->master_cycles = 0;
|
||||
memory_speed = MEMSPEED_SLOWROM;
|
||||
wai_interrupt_occurred = false;
|
||||
|
||||
PPUInit(0); //0 blocks reallocating memory for vram, cgram, etc.
|
||||
UpdateDisplay();
|
||||
snes_time->set_speed_map(MEMSPEED_SLOWROM);
|
||||
cpu_state = CPUSTATE_RUN;
|
||||
}
|
||||
|
||||
/***********
|
||||
*** IRQ ***
|
||||
***********
|
||||
cycles:
|
||||
[1] pbr,pc ; io
|
||||
[2] pbr,pc ; io
|
||||
[3] 0,s ; pbr
|
||||
[4] 0,s-1 ; pch
|
||||
[5] 0,s-2 ; pcl
|
||||
[6] 0,s-3 ; p
|
||||
[7] 0,va ; aavl
|
||||
[8] 0,va+1 ; aavh
|
||||
*/
|
||||
|
||||
void g65816::InvokeIRQ(word addr) {
|
||||
snes_time->add_cpu_icycles(2); //1,2 [i/o]
|
||||
gx816->stack_write(gx816->regs.pc >> 16); //3 [write pbr]
|
||||
gx816->stack_write(gx816->regs.pc >> 8); //4 [write pch]
|
||||
gx816->stack_write(gx816->regs.pc); //5 [write pcl]
|
||||
gx816->stack_write(gx816->regs.p); //6 [write p]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, addr); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, addr + 1); //8 [read high]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.w;
|
||||
gx816->regs.p |= PF_I;
|
||||
wai_interrupt_occurred = true;
|
||||
snes_time->update_timer();
|
||||
}
|
||||
|
||||
void g65816::exec_op(void) {
|
||||
FILE *fp;
|
||||
byte op;
|
||||
int i;
|
||||
static ulong sram_save_tick = 0;
|
||||
if(cpu_state == CPUSTATE_RUN || cpu_state == CPUSTATE_STP) {
|
||||
op = mem_read(MEMMODE_NONE, MEMSIZE_BYTE, gx816->regs.pc);
|
||||
if(regs.e == true)g65816_optbl_e[op]();
|
||||
else switch((regs.p & 0x30)) {
|
||||
case 0x30:g65816_optbl_MX[op]();break;
|
||||
case 0x20:g65816_optbl_Mx[op]();break;
|
||||
case 0x10:g65816_optbl_mX[op]();break;
|
||||
case 0x00:g65816_optbl_mx[op]();break;
|
||||
}
|
||||
debugger.cpu_op_executed = true;
|
||||
debugger.disas_cpu_op = true;
|
||||
snes_time->update_timer();
|
||||
} else if(cpu_state == CPUSTATE_DMA) {
|
||||
ppu_update_dma();
|
||||
snes_time->update_timer();
|
||||
}
|
||||
|
||||
snes_time->update_timer_events();
|
||||
ppu_update_scanline();
|
||||
|
||||
//see if we need to backup sram to a file yet...
|
||||
if(sram_size != 0) {
|
||||
sram_save_tick++;
|
||||
if(sram_save_tick >= emu_state.sram_save_tick_count) {
|
||||
sram_save_tick = 0;
|
||||
fp = fopen(emu_state.sram_name, "wb");
|
||||
fwrite(sram, 1, sram_size, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
debug_test_bp(BPSRC_MEM, BP_EXEC, gx816->regs.pc, 0);
|
||||
}
|
||||
|
||||
void g65816::Run(void) {
|
||||
if(snes_time->bridge.apu_cycles >= snes_time->bridge.cpu_cycles) {
|
||||
exec_op();
|
||||
}
|
||||
if(snes_time->bridge.cpu_cycles >= 65536 && snes_time->bridge.apu_cycles >= 65536) {
|
||||
snes_time->bridge.cpu_cycles &= 65535;
|
||||
snes_time->bridge.apu_cycles &= 65535;
|
||||
}
|
||||
}
|
||||
|
||||
g65816::g65816() {
|
||||
int i;
|
||||
rom = (byte*)malloc(0x600000);
|
||||
wram = (byte*)malloc(0x020000);
|
||||
sram = (byte*)malloc(0x0e0000);
|
||||
nmi_enabled = false;
|
||||
nmi_pin = 0;
|
||||
|
||||
op.dp = op.sp = 0x00;
|
||||
op.r.l = 0x000000;
|
||||
op.aa.l = 0x000000;
|
||||
}
|
||||
|
||||
g65816::~g65816() {
|
||||
if(rom)free(rom);
|
||||
if(wram)free(wram);
|
||||
if(sram)free(sram);
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
regs.dc is not a real register. it is used to store the data counter
|
||||
for reading from / writing to memory locations. it is also needed
|
||||
to emulate slowrom / fastrom, as the speed varies depending on the
|
||||
location where the memory was accessed.
|
||||
*/
|
||||
|
||||
class g65816 {
|
||||
public:
|
||||
//cpu declarations
|
||||
byte cpu_state;
|
||||
struct {
|
||||
ulong pc;
|
||||
union {
|
||||
byte b;
|
||||
word w;
|
||||
struct { byte l, h; }p;
|
||||
}a;
|
||||
word x, y, d, s;
|
||||
byte db, p;
|
||||
bool e;
|
||||
}regs;
|
||||
struct {
|
||||
byte dp, sp;
|
||||
union {
|
||||
byte b;
|
||||
word w;
|
||||
ulong l;
|
||||
struct { byte l, h, b; }p;
|
||||
}r;
|
||||
union {
|
||||
word w;
|
||||
ulong l;
|
||||
struct { byte l, h, b; }p;
|
||||
}aa;
|
||||
ulong addr, iaddr;
|
||||
bool c2, c4;
|
||||
}op;
|
||||
byte memory_speed;
|
||||
|
||||
byte nmi_pin;
|
||||
bool nmi_enabled;
|
||||
|
||||
bool wai_interrupt_occurred;
|
||||
|
||||
//memory declarations
|
||||
byte *wram, *sram, *rom;
|
||||
ulong map;
|
||||
ulong sram_size;
|
||||
|
||||
//cpu functions (cpu/g65816.cpp)
|
||||
void Run(void);
|
||||
void LoadROM(void);
|
||||
void PowerOn(byte first_time);
|
||||
void Reset(void);
|
||||
void InvokeIRQ(word addr);
|
||||
|
||||
//memory functions (mem/memory.cpp)
|
||||
void exec_op(void);
|
||||
void InitializeROM(byte memory_map);
|
||||
void InitializeWRAM(byte value);
|
||||
ulong mirror_offset(ulong offset);
|
||||
ulong convert_offset(byte read_mode, ulong addr, bool mirror = true);
|
||||
//ulong adjust_base_offset(byte read_mode, ulong addr);
|
||||
//ulong read_indirect_address(byte read_mode, ulong addr);
|
||||
//ulong get_dc(byte read_mode, ulong addr);
|
||||
|
||||
byte mem_getbyte_direct(ulong addr, byte access_mode = MEMACCESS_NORMAL);
|
||||
byte mem_getbyte(ulong addr, byte access_mode = MEMACCESS_NORMAL);
|
||||
void mem_putbyte_direct(ulong addr, byte value, byte access_mode = MEMACCESS_NORMAL);
|
||||
void mem_putbyte(ulong addr, byte value, byte access_mode = MEMACCESS_NORMAL);
|
||||
ulong mem_read(byte read_mode, byte read_size, ulong addr, byte access_mode = MEMACCESS_NORMAL);
|
||||
void mem_write(byte write_mode, byte write_size, ulong addr, ulong value, byte access_mode = MEMACCESS_NORMAL);
|
||||
|
||||
ulong read_operand(byte size);
|
||||
byte op_read(byte mode, ulong addr);
|
||||
void op_write(byte mode, ulong addr, byte value);
|
||||
byte stack_read(void);
|
||||
void stack_write(byte value);
|
||||
void op_cond(byte c, ulong n0 = 0, ulong n1 = 0);
|
||||
|
||||
ulong rom_read(ulong addr, byte read_size);
|
||||
void rom_write(ulong addr, ulong v, byte write_size);
|
||||
|
||||
g65816();
|
||||
~g65816();
|
||||
};
|
||||
@@ -1,162 +0,0 @@
|
||||
#define g65816_setn() gx816->regs.p |= PF_N
|
||||
#define g65816_clrn() gx816->regs.p &= ~PF_N
|
||||
#define g65816_setv() gx816->regs.p |= PF_V
|
||||
#define g65816_clrv() gx816->regs.p &= ~PF_V
|
||||
#define g65816_setm() gx816->regs.p |= PF_M
|
||||
#define g65816_clrm() gx816->regs.p &= ~PF_M
|
||||
#define g65816_setx() gx816->regs.p |= PF_X
|
||||
#define g65816_clrx() gx816->regs.p &= ~PF_X
|
||||
#define g65816_setd() gx816->regs.p |= PF_D
|
||||
#define g65816_clrd() gx816->regs.p &= ~PF_D
|
||||
#define g65816_seti() gx816->regs.p |= PF_I
|
||||
#define g65816_clri() gx816->regs.p &= ~PF_I
|
||||
#define g65816_setz() gx816->regs.p |= PF_Z
|
||||
#define g65816_clrz() gx816->regs.p &= ~PF_Z
|
||||
#define g65816_setc() gx816->regs.p |= PF_C
|
||||
#define g65816_clrc() gx816->regs.p &= ~PF_C
|
||||
#define g65816_testn(x) if(x)g65816_setn(); else g65816_clrn()
|
||||
#define g65816_testv(x) if(x)g65816_setv(); else g65816_clrv()
|
||||
#define g65816_testd(x) if(x)g65816_setd(); else g65816_clrd()
|
||||
#define g65816_testi(x) if(x)g65816_seti(); else g65816_clri()
|
||||
#define g65816_testz(x) if(x)g65816_setz(); else g65816_clrz()
|
||||
#define g65816_testc(x) if(x)g65816_setc(); else g65816_clrc()
|
||||
|
||||
//increment program counter, wrap around pbr
|
||||
#define g65816_incpc(__n) gx816->regs.pc = (gx816->regs.pc & 0xff0000) | (word)(gx816->regs.pc + __n)
|
||||
|
||||
/*
|
||||
vpa = 1, vda = 1 -> add_cpu_pcycles (opcode fetch)
|
||||
vpa = 1, vda = 0 -> add_cpu_pcycles (operand fetch)
|
||||
vpa = 0, vda = 1 -> add_cpu_dcycles (memory fetch)
|
||||
vpa = 0, vda = 0 -> add_cpu_icycles (internal operation)
|
||||
*/
|
||||
|
||||
//opcode functions
|
||||
#include "g65816_ops_adc.cpp"
|
||||
#include "g65816_ops_and.cpp"
|
||||
#include "g65816_ops_cmp.cpp"
|
||||
#include "g65816_ops_eor.cpp"
|
||||
#include "g65816_ops_lda.cpp"
|
||||
#include "g65816_ops_ora.cpp"
|
||||
#include "g65816_ops_sbc.cpp"
|
||||
#include "g65816_ops_sta.cpp"
|
||||
#include "g65816_ops_incdec.cpp"
|
||||
#include "g65816_ops_shift.cpp"
|
||||
#include "g65816_ops_stack.cpp"
|
||||
#include "g65816_ops_pc.cpp"
|
||||
#include "g65816_ops_misc.cpp"
|
||||
|
||||
vfunc g65816_optbl_e[256] = { // g65816_optbl_e, g65816_optbl_e, g65816_optbl_e,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxb, g65816_op_cop, g65816_op_ora_srb, /* 0x */ g65816_op_tsb_dpb, g65816_op_ora_dpb, g65816_op_asl_dpb, g65816_op_ora_ildpb, /* 0x */ g65816_op_php, g65816_op_ora_constb, g65816_op_aslb, g65816_op_phd, /* 0x */ g65816_op_tsb_addrb, g65816_op_ora_addrb, g65816_op_asl_addrb, g65816_op_ora_longb,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyb, g65816_op_ora_idpb, g65816_op_ora_isryb, /* 1x */ g65816_op_trb_dpb, g65816_op_ora_dpxb, g65816_op_asl_dpxb, g65816_op_ora_ildpyb, /* 1x */ g65816_op_clc, g65816_op_ora_addryb, g65816_op_incb, g65816_op_tcse, /* 1x */ g65816_op_trb_addrb, g65816_op_ora_addrxb, g65816_op_asl_addrxb, g65816_op_ora_longxb,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxb, g65816_op_jsr_long, g65816_op_and_srb, /* 2x */ g65816_op_bit_dpb, g65816_op_and_dpb, g65816_op_rol_dpb, g65816_op_and_ildpb, /* 2x */ g65816_op_plp, g65816_op_and_constb, g65816_op_rolb, g65816_op_pld, /* 2x */ g65816_op_bit_addrb, g65816_op_and_addrb, g65816_op_rol_addrb, g65816_op_and_longb,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyb, g65816_op_and_idpb, g65816_op_and_isryb, /* 3x */ g65816_op_bit_dpxb, g65816_op_and_dpxb, g65816_op_rol_dpxb, g65816_op_and_ildpyb, /* 3x */ g65816_op_sec, g65816_op_and_addryb, g65816_op_decb, g65816_op_tsce, /* 3x */ g65816_op_bit_addrxb, g65816_op_and_addrxb, g65816_op_rol_addrxb, g65816_op_and_longxb,
|
||||
|
||||
/* 4x */ g65816_op_rtie, g65816_op_eor_idpxb, g65816_op_wdm, g65816_op_eor_srb, /* 4x */ g65816_op_mvp, g65816_op_eor_dpb, g65816_op_lsr_dpb, g65816_op_eor_ildpb, /* 4x */ g65816_op_phab, g65816_op_eor_constb, g65816_op_lsrb, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrb, g65816_op_lsr_addrb, g65816_op_eor_longb,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyb, g65816_op_eor_idpb, g65816_op_eor_isryb, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxb, g65816_op_lsr_dpxb, g65816_op_eor_ildpyb, /* 5x */ g65816_op_cli, g65816_op_eor_addryb, g65816_op_phyb, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxb, g65816_op_lsr_addrxb, g65816_op_eor_longxb,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxb, g65816_op_per, g65816_op_adc_srb, /* 6x */ g65816_op_stz_dpb, g65816_op_adc_dpb, g65816_op_ror_dpb, g65816_op_adc_ildpb, /* 6x */ g65816_op_plab, g65816_op_adc_constb, g65816_op_rorb, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrb, g65816_op_ror_addrb, g65816_op_adc_longb,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyb, g65816_op_adc_idpb, g65816_op_adc_isryb, /* 7x */ g65816_op_stz_dpxb, g65816_op_adc_dpxb, g65816_op_ror_dpxb, g65816_op_adc_ildpyb, /* 7x */ g65816_op_sei, g65816_op_adc_addryb, g65816_op_plyb, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxb, g65816_op_ror_addrxb, g65816_op_adc_longxb,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxb, g65816_op_brl, g65816_op_sta_srb, /* 8x */ g65816_op_sty_dpb, g65816_op_sta_dpb, g65816_op_stx_dpb, g65816_op_sta_ildpb, /* 8x */ g65816_op_deyb, g65816_op_bit_constb, g65816_op_txab, g65816_op_phb, /* 8x */ g65816_op_sty_addrb, g65816_op_sta_addrb, g65816_op_stx_addrb, g65816_op_sta_longb,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyb, g65816_op_sta_idpb, g65816_op_sta_isryb, /* 9x */ g65816_op_sty_dpxb, g65816_op_sta_dpxb, g65816_op_stx_dpyb, g65816_op_sta_ildpyb, /* 9x */ g65816_op_tyab, g65816_op_sta_addryb, g65816_op_txsb, g65816_op_txyb, /* 9x */ g65816_op_stz_addrb, g65816_op_sta_addrxb, g65816_op_stz_addrxb, g65816_op_sta_longxb,
|
||||
/* ax */ g65816_op_ldy_constb, g65816_op_lda_idpxb, g65816_op_ldx_constb, g65816_op_lda_srb, /* ax */ g65816_op_ldy_dpb, g65816_op_lda_dpb, g65816_op_ldx_dpb, g65816_op_lda_ildpb, /* ax */ g65816_op_tayb, g65816_op_lda_constb, g65816_op_taxb, g65816_op_plb, /* ax */ g65816_op_ldy_addrb, g65816_op_lda_addrb, g65816_op_ldx_addrb, g65816_op_lda_longb,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyb, g65816_op_lda_idpb, g65816_op_lda_isryb, /* bx */ g65816_op_ldy_dpxb, g65816_op_lda_dpxb, g65816_op_ldx_dpyb, g65816_op_lda_ildpyb, /* bx */ g65816_op_clv, g65816_op_lda_addryb, g65816_op_tsxb, g65816_op_tyxb, /* bx */ g65816_op_ldy_addrxb, g65816_op_lda_addrxb, g65816_op_ldx_addryb, g65816_op_lda_longxb,
|
||||
|
||||
/* cx */ g65816_op_cpy_constb, g65816_op_cmp_idpxb, g65816_op_rep, g65816_op_cmp_srb, /* cx */ g65816_op_cpy_dpb, g65816_op_cmp_dpb, g65816_op_dec_dpb, g65816_op_cmp_ildpb, /* cx */ g65816_op_inyb, g65816_op_cmp_constb, g65816_op_dexb, g65816_op_wai, /* cx */ g65816_op_cpy_addrb, g65816_op_cmp_addrb, g65816_op_dec_addrb, g65816_op_cmp_longb,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyb, g65816_op_cmp_idpb, g65816_op_cmp_isryb, /* dx */ g65816_op_pei, g65816_op_cmp_dpxb, g65816_op_dec_dpxb, g65816_op_cmp_ildpyb, /* dx */ g65816_op_cld, g65816_op_cmp_addryb, g65816_op_phxb, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxb, g65816_op_dec_addrxb, g65816_op_cmp_longxb,
|
||||
/* ex */ g65816_op_cpx_constb, g65816_op_sbc_idpxb, g65816_op_sep, g65816_op_sbc_srb, /* ex */ g65816_op_cpx_dpb, g65816_op_sbc_dpb, g65816_op_inc_dpb, g65816_op_sbc_ildpb, /* ex */ g65816_op_inxb, g65816_op_sbc_constb, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrb, g65816_op_sbc_addrb, g65816_op_inc_addrb, g65816_op_sbc_longb,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyb, g65816_op_sbc_idpb, g65816_op_sbc_isryb, /* fx */ g65816_op_pea, g65816_op_sbc_dpxb, g65816_op_inc_dpxb, g65816_op_sbc_ildpyb, /* fx */ g65816_op_sed, g65816_op_sbc_addryb, g65816_op_plxb, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxb, g65816_op_inc_addrxb, g65816_op_sbc_longxb
|
||||
};
|
||||
|
||||
vfunc g65816_optbl_MX[256] = { // g65816_optbl_MX, g65816_optbl_MX, g65816_optbl_MX,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxb, g65816_op_cop, g65816_op_ora_srb, /* 0x */ g65816_op_tsb_dpb, g65816_op_ora_dpb, g65816_op_asl_dpb, g65816_op_ora_ildpb, /* 0x */ g65816_op_php, g65816_op_ora_constb, g65816_op_aslb, g65816_op_phd, /* 0x */ g65816_op_tsb_addrb, g65816_op_ora_addrb, g65816_op_asl_addrb, g65816_op_ora_longb,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyb, g65816_op_ora_idpb, g65816_op_ora_isryb, /* 1x */ g65816_op_trb_dpb, g65816_op_ora_dpxb, g65816_op_asl_dpxb, g65816_op_ora_ildpyb, /* 1x */ g65816_op_clc, g65816_op_ora_addryb, g65816_op_incb, g65816_op_tcsn, /* 1x */ g65816_op_trb_addrb, g65816_op_ora_addrxb, g65816_op_asl_addrxb, g65816_op_ora_longxb,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxb, g65816_op_jsr_long, g65816_op_and_srb, /* 2x */ g65816_op_bit_dpb, g65816_op_and_dpb, g65816_op_rol_dpb, g65816_op_and_ildpb, /* 2x */ g65816_op_plp, g65816_op_and_constb, g65816_op_rolb, g65816_op_pld, /* 2x */ g65816_op_bit_addrb, g65816_op_and_addrb, g65816_op_rol_addrb, g65816_op_and_longb,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyb, g65816_op_and_idpb, g65816_op_and_isryb, /* 3x */ g65816_op_bit_dpxb, g65816_op_and_dpxb, g65816_op_rol_dpxb, g65816_op_and_ildpyb, /* 3x */ g65816_op_sec, g65816_op_and_addryb, g65816_op_decb, g65816_op_tscn, /* 3x */ g65816_op_bit_addrxb, g65816_op_and_addrxb, g65816_op_rol_addrxb, g65816_op_and_longxb,
|
||||
|
||||
/* 4x */ g65816_op_rtin, g65816_op_eor_idpxb, g65816_op_wdm, g65816_op_eor_srb, /* 4x */ g65816_op_mvp, g65816_op_eor_dpb, g65816_op_lsr_dpb, g65816_op_eor_ildpb, /* 4x */ g65816_op_phab, g65816_op_eor_constb, g65816_op_lsrb, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrb, g65816_op_lsr_addrb, g65816_op_eor_longb,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyb, g65816_op_eor_idpb, g65816_op_eor_isryb, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxb, g65816_op_lsr_dpxb, g65816_op_eor_ildpyb, /* 5x */ g65816_op_cli, g65816_op_eor_addryb, g65816_op_phyb, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxb, g65816_op_lsr_addrxb, g65816_op_eor_longxb,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxb, g65816_op_per, g65816_op_adc_srb, /* 6x */ g65816_op_stz_dpb, g65816_op_adc_dpb, g65816_op_ror_dpb, g65816_op_adc_ildpb, /* 6x */ g65816_op_plab, g65816_op_adc_constb, g65816_op_rorb, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrb, g65816_op_ror_addrb, g65816_op_adc_longb,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyb, g65816_op_adc_idpb, g65816_op_adc_isryb, /* 7x */ g65816_op_stz_dpxb, g65816_op_adc_dpxb, g65816_op_ror_dpxb, g65816_op_adc_ildpyb, /* 7x */ g65816_op_sei, g65816_op_adc_addryb, g65816_op_plyb, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxb, g65816_op_ror_addrxb, g65816_op_adc_longxb,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxb, g65816_op_brl, g65816_op_sta_srb, /* 8x */ g65816_op_sty_dpb, g65816_op_sta_dpb, g65816_op_stx_dpb, g65816_op_sta_ildpb, /* 8x */ g65816_op_deyb, g65816_op_bit_constb, g65816_op_txab, g65816_op_phb, /* 8x */ g65816_op_sty_addrb, g65816_op_sta_addrb, g65816_op_stx_addrb, g65816_op_sta_longb,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyb, g65816_op_sta_idpb, g65816_op_sta_isryb, /* 9x */ g65816_op_sty_dpxb, g65816_op_sta_dpxb, g65816_op_stx_dpyb, g65816_op_sta_ildpyb, /* 9x */ g65816_op_tyab, g65816_op_sta_addryb, g65816_op_txsb, g65816_op_txyb, /* 9x */ g65816_op_stz_addrb, g65816_op_sta_addrxb, g65816_op_stz_addrxb, g65816_op_sta_longxb,
|
||||
/* ax */ g65816_op_ldy_constb, g65816_op_lda_idpxb, g65816_op_ldx_constb, g65816_op_lda_srb, /* ax */ g65816_op_ldy_dpb, g65816_op_lda_dpb, g65816_op_ldx_dpb, g65816_op_lda_ildpb, /* ax */ g65816_op_tayb, g65816_op_lda_constb, g65816_op_taxb, g65816_op_plb, /* ax */ g65816_op_ldy_addrb, g65816_op_lda_addrb, g65816_op_ldx_addrb, g65816_op_lda_longb,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyb, g65816_op_lda_idpb, g65816_op_lda_isryb, /* bx */ g65816_op_ldy_dpxb, g65816_op_lda_dpxb, g65816_op_ldx_dpyb, g65816_op_lda_ildpyb, /* bx */ g65816_op_clv, g65816_op_lda_addryb, g65816_op_tsxb, g65816_op_tyxb, /* bx */ g65816_op_ldy_addrxb, g65816_op_lda_addrxb, g65816_op_ldx_addryb, g65816_op_lda_longxb,
|
||||
|
||||
/* cx */ g65816_op_cpy_constb, g65816_op_cmp_idpxb, g65816_op_rep, g65816_op_cmp_srb, /* cx */ g65816_op_cpy_dpb, g65816_op_cmp_dpb, g65816_op_dec_dpb, g65816_op_cmp_ildpb, /* cx */ g65816_op_inyb, g65816_op_cmp_constb, g65816_op_dexb, g65816_op_wai, /* cx */ g65816_op_cpy_addrb, g65816_op_cmp_addrb, g65816_op_dec_addrb, g65816_op_cmp_longb,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyb, g65816_op_cmp_idpb, g65816_op_cmp_isryb, /* dx */ g65816_op_pei, g65816_op_cmp_dpxb, g65816_op_dec_dpxb, g65816_op_cmp_ildpyb, /* dx */ g65816_op_cld, g65816_op_cmp_addryb, g65816_op_phxb, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxb, g65816_op_dec_addrxb, g65816_op_cmp_longxb,
|
||||
/* ex */ g65816_op_cpx_constb, g65816_op_sbc_idpxb, g65816_op_sep, g65816_op_sbc_srb, /* ex */ g65816_op_cpx_dpb, g65816_op_sbc_dpb, g65816_op_inc_dpb, g65816_op_sbc_ildpb, /* ex */ g65816_op_inxb, g65816_op_sbc_constb, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrb, g65816_op_sbc_addrb, g65816_op_inc_addrb, g65816_op_sbc_longb,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyb, g65816_op_sbc_idpb, g65816_op_sbc_isryb, /* fx */ g65816_op_pea, g65816_op_sbc_dpxb, g65816_op_inc_dpxb, g65816_op_sbc_ildpyb, /* fx */ g65816_op_sed, g65816_op_sbc_addryb, g65816_op_plxb, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxb, g65816_op_inc_addrxb, g65816_op_sbc_longxb
|
||||
};
|
||||
|
||||
vfunc g65816_optbl_Mx[256] = { // g65816_optbl_Mx, g65816_optbl_Mx, g65816_optbl_Mx,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxb, g65816_op_cop, g65816_op_ora_srb, /* 0x */ g65816_op_tsb_dpb, g65816_op_ora_dpb, g65816_op_asl_dpb, g65816_op_ora_ildpb, /* 0x */ g65816_op_php, g65816_op_ora_constb, g65816_op_aslb, g65816_op_phd, /* 0x */ g65816_op_tsb_addrb, g65816_op_ora_addrb, g65816_op_asl_addrb, g65816_op_ora_longb,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyb, g65816_op_ora_idpb, g65816_op_ora_isryb, /* 1x */ g65816_op_trb_dpb, g65816_op_ora_dpxb, g65816_op_asl_dpxb, g65816_op_ora_ildpyb, /* 1x */ g65816_op_clc, g65816_op_ora_addryb, g65816_op_incb, g65816_op_tcsn, /* 1x */ g65816_op_trb_addrb, g65816_op_ora_addrxb, g65816_op_asl_addrxb, g65816_op_ora_longxb,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxb, g65816_op_jsr_long, g65816_op_and_srb, /* 2x */ g65816_op_bit_dpb, g65816_op_and_dpb, g65816_op_rol_dpb, g65816_op_and_ildpb, /* 2x */ g65816_op_plp, g65816_op_and_constb, g65816_op_rolb, g65816_op_pld, /* 2x */ g65816_op_bit_addrb, g65816_op_and_addrb, g65816_op_rol_addrb, g65816_op_and_longb,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyb, g65816_op_and_idpb, g65816_op_and_isryb, /* 3x */ g65816_op_bit_dpxb, g65816_op_and_dpxb, g65816_op_rol_dpxb, g65816_op_and_ildpyb, /* 3x */ g65816_op_sec, g65816_op_and_addryb, g65816_op_decb, g65816_op_tscn, /* 3x */ g65816_op_bit_addrxb, g65816_op_and_addrxb, g65816_op_rol_addrxb, g65816_op_and_longxb,
|
||||
|
||||
/* 4x */ g65816_op_rtin, g65816_op_eor_idpxb, g65816_op_wdm, g65816_op_eor_srb, /* 4x */ g65816_op_mvp, g65816_op_eor_dpb, g65816_op_lsr_dpb, g65816_op_eor_ildpb, /* 4x */ g65816_op_phab, g65816_op_eor_constb, g65816_op_lsrb, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrb, g65816_op_lsr_addrb, g65816_op_eor_longb,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyb, g65816_op_eor_idpb, g65816_op_eor_isryb, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxb, g65816_op_lsr_dpxb, g65816_op_eor_ildpyb, /* 5x */ g65816_op_cli, g65816_op_eor_addryb, g65816_op_phyw, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxb, g65816_op_lsr_addrxb, g65816_op_eor_longxb,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxb, g65816_op_per, g65816_op_adc_srb, /* 6x */ g65816_op_stz_dpb, g65816_op_adc_dpb, g65816_op_ror_dpb, g65816_op_adc_ildpb, /* 6x */ g65816_op_plab, g65816_op_adc_constb, g65816_op_rorb, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrb, g65816_op_ror_addrb, g65816_op_adc_longb,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyb, g65816_op_adc_idpb, g65816_op_adc_isryb, /* 7x */ g65816_op_stz_dpxb, g65816_op_adc_dpxb, g65816_op_ror_dpxb, g65816_op_adc_ildpyb, /* 7x */ g65816_op_sei, g65816_op_adc_addryb, g65816_op_plyw, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxb, g65816_op_ror_addrxb, g65816_op_adc_longxb,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxb, g65816_op_brl, g65816_op_sta_srb, /* 8x */ g65816_op_sty_dpw, g65816_op_sta_dpb, g65816_op_stx_dpw, g65816_op_sta_ildpb, /* 8x */ g65816_op_deyw, g65816_op_bit_constb, g65816_op_txab, g65816_op_phb, /* 8x */ g65816_op_sty_addrw, g65816_op_sta_addrb, g65816_op_stx_addrw, g65816_op_sta_longb,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyb, g65816_op_sta_idpb, g65816_op_sta_isryb, /* 9x */ g65816_op_sty_dpxw, g65816_op_sta_dpxb, g65816_op_stx_dpyw, g65816_op_sta_ildpyb, /* 9x */ g65816_op_tyab, g65816_op_sta_addryb, g65816_op_txsw, g65816_op_txyw, /* 9x */ g65816_op_stz_addrb, g65816_op_sta_addrxb, g65816_op_stz_addrxb, g65816_op_sta_longxb,
|
||||
/* ax */ g65816_op_ldy_constw, g65816_op_lda_idpxb, g65816_op_ldx_constw, g65816_op_lda_srb, /* ax */ g65816_op_ldy_dpw, g65816_op_lda_dpb, g65816_op_ldx_dpw, g65816_op_lda_ildpb, /* ax */ g65816_op_tayw, g65816_op_lda_constb, g65816_op_taxw, g65816_op_plb, /* ax */ g65816_op_ldy_addrw, g65816_op_lda_addrb, g65816_op_ldx_addrw, g65816_op_lda_longb,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyb, g65816_op_lda_idpb, g65816_op_lda_isryb, /* bx */ g65816_op_ldy_dpxw, g65816_op_lda_dpxb, g65816_op_ldx_dpyw, g65816_op_lda_ildpyb, /* bx */ g65816_op_clv, g65816_op_lda_addryb, g65816_op_tsxw, g65816_op_tyxw, /* bx */ g65816_op_ldy_addrxw, g65816_op_lda_addrxb, g65816_op_ldx_addryw, g65816_op_lda_longxb,
|
||||
|
||||
/* cx */ g65816_op_cpy_constw, g65816_op_cmp_idpxb, g65816_op_rep, g65816_op_cmp_srb, /* cx */ g65816_op_cpy_dpw, g65816_op_cmp_dpb, g65816_op_dec_dpb, g65816_op_cmp_ildpb, /* cx */ g65816_op_inyw, g65816_op_cmp_constb, g65816_op_dexw, g65816_op_wai, /* cx */ g65816_op_cpy_addrw, g65816_op_cmp_addrb, g65816_op_dec_addrb, g65816_op_cmp_longb,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyb, g65816_op_cmp_idpb, g65816_op_cmp_isryb, /* dx */ g65816_op_pei, g65816_op_cmp_dpxb, g65816_op_dec_dpxb, g65816_op_cmp_ildpyb, /* dx */ g65816_op_cld, g65816_op_cmp_addryb, g65816_op_phxw, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxb, g65816_op_dec_addrxb, g65816_op_cmp_longxb,
|
||||
/* ex */ g65816_op_cpx_constw, g65816_op_sbc_idpxb, g65816_op_sep, g65816_op_sbc_srb, /* ex */ g65816_op_cpx_dpw, g65816_op_sbc_dpb, g65816_op_inc_dpb, g65816_op_sbc_ildpb, /* ex */ g65816_op_inxw, g65816_op_sbc_constb, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrw, g65816_op_sbc_addrb, g65816_op_inc_addrb, g65816_op_sbc_longb,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyb, g65816_op_sbc_idpb, g65816_op_sbc_isryb, /* fx */ g65816_op_pea, g65816_op_sbc_dpxb, g65816_op_inc_dpxb, g65816_op_sbc_ildpyb, /* fx */ g65816_op_sed, g65816_op_sbc_addryb, g65816_op_plxw, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxb, g65816_op_inc_addrxb, g65816_op_sbc_longxb
|
||||
};
|
||||
|
||||
vfunc g65816_optbl_mX[256] = { // g65816_optbl_mX, g65816_optbl_mX, g65816_optbl_mX,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxw, g65816_op_cop, g65816_op_ora_srw, /* 0x */ g65816_op_tsb_dpw, g65816_op_ora_dpw, g65816_op_asl_dpw, g65816_op_ora_ildpw, /* 0x */ g65816_op_php, g65816_op_ora_constw, g65816_op_aslw, g65816_op_phd, /* 0x */ g65816_op_tsb_addrw, g65816_op_ora_addrw, g65816_op_asl_addrw, g65816_op_ora_longw,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyw, g65816_op_ora_idpw, g65816_op_ora_isryw, /* 1x */ g65816_op_trb_dpw, g65816_op_ora_dpxw, g65816_op_asl_dpxw, g65816_op_ora_ildpyw, /* 1x */ g65816_op_clc, g65816_op_ora_addryw, g65816_op_incw, g65816_op_tcsn, /* 1x */ g65816_op_trb_addrw, g65816_op_ora_addrxw, g65816_op_asl_addrxw, g65816_op_ora_longxw,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxw, g65816_op_jsr_long, g65816_op_and_srw, /* 2x */ g65816_op_bit_dpw, g65816_op_and_dpw, g65816_op_rol_dpw, g65816_op_and_ildpw, /* 2x */ g65816_op_plp, g65816_op_and_constw, g65816_op_rolw, g65816_op_pld, /* 2x */ g65816_op_bit_addrw, g65816_op_and_addrw, g65816_op_rol_addrw, g65816_op_and_longw,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyw, g65816_op_and_idpw, g65816_op_and_isryw, /* 3x */ g65816_op_bit_dpxw, g65816_op_and_dpxw, g65816_op_rol_dpxw, g65816_op_and_ildpyw, /* 3x */ g65816_op_sec, g65816_op_and_addryw, g65816_op_decw, g65816_op_tscn, /* 3x */ g65816_op_bit_addrxw, g65816_op_and_addrxw, g65816_op_rol_addrxw, g65816_op_and_longxw,
|
||||
|
||||
/* 4x */ g65816_op_rtin, g65816_op_eor_idpxw, g65816_op_wdm, g65816_op_eor_srw, /* 4x */ g65816_op_mvp, g65816_op_eor_dpw, g65816_op_lsr_dpw, g65816_op_eor_ildpw, /* 4x */ g65816_op_phaw, g65816_op_eor_constw, g65816_op_lsrw, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrw, g65816_op_lsr_addrw, g65816_op_eor_longw,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyw, g65816_op_eor_idpw, g65816_op_eor_isryw, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxw, g65816_op_lsr_dpxw, g65816_op_eor_ildpyw, /* 5x */ g65816_op_cli, g65816_op_eor_addryw, g65816_op_phyb, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxw, g65816_op_lsr_addrxw, g65816_op_eor_longxw,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxw, g65816_op_per, g65816_op_adc_srw, /* 6x */ g65816_op_stz_dpw, g65816_op_adc_dpw, g65816_op_ror_dpw, g65816_op_adc_ildpw, /* 6x */ g65816_op_plaw, g65816_op_adc_constw, g65816_op_rorw, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrw, g65816_op_ror_addrw, g65816_op_adc_longw,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyw, g65816_op_adc_idpw, g65816_op_adc_isryw, /* 7x */ g65816_op_stz_dpxw, g65816_op_adc_dpxw, g65816_op_ror_dpxw, g65816_op_adc_ildpyw, /* 7x */ g65816_op_sei, g65816_op_adc_addryw, g65816_op_plyb, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxw, g65816_op_ror_addrxw, g65816_op_adc_longxw,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxw, g65816_op_brl, g65816_op_sta_srw, /* 8x */ g65816_op_sty_dpb, g65816_op_sta_dpw, g65816_op_stx_dpb, g65816_op_sta_ildpw, /* 8x */ g65816_op_deyb, g65816_op_bit_constw, g65816_op_txaw, g65816_op_phb, /* 8x */ g65816_op_sty_addrb, g65816_op_sta_addrw, g65816_op_stx_addrb, g65816_op_sta_longw,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyw, g65816_op_sta_idpw, g65816_op_sta_isryw, /* 9x */ g65816_op_sty_dpxb, g65816_op_sta_dpxw, g65816_op_stx_dpyb, g65816_op_sta_ildpyw, /* 9x */ g65816_op_tyaw, g65816_op_sta_addryw, g65816_op_txsb, g65816_op_txyb, /* 9x */ g65816_op_stz_addrw, g65816_op_sta_addrxw, g65816_op_stz_addrxw, g65816_op_sta_longxw,
|
||||
/* ax */ g65816_op_ldy_constb, g65816_op_lda_idpxw, g65816_op_ldx_constb, g65816_op_lda_srw, /* ax */ g65816_op_ldy_dpb, g65816_op_lda_dpw, g65816_op_ldx_dpb, g65816_op_lda_ildpw, /* ax */ g65816_op_tayb, g65816_op_lda_constw, g65816_op_taxb, g65816_op_plb, /* ax */ g65816_op_ldy_addrb, g65816_op_lda_addrw, g65816_op_ldx_addrb, g65816_op_lda_longw,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyw, g65816_op_lda_idpw, g65816_op_lda_isryw, /* bx */ g65816_op_ldy_dpxb, g65816_op_lda_dpxw, g65816_op_ldx_dpyb, g65816_op_lda_ildpyw, /* bx */ g65816_op_clv, g65816_op_lda_addryw, g65816_op_tsxb, g65816_op_tyxb, /* bx */ g65816_op_ldy_addrxb, g65816_op_lda_addrxw, g65816_op_ldx_addryb, g65816_op_lda_longxw,
|
||||
|
||||
/* cx */ g65816_op_cpy_constb, g65816_op_cmp_idpxw, g65816_op_rep, g65816_op_cmp_srw, /* cx */ g65816_op_cpy_dpb, g65816_op_cmp_dpw, g65816_op_dec_dpw, g65816_op_cmp_ildpw, /* cx */ g65816_op_inyb, g65816_op_cmp_constw, g65816_op_dexb, g65816_op_wai, /* cx */ g65816_op_cpy_addrb, g65816_op_cmp_addrw, g65816_op_dec_addrw, g65816_op_cmp_longw,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyw, g65816_op_cmp_idpw, g65816_op_cmp_isryw, /* dx */ g65816_op_pei, g65816_op_cmp_dpxw, g65816_op_dec_dpxw, g65816_op_cmp_ildpyw, /* dx */ g65816_op_cld, g65816_op_cmp_addryw, g65816_op_phxb, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxw, g65816_op_dec_addrxw, g65816_op_cmp_longxw,
|
||||
/* ex */ g65816_op_cpx_constb, g65816_op_sbc_idpxw, g65816_op_sep, g65816_op_sbc_srw, /* ex */ g65816_op_cpx_dpb, g65816_op_sbc_dpw, g65816_op_inc_dpw, g65816_op_sbc_ildpw, /* ex */ g65816_op_inxb, g65816_op_sbc_constw, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrb, g65816_op_sbc_addrw, g65816_op_inc_addrw, g65816_op_sbc_longw,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyw, g65816_op_sbc_idpw, g65816_op_sbc_isryw, /* fx */ g65816_op_pea, g65816_op_sbc_dpxw, g65816_op_inc_dpxw, g65816_op_sbc_ildpyw, /* fx */ g65816_op_sed, g65816_op_sbc_addryw, g65816_op_plxb, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxw, g65816_op_inc_addrxw, g65816_op_sbc_longxw
|
||||
};
|
||||
|
||||
vfunc g65816_optbl_mx[256] = { // g65816_optbl_mx, g65816_optbl_mx, g65816_optbl_mx,
|
||||
// ----------------------x0, ----------------------x1, ----------------------x2, ----------------------x3, -------- ----------------------x4, ----------------------x5, ----------------------x6, ----------------------x7, -------- ----------------------x8, ----------------------x9, ----------------------xa, ----------------------xb, -------- ----------------------xc, ----------------------xd, ----------------------xe, ----------------------xf,
|
||||
/* 0x */ g65816_op_brk, g65816_op_ora_idpxw, g65816_op_cop, g65816_op_ora_srw, /* 0x */ g65816_op_tsb_dpw, g65816_op_ora_dpw, g65816_op_asl_dpw, g65816_op_ora_ildpw, /* 0x */ g65816_op_php, g65816_op_ora_constw, g65816_op_aslw, g65816_op_phd, /* 0x */ g65816_op_tsb_addrw, g65816_op_ora_addrw, g65816_op_asl_addrw, g65816_op_ora_longw,
|
||||
/* 1x */ g65816_op_bpl, g65816_op_ora_idpyw, g65816_op_ora_idpw, g65816_op_ora_isryw, /* 1x */ g65816_op_trb_dpw, g65816_op_ora_dpxw, g65816_op_asl_dpxw, g65816_op_ora_ildpyw, /* 1x */ g65816_op_clc, g65816_op_ora_addryw, g65816_op_incw, g65816_op_tcsn, /* 1x */ g65816_op_trb_addrw, g65816_op_ora_addrxw, g65816_op_asl_addrxw, g65816_op_ora_longxw,
|
||||
/* 2x */ g65816_op_jsr_addr, g65816_op_and_idpxw, g65816_op_jsr_long, g65816_op_and_srw, /* 2x */ g65816_op_bit_dpw, g65816_op_and_dpw, g65816_op_rol_dpw, g65816_op_and_ildpw, /* 2x */ g65816_op_plp, g65816_op_and_constw, g65816_op_rolw, g65816_op_pld, /* 2x */ g65816_op_bit_addrw, g65816_op_and_addrw, g65816_op_rol_addrw, g65816_op_and_longw,
|
||||
/* 3x */ g65816_op_bmi, g65816_op_and_idpyw, g65816_op_and_idpw, g65816_op_and_isryw, /* 3x */ g65816_op_bit_dpxw, g65816_op_and_dpxw, g65816_op_rol_dpxw, g65816_op_and_ildpyw, /* 3x */ g65816_op_sec, g65816_op_and_addryw, g65816_op_decw, g65816_op_tscn, /* 3x */ g65816_op_bit_addrxw, g65816_op_and_addrxw, g65816_op_rol_addrxw, g65816_op_and_longxw,
|
||||
|
||||
/* 4x */ g65816_op_rtin, g65816_op_eor_idpxw, g65816_op_wdm, g65816_op_eor_srw, /* 4x */ g65816_op_mvp, g65816_op_eor_dpw, g65816_op_lsr_dpw, g65816_op_eor_ildpw, /* 4x */ g65816_op_phaw, g65816_op_eor_constw, g65816_op_lsrw, g65816_op_phk, /* 4x */ g65816_op_jmp_addr, g65816_op_eor_addrw, g65816_op_lsr_addrw, g65816_op_eor_longw,
|
||||
/* 5x */ g65816_op_bvc, g65816_op_eor_idpyw, g65816_op_eor_idpw, g65816_op_eor_isryw, /* 5x */ g65816_op_mvn, g65816_op_eor_dpxw, g65816_op_lsr_dpxw, g65816_op_eor_ildpyw, /* 5x */ g65816_op_cli, g65816_op_eor_addryw, g65816_op_phyw, g65816_op_tcd, /* 5x */ g65816_op_jmp_long, g65816_op_eor_addrxw, g65816_op_lsr_addrxw, g65816_op_eor_longxw,
|
||||
/* 6x */ g65816_op_rts, g65816_op_adc_idpxw, g65816_op_per, g65816_op_adc_srw, /* 6x */ g65816_op_stz_dpw, g65816_op_adc_dpw, g65816_op_ror_dpw, g65816_op_adc_ildpw, /* 6x */ g65816_op_plaw, g65816_op_adc_constw, g65816_op_rorw, g65816_op_rtl, /* 6x */ g65816_op_jmp_iaddr, g65816_op_adc_addrw, g65816_op_ror_addrw, g65816_op_adc_longw,
|
||||
/* 7x */ g65816_op_bvs, g65816_op_adc_idpyw, g65816_op_adc_idpw, g65816_op_adc_isryw, /* 7x */ g65816_op_stz_dpxw, g65816_op_adc_dpxw, g65816_op_ror_dpxw, g65816_op_adc_ildpyw, /* 7x */ g65816_op_sei, g65816_op_adc_addryw, g65816_op_plyw, g65816_tdc, /* 7x */ g65816_op_jmp_iaddrx, g65816_op_adc_addrxw, g65816_op_ror_addrxw, g65816_op_adc_longxw,
|
||||
|
||||
/* 8x */ g65816_op_bra, g65816_op_sta_idpxw, g65816_op_brl, g65816_op_sta_srw, /* 8x */ g65816_op_sty_dpw, g65816_op_sta_dpw, g65816_op_stx_dpw, g65816_op_sta_ildpw, /* 8x */ g65816_op_deyw, g65816_op_bit_constw, g65816_op_txaw, g65816_op_phb, /* 8x */ g65816_op_sty_addrw, g65816_op_sta_addrw, g65816_op_stx_addrw, g65816_op_sta_longw,
|
||||
/* 9x */ g65816_op_bcc, g65816_op_sta_idpyw, g65816_op_sta_idpw, g65816_op_sta_isryw, /* 9x */ g65816_op_sty_dpxw, g65816_op_sta_dpxw, g65816_op_stx_dpyw, g65816_op_sta_ildpyw, /* 9x */ g65816_op_tyaw, g65816_op_sta_addryw, g65816_op_txsw, g65816_op_txyw, /* 9x */ g65816_op_stz_addrw, g65816_op_sta_addrxw, g65816_op_stz_addrxw, g65816_op_sta_longxw,
|
||||
/* ax */ g65816_op_ldy_constw, g65816_op_lda_idpxw, g65816_op_ldx_constw, g65816_op_lda_srw, /* ax */ g65816_op_ldy_dpw, g65816_op_lda_dpw, g65816_op_ldx_dpw, g65816_op_lda_ildpw, /* ax */ g65816_op_tayw, g65816_op_lda_constw, g65816_op_taxw, g65816_op_plb, /* ax */ g65816_op_ldy_addrw, g65816_op_lda_addrw, g65816_op_ldx_addrw, g65816_op_lda_longw,
|
||||
/* bx */ g65816_op_bcs, g65816_op_lda_idpyw, g65816_op_lda_idpw, g65816_op_lda_isryw, /* bx */ g65816_op_ldy_dpxw, g65816_op_lda_dpxw, g65816_op_ldx_dpyw, g65816_op_lda_ildpyw, /* bx */ g65816_op_clv, g65816_op_lda_addryw, g65816_op_tsxw, g65816_op_tyxw, /* bx */ g65816_op_ldy_addrxw, g65816_op_lda_addrxw, g65816_op_ldx_addryw, g65816_op_lda_longxw,
|
||||
|
||||
/* cx */ g65816_op_cpy_constw, g65816_op_cmp_idpxw, g65816_op_rep, g65816_op_cmp_srw, /* cx */ g65816_op_cpy_dpw, g65816_op_cmp_dpw, g65816_op_dec_dpw, g65816_op_cmp_ildpw, /* cx */ g65816_op_inyw, g65816_op_cmp_constw, g65816_op_dexw, g65816_op_wai, /* cx */ g65816_op_cpy_addrw, g65816_op_cmp_addrw, g65816_op_dec_addrw, g65816_op_cmp_longw,
|
||||
/* dx */ g65816_op_bne, g65816_op_cmp_idpyw, g65816_op_cmp_idpw, g65816_op_cmp_isryw, /* dx */ g65816_op_pei, g65816_op_cmp_dpxw, g65816_op_dec_dpxw, g65816_op_cmp_ildpyw, /* dx */ g65816_op_cld, g65816_op_cmp_addryw, g65816_op_phxw, g65816_op_stp, /* dx */ g65816_op_jmp_iladdr, g65816_op_cmp_addrxw, g65816_op_dec_addrxw, g65816_op_cmp_longxw,
|
||||
/* ex */ g65816_op_cpx_constw, g65816_op_sbc_idpxw, g65816_op_sep, g65816_op_sbc_srw, /* ex */ g65816_op_cpx_dpw, g65816_op_sbc_dpw, g65816_op_inc_dpw, g65816_op_sbc_ildpw, /* ex */ g65816_op_inxw, g65816_op_sbc_constw, g65816_op_nop, g65816_op_xba, /* ex */ g65816_op_cpx_addrw, g65816_op_sbc_addrw, g65816_op_inc_addrw, g65816_op_sbc_longw,
|
||||
/* fx */ g65816_op_beq, g65816_op_sbc_idpyw, g65816_op_sbc_idpw, g65816_op_sbc_isryw, /* fx */ g65816_op_pea, g65816_op_sbc_dpxw, g65816_op_inc_dpxw, g65816_op_sbc_ildpyw, /* fx */ g65816_op_sed, g65816_op_sbc_addryw, g65816_op_plxw, g65816_op_xce, /* fx */ g65816_op_jsr_iaddrx, g65816_op_sbc_addrxw, g65816_op_inc_addrxw, g65816_op_sbc_longxw
|
||||
};
|
||||
@@ -1,526 +0,0 @@
|
||||
void g65816_flags_adc_b(void) {
|
||||
int r = gx816->regs.a.b + gx816->op.r.b + (gx816->regs.p & PF_C);
|
||||
//bcd
|
||||
if(gx816->regs.p & PF_D) {
|
||||
if(((r ) & 15) > 9)r += 6;
|
||||
if(((r >> 4) & 15) > 9)r += 6 << 4;
|
||||
}
|
||||
|
||||
g65816_testn(r & 0x80);
|
||||
g65816_testv(~(gx816->regs.a.b ^ gx816->op.r.b) & (gx816->regs.a.b ^ (byte)r) & 0x80);
|
||||
g65816_testz((byte)r == 0);
|
||||
g65816_testc(r > 0xff);
|
||||
gx816->regs.a.b = r;
|
||||
}
|
||||
|
||||
void g65816_flags_adc_w(void) {
|
||||
int r = gx816->regs.a.w + gx816->op.r.w + (gx816->regs.p & PF_C);
|
||||
//bcd
|
||||
if(gx816->regs.p & PF_D) {
|
||||
if(((r ) & 15) > 9)r += 6;
|
||||
if(((r >> 4) & 15) > 9)r += 6 << 4;
|
||||
if(((r >> 8) & 15) > 9)r += 6 << 8;
|
||||
if(((r >> 12) & 15) > 9)r += 6 << 12;
|
||||
}
|
||||
|
||||
g65816_testn(r & 0x8000);
|
||||
g65816_testv(~(gx816->regs.a.w ^ gx816->op.r.w) & (gx816->regs.a.w ^ (word)r) & 0x8000);
|
||||
g65816_testz((word)r == 0);
|
||||
g65816_testc(r > 0xffff);
|
||||
gx816->regs.a.w = r;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x69: adc #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_constb(void) {
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_constw(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x6d: adc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_adc_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7d: adc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_adc_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x65: adc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x72: adc (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x67: adc [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x6f: adc long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_adc_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_adc_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7f: adc long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_adc_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_adc_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x79: adc addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_adc_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x75: adc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_adc_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x61: adc (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x71: adc (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x77: adc [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x63: adc sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x73: adc (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_adc_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_adc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_adc_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_adc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,504 +0,0 @@
|
||||
void g65816_flags_and_b() {
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
}
|
||||
|
||||
void g65816_flags_and_w() {
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x29: and #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_constb(void) {
|
||||
gx816->regs.a.b &= gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_constw(void) {
|
||||
gx816->regs.a.w &= gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2d: and addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_and_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3d: and addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_and_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x25: and dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x32: and (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x27: and [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2f: and long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_and_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_and_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3f: and long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_and_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_and_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x39: and addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_and_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x35: and dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_and_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x21: and (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x31: and (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x37: and [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x23: and sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x33: and (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_and_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.b &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_and_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_and_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.p.l &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->regs.a.p.h &= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_and_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,508 +0,0 @@
|
||||
void g65816_flags_cmp_b() {
|
||||
int r = gx816->regs.a.b - gx816->op.r.b;
|
||||
g65816_testn(r & 0x80);
|
||||
g65816_testz((byte)r == 0);
|
||||
g65816_testc(r >= 0);
|
||||
}
|
||||
|
||||
void g65816_flags_cmp_w() {
|
||||
int r = gx816->regs.a.w - gx816->op.r.w;
|
||||
g65816_testn(r & 0x8000);
|
||||
g65816_testz((word)r == 0);
|
||||
g65816_testc(r >= 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xc9: cmp #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_constb(void) {
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_constw(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xcd: cmp addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdd: cmp addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xc5: cmp dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd2: cmp (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xc7: cmp [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xcf: cmp long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdf: cmp long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd9: cmp addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd5: cmp dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xc1: cmp (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd1: cmp (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd7: cmp [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xc3: cmp sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xd3: cmp (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_cmp_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_cmp_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_cmp_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_cmp_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,504 +0,0 @@
|
||||
void g65816_flags_eor_b() {
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
}
|
||||
|
||||
void g65816_flags_eor_w() {
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x49: eor #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_constb(void) {
|
||||
gx816->regs.a.b ^= gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_constw(void) {
|
||||
gx816->regs.a.w ^= gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x4d: eor addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_eor_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5d: eor addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_eor_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x45: eor dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x52: eor (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x47: eor [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x4f: eor long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_eor_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_eor_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5f: eor long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_eor_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_eor_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x59: eor addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_eor_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x55: eor dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_eor_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x41: eor (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x51: eor (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x57: eor [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x43: eor sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x53: eor (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_eor_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.b ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_eor_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_eor_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.p.l ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->regs.a.p.h ^= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_eor_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,511 +0,0 @@
|
||||
/*****************
|
||||
*** 0x1a: inc ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_incb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.a.b++;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_incw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.a.w++;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xee: inc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_inc_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.b++;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_inc_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.w++;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xfe: inc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_inc_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b++;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_inc_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.w++;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xe6: inc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_inc_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b++;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_inc_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.w++;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf6: inc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_inc_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.b++;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_inc_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.w++;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xe8: inx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_inxb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.x++;
|
||||
gx816->regs.x &= 0xff;
|
||||
g65816_testn(gx816->regs.x & 0x80);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_inxw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.x++;
|
||||
g65816_testn(gx816->regs.x & 0x8000);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xc8: iny ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_inyb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.y++;
|
||||
gx816->regs.y &= 0xff;
|
||||
g65816_testn(gx816->regs.y & 0x80);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_inyw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.y++;
|
||||
g65816_testn(gx816->regs.y & 0x8000);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x3a: dec ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_decb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.a.b--;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_decw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.a.w--;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xce: dec addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_dec_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.b--;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_dec_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.w--;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xde: dec addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_dec_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b--;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_dec_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.w--;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xc6: dec dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_dec_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b--;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_dec_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.w--;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd6: dec dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_dec_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.b--;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_dec_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->op.r.w--;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xca: dex ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_dexb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.x--;
|
||||
gx816->regs.x &= 0xff;
|
||||
g65816_testn(gx816->regs.x & 0x80);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_dexw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.x--;
|
||||
g65816_testn(gx816->regs.x & 0x8000);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x88: dey ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_deyb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.y--;
|
||||
gx816->regs.y &= 0xff;
|
||||
g65816_testn(gx816->regs.y & 0x80);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_deyw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
gx816->regs.y--;
|
||||
g65816_testn(gx816->regs.y & 0x8000);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
@@ -1,504 +0,0 @@
|
||||
void g65816_flags_lda_b(void) {
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
}
|
||||
|
||||
void g65816_flags_lda_w(void) {
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xa9: lda #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_constb(void) {
|
||||
gx816->regs.a.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_constw(void) {
|
||||
gx816->regs.a.w = gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xad: lda addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lda_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xbd: lda addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lda_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xa5: lda dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb2: lda (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xa7: lda [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xaf: lda long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_lda_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_lda_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xbf: lda long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_lda_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_lda_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb9: lda addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lda_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb5: lda dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_lda_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xa1: lda (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb1: lda (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb7: lda [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xa3: lda sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xb3: lda (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_lda_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_lda_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lda_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->regs.a.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_lda_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,504 +0,0 @@
|
||||
void g65816_flags_ora_b() {
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
}
|
||||
|
||||
void g65816_flags_ora_w() {
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x09: ora #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_constb(void) {
|
||||
gx816->regs.a.b |= gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_constw(void) {
|
||||
gx816->regs.a.w |= gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0d: ora addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ora_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1d: ora addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ora_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x05: ora dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x12: ora (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x07: ora [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0f: ora long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_ora_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_ora_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1f: ora long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_ora_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_ora_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x19: ora addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ora_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x15: ora dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_ora_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x01: ora (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x11: ora (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x17: ora [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x03: ora sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x13: ora (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_ora_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.b |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_ora_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ora_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->regs.a.p.l |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->regs.a.p.h |= gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_ora_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,497 +0,0 @@
|
||||
/**********************
|
||||
*** 0x4c: jmp addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_addr(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x5c: jml long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] pbr,pc+3 ; new pbr
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_long(void) {
|
||||
gx816->regs.pc = gx816->read_operand(3); //1-4 [op fetch]
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x6c: jmp (addr) ***
|
||||
************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,aa ; new pcl
|
||||
[5] 0,aa+1 ; new pch
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_iaddr(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 1); //5 [read high]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x7c: jmp (addr,x) ***
|
||||
**************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] pbr,aa+x ; new pcl
|
||||
[6] pbr,aa+x+1 ; new pch
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_iaddrx(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x + 1); //6 [read high]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdc: jmp [addr] ***
|
||||
************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,aa ; new pcl
|
||||
[5] 0,aa+1 ; new pch
|
||||
[6] 0,aa+2 ; new pbr
|
||||
*/
|
||||
|
||||
void g65816_op_jmp_iladdr(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 1); //5 [read high]
|
||||
gx816->op.r.p.b = gx816->op_read(OPMODE_ADDR, gx816->op.aa.w + 2); //6 [read bank]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.l;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x20: jsr addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] 0,s ; pch
|
||||
[6] 0,s-1 ; pcl
|
||||
*/
|
||||
|
||||
void g65816_op_jsr_addr(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->regs.pc += 2;
|
||||
gx816->stack_write(gx816->regs.pc >> 8); //5 [write high]
|
||||
gx816->stack_write(gx816->regs.pc); //6 [write low]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x22: jsl long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] 0,s ; pbr
|
||||
[5] 0,s ; io
|
||||
[6] pbr,pc+3 ; new pbr
|
||||
[7] 0,s-1 ; pch
|
||||
[8] 0,s-2 ; pcl
|
||||
*/
|
||||
|
||||
void g65816_op_jsr_long(void) {
|
||||
gx816->op.r.l = gx816->read_operand(3); //1-3,6 [op fetch]
|
||||
gx816->regs.pc += 3;
|
||||
gx816->stack_write(gx816->regs.pc >> 16); //4 [write bank]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
gx816->stack_write(gx816->regs.pc >> 8); //7 [write high]
|
||||
gx816->stack_write(gx816->regs.pc); //8 [write low]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.l;
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xfc: jsr (addr,x) ***
|
||||
**************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] 0,s ; pch
|
||||
[4] 0,s-1 ; pcl
|
||||
[5] pbr,pc+2 ; aah
|
||||
[6] pbr,pc+2 ; io
|
||||
[7] pbr,aa+x ; new pcl
|
||||
[8] pbr,aa+x+1 ; new pch
|
||||
*/
|
||||
|
||||
void g65816_op_jsr_iaddrx(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1,2,5 [op fetch]
|
||||
gx816->regs.pc += 2;
|
||||
gx816->stack_write(gx816->regs.pc >> 8); //3 [write high]
|
||||
gx816->stack_write(gx816->regs.pc); //4 [write low]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_PBR, gx816->op.aa.w + gx816->regs.x + 1); //8 [read high]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x40: rti ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; p
|
||||
[5] 0,s+2 ; new pcl
|
||||
[6] 0,s+3 ; new pch
|
||||
[7] 0,s+4 ; pbr [7]
|
||||
*/
|
||||
|
||||
void g65816_op_rtie(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.p = gx816->stack_read(); //4 [read p]
|
||||
gx816->op.r.p.l = gx816->stack_read(); //5 [read pcl]
|
||||
gx816->op.r.p.h = gx816->stack_read(); //6 [read pch]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
|
||||
gx816->regs.p &= ~ PF_I;
|
||||
}
|
||||
|
||||
void g65816_op_rtin(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.p = gx816->stack_read(); //4 [read p]
|
||||
gx816->op.r.p.l = gx816->stack_read(); //5 [read pcl]
|
||||
gx816->op.r.p.h = gx816->stack_read(); //6 [read pch]
|
||||
gx816->op.r.p.b = gx816->stack_read(); //7 [read pbr]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.l;
|
||||
if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
|
||||
gx816->regs.p &= ~ PF_I;
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x60: rts ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; pcl
|
||||
[5] 0,s+2 ; pch
|
||||
[6] 0,s+2 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_rts(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->op.r.p.l = gx816->stack_read(); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->stack_read(); //5 [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | gx816->op.r.w;
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x6b: rtl ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; pcl
|
||||
[5] 0,s+2 ; pch
|
||||
[6] 0,s+3 ; pbr
|
||||
*/
|
||||
|
||||
void g65816_op_rtl(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->op.r.p.l = gx816->stack_read(); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->stack_read(); //5 [read high]
|
||||
gx816->op.r.p.b = gx816->stack_read(); //6 [read bank]
|
||||
|
||||
gx816->regs.pc = gx816->op.r.l;
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x80: bra near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bra(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*********************
|
||||
*** 0x82: brl far ***
|
||||
*********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; offset low
|
||||
[3] pbr,pc+2 ; offset high
|
||||
[4] pbr,pc+2 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_brl(void) {
|
||||
word r;
|
||||
gx816->op.r.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
r = gx816->regs.pc + (signed short)gx816->op.r.w;
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x90: bcc near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bcc(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(!(gx816->regs.p & PF_C)) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb0: bcs near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bcs(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(gx816->regs.p & PF_C) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd0: bne near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bne(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(!(gx816->regs.p & PF_Z)) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf0: beq near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_beq(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(gx816->regs.p & PF_Z) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x10: bpl near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bpl(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(!(gx816->regs.p & PF_N)) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x30: bmi near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bmi(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(gx816->regs.p & PF_N) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x50: bvc near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bvc(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(!(gx816->regs.p & PF_V)) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x70: bvs near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
|
||||
void g65816_op_bvs(void) {
|
||||
word r;
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
if(gx816->regs.p & PF_V) {
|
||||
snes_time->add_cpu_icycles(1); //2a [i/o]
|
||||
r = gx816->regs.pc + (signed char)gx816->op.r.b;
|
||||
if(gx816->regs.e == true) {
|
||||
if((gx816->regs.pc & 0xff00) != ((r + 2) & 0xff00)) {
|
||||
snes_time->add_cpu_icycles(1); //2b [i/o]
|
||||
}
|
||||
}
|
||||
gx816->regs.pc = (gx816->regs.pc & 0xff0000) | r;
|
||||
}
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,526 +0,0 @@
|
||||
void g65816_flags_sbc_b() {
|
||||
int r = gx816->regs.a.b - gx816->op.r.b - !(gx816->regs.p & PF_C);
|
||||
//bcd
|
||||
if(gx816->regs.p & PF_D) {
|
||||
if(((r ) & 15) > 9)r -= 6;
|
||||
if(((r >> 4) & 15) > 9)r -= 6 << 4;
|
||||
}
|
||||
|
||||
g65816_testn(r & 0x80);
|
||||
g65816_testv((gx816->regs.a.b ^ gx816->op.r.b) & (gx816->regs.a.b ^ (byte)r) & 0x80);
|
||||
g65816_testz((byte)r == 0);
|
||||
g65816_testc(r >= 0);
|
||||
gx816->regs.a.b = r;
|
||||
}
|
||||
|
||||
void g65816_flags_sbc_w() {
|
||||
int r = gx816->regs.a.w - gx816->op.r.w - !(gx816->regs.p & PF_C);
|
||||
//bcd
|
||||
if(gx816->regs.p & PF_D) {
|
||||
if(((r ) & 15) > 9)r -= 6;
|
||||
if(((r >> 4) & 15) > 9)r -= 6 << 4;
|
||||
if(((r >> 8) & 15) > 9)r -= 6 << 8;
|
||||
if(((r >> 12) & 15) > 9)r -= 6 << 12;
|
||||
}
|
||||
|
||||
g65816_testn(r & 0x8000);
|
||||
g65816_testv((gx816->regs.a.w ^ gx816->op.r.w) & (gx816->regs.a.w ^ (word)r) & 0x8000);
|
||||
g65816_testz((word)r == 0);
|
||||
g65816_testc(r >= 0);
|
||||
gx816->regs.a.w = r;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xe9: sbc #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_constb(void) {
|
||||
gx816->op.r.b = gx816->read_operand(1); //1,2 [op fetch]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_constw(void) {
|
||||
gx816->op.r.w = gx816->read_operand(2); //1,2,2a [op fetch]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xed: sbc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xfd: sbc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.x); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xe5: sbc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf2: sbc (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //5a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xe7: sbc [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //6a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xef: sbc long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + 1); //5a [read]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xff: sbc long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x); //5 [read]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1); //5a [read]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf9: sbc addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //3a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf5: sbc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xe1: sbc (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //6 [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf1: sbc (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_cond(4, gx816->op.aa.w, gx816->op.aa.w + gx816->regs.y); //4a [pbc or p.x=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //5a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf7: sbc [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y); //6 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1); //6a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xe3: sbc sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //4a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xf3: sbc (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sbc_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read]
|
||||
|
||||
g65816_flags_sbc_b();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sbc_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y); //7 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1); //7a [read high]
|
||||
|
||||
g65816_flags_sbc_w();
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,873 +0,0 @@
|
||||
/*****************
|
||||
*** 0x0a: asl ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_aslb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.b & 0x80);
|
||||
gx816->regs.a.b <<= 1;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_aslw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.w & 0x8000);
|
||||
gx816->regs.a.w <<= 1;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0e: asl addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_asl_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_asl_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1e: asl addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_asl_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_asl_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x06: asl dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_asl_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_asl_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x16: asl dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_asl_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_asl_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x4a: lsr ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_lsrb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.b & 0x01);
|
||||
gx816->regs.a.b >>= 1;
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_lsrw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.w & 0x0001);
|
||||
gx816->regs.a.w >>= 1;
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
*** 0x4e: lsr addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_lsr_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lsr_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5e: lsr addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_lsr_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_lsr_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x46: lsr dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_lsr_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lsr_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x56: lsr dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_lsr_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_lsr_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_clrn();
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x2a: rol ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_rolb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.b & 0x80);
|
||||
gx816->regs.a.b <<= 1;
|
||||
gx816->regs.a.b |= c;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_rolw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.w & 0x8000);
|
||||
gx816->regs.a.w <<= 1;
|
||||
gx816->regs.a.w |= c;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2e: rol addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_rol_addrb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_rol_addrw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3e: rol addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_rol_addrxb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_rol_addrxw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x26: rol dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_rol_dpb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_rol_dpw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x36: rol dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_rol_dpxb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x01:0x00;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b <<= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_rol_dpxw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x0001:0x0000;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x8000);
|
||||
gx816->op.r.w <<= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x6a: ror ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
|
||||
void g65816_op_rorb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.b & 0x01);
|
||||
gx816->regs.a.b >>= 1;
|
||||
gx816->regs.a.b |= c;
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_rorw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
|
||||
g65816_testc(gx816->regs.a.w & 0x0001);
|
||||
gx816->regs.a.w >>= 1;
|
||||
gx816->regs.a.w |= c;
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
*** 0x6e: ror addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_ror_addrb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ror_addrw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7e: ror addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_ror_addrxb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.b); //7 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_ror_addrxw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x); //5 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1); //5a [read high]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->op.r.p.h); //7a [write high]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->op.r.p.l); //7 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x66: ror dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_ror_dpb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x01);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.b); //5 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ror_dpw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //3a [read high]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x0001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->op.r.p.h); //5a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->op.r.p.l); //5 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x76: ror dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
|
||||
void g65816_op_ror_dpxb(void) {
|
||||
byte c = (gx816->regs.p & PF_C)?0x80:0x00;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.b = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.b & 0x80);
|
||||
gx816->op.r.b >>= 1;
|
||||
gx816->op.r.b |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.b); //6 [write]
|
||||
|
||||
g65816_testn(gx816->op.r.b & 0x80);
|
||||
g65816_testz(gx816->op.r.b == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_ror_dpxw(void) {
|
||||
word c = (gx816->regs.p & PF_C)?0x8000:0x0000;
|
||||
gx816->op.dp = gx816->read_operand(1); //1-2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.r.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [read low]
|
||||
gx816->op.r.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //4a [read high]
|
||||
snes_time->add_cpu_icycles(1); //5 [i/o]
|
||||
g65816_testc(gx816->op.r.w & 0x001);
|
||||
gx816->op.r.w >>= 1;
|
||||
gx816->op.r.w |= c;
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->op.r.p.h); //6a [write high]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->op.r.p.l); //6 [write low]
|
||||
|
||||
g65816_testn(gx816->op.r.w & 0x8000);
|
||||
g65816_testz(gx816->op.r.w == 0);
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,443 +0,0 @@
|
||||
/**********************
|
||||
*** 0x8d: sta addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_addrb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sta_addrw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x9d: sta addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_addrxb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sta_addrxw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.x + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x85: sta dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_dpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->regs.a.b); //3 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_dpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp, gx816->regs.a.p.l); //3 [write low]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + 1, gx816->regs.a.p.h); //3a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x92: sta (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_idpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //5 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_idpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //5 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //5a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x87: sta [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_ildpb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.b); //6 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_ildpw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.p.l); //6 [write low]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + 1, gx816->regs.a.p.h); //6a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x8f: sta long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sta_longb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.b); //5 [write]
|
||||
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_sta_longw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l, gx816->regs.a.p.l); //5 [write]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + 1, gx816->regs.a.p.h); //5a [write]
|
||||
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x9f: sta long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sta_longxb(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x, gx816->regs.a.b); //5 [write]
|
||||
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
void g65816_op_sta_longxw(void) {
|
||||
gx816->op.aa.l = gx816->read_operand(3); //1-4 [op fetch]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x, gx816->regs.a.p.l); //5 [write]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.x + 1, gx816->regs.a.p.h); //5a [write]
|
||||
|
||||
g65816_incpc(4);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x99: sta addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_addryb(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
void g65816_op_sta_addryw(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x95: sta dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
|
||||
void g65816_op_sta_dpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_dpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x81: sta (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_idpxb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.b); //6 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_idpxw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + gx816->regs.x + 1); //5 [aah]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w, gx816->regs.a.p.l); //6 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + 1, gx816->regs.a.p.h); //6 [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x91: sta (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_idpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
snes_time->add_cpu_icycles(1); //4a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //5 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_idpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
snes_time->add_cpu_icycles(1); //4a [write i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //5 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //5a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x97: sta [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_ildpyb(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y, gx816->regs.a.b); //6 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_ildpyw(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [dl!=0]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [aah]
|
||||
gx816->op.aa.p.b = gx816->op_read(OPMODE_DP, gx816->op.dp + 2); //5 [aab]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y, gx816->regs.a.p.l); //6 [write low]
|
||||
gx816->op_write(OPMODE_LONG, gx816->op.aa.l + gx816->regs.y + 1, gx816->regs.a.p.h); //6a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x83: sta sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_srb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op_write(OPMODE_SP, gx816->op.sp, gx816->regs.a.b); //4 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_srw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op_write(OPMODE_SP, gx816->op.sp, gx816->regs.a.p.l); //4 [write low]
|
||||
gx816->op_write(OPMODE_SP, gx816->op.sp + 1, gx816->regs.a.p.h); //4a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x93: sta (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_sta_isryb(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.b); //7 [write]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
void g65816_op_sta_isryw(void) {
|
||||
gx816->op.sp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //3 [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_SP, gx816->op.sp); //4 [aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_SP, gx816->op.sp + 1); //5 [aah]
|
||||
snes_time->add_cpu_icycles(1); //6 [i/o]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y, gx816->regs.a.p.l); //7 [write low]
|
||||
gx816->op_write(OPMODE_DBR, gx816->op.aa.w + gx816->regs.y + 1, gx816->regs.a.p.h); //7a [write high]
|
||||
|
||||
g65816_incpc(2);
|
||||
}
|
||||
@@ -1,357 +0,0 @@
|
||||
/*****************
|
||||
*** 0x48: pha ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phab(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.a.b); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_phaw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.a.p.h); //3a [reg high]
|
||||
gx816->stack_write(gx816->regs.a.p.l); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x8b: phb ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.db); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x0b: phd ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phd(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.d >> 8); //3a [reg high]
|
||||
gx816->stack_write(gx816->regs.d); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x4b: phk ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phk(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.pc >> 16); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x08: php ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_php(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.p); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xda: phx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phxb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.x); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_phxw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.x >> 8); //3a [reg high]
|
||||
gx816->stack_write(gx816->regs.x); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x5a: phy ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
|
||||
void g65816_op_phyb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.y); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_phyw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //2 [i/o]
|
||||
gx816->stack_write(gx816->regs.y >> 8); //3a [reg high]
|
||||
gx816->stack_write(gx816->regs.y); //3 [reg low]
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x68: pla ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plab(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.a.b = gx816->stack_read(); //4 [reg low]
|
||||
g65816_testn(gx816->regs.a.b & 0x80);
|
||||
g65816_testz(gx816->regs.a.b == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_plaw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.a.p.l = gx816->stack_read(); //4 [reg low]
|
||||
gx816->regs.a.p.h = gx816->stack_read(); //4a [reg high]
|
||||
g65816_testn(gx816->regs.a.w & 0x8000);
|
||||
g65816_testz(gx816->regs.a.w == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xab: plb ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.db = gx816->stack_read(); //4 [reg low]
|
||||
g65816_testn(gx816->regs.db & 0x80);
|
||||
g65816_testz(gx816->regs.db == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x2b: pld ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_pld(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.d = gx816->stack_read(); //4 [reg low]
|
||||
gx816->regs.d |= gx816->stack_read() << 8; //4a [reg high]
|
||||
g65816_testn(gx816->regs.d & 0x8000);
|
||||
g65816_testz(gx816->regs.d == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x28: plp ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plp(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.p = gx816->stack_read(); //4 [reg low]
|
||||
g65816_incpc(1);
|
||||
if(gx816->regs.e == true)gx816->regs.p |= 0x30;
|
||||
if(gx816->regs.p & PF_X) { gx816->regs.x &= 0xff; gx816->regs.y &= 0xff; }
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xfa: plx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plxb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.x = gx816->stack_read(); //4 [reg low]
|
||||
g65816_testn(gx816->regs.x & 0x80);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_plxw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.x = gx816->stack_read(); //4 [reg low]
|
||||
gx816->regs.x |= gx816->stack_read() << 8; //4a [reg high]
|
||||
g65816_testn(gx816->regs.x & 0x8000);
|
||||
g65816_testz(gx816->regs.x == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x7a: ply ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
|
||||
void g65816_op_plyb(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.y = gx816->stack_read(); //4 [reg low]
|
||||
g65816_testn(gx816->regs.y & 0x80);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
void g65816_op_plyw(void) {
|
||||
snes_time->add_cpu_pcycles(1); //1 [op fetch]
|
||||
snes_time->add_cpu_icycles(2); //2,3 [i/o]
|
||||
gx816->regs.y = gx816->stack_read(); //4 [reg low]
|
||||
gx816->regs.y |= gx816->stack_read() << 8; //4a [reg high]
|
||||
g65816_testn(gx816->regs.y & 0x8000);
|
||||
g65816_testz(gx816->regs.y == 0);
|
||||
g65816_incpc(1);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf4: pea addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,s ; aah
|
||||
[5] 0,s-1 ; aal
|
||||
*/
|
||||
|
||||
void g65816_op_pea(void) {
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
gx816->stack_write(gx816->op.aa.p.h); //4 [write high]
|
||||
gx816->stack_write(gx816->op.aa.p.l); //5 [write low]
|
||||
g65816_incpc(3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd4: pei (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,s ; aah
|
||||
[6 ] 0,s-1 ; aal
|
||||
*/
|
||||
|
||||
void g65816_op_pei(void) {
|
||||
gx816->op.dp = gx816->read_operand(1); //1,2 [op fetch]
|
||||
gx816->op_cond(2); //2a [i/o]
|
||||
gx816->op.aa.p.l = gx816->op_read(OPMODE_DP, gx816->op.dp); //3 [read aal]
|
||||
gx816->op.aa.p.h = gx816->op_read(OPMODE_DP, gx816->op.dp + 1); //4 [read aah]
|
||||
gx816->stack_write(gx816->op.aa.p.h); //5 [write aah]
|
||||
gx816->stack_write(gx816->op.aa.p.l); //6 [write aal]
|
||||
g65816_incpc(2);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x62: per addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; offset low
|
||||
[3] pbr,pc+2 ; offset high
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] 0,s ; pch+offset
|
||||
[6] 0,s-1 ; pcl+offset
|
||||
*/
|
||||
|
||||
void g65816_op_per(void) {
|
||||
word r;
|
||||
gx816->op.aa.w = gx816->read_operand(2); //1-3 [op fetch]
|
||||
snes_time->add_cpu_icycles(1); //4 [i/o]
|
||||
r = (gx816->regs.pc + (signed short)gx816->op.aa.w + 3);
|
||||
gx816->stack_write(r >> 8); //5 [write pch]
|
||||
gx816->stack_write(r); //6 [write pcl]
|
||||
g65816_incpc(3);
|
||||
}
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
/* bsnes
|
||||
project started: 10/14/2004
|
||||
author: byuu */
|
||||
|
||||
#include "base.h"
|
||||
#include "main.h"
|
||||
#include "timing/timing.h"
|
||||
#include "cpu/g65816.h"
|
||||
#include "apu/spc700.h"
|
||||
#include "bridge/bridge.h"
|
||||
extern snes_timer *snes_time;
|
||||
extern g65816 *gx816;
|
||||
extern sony_spc700 *spc700;
|
||||
extern ppustate ppu;
|
||||
extern port_bridge *cpu_apu_bridge;
|
||||
debugstate debugger;
|
||||
|
||||
void debug_test_breakpoint_hit(byte source, byte flag, ulong offset, byte value, int i) {
|
||||
dprintf("* breakpoint %d hit", i);
|
||||
debugger.bp_list[i].hit_count++;
|
||||
debugger.refresh_bp = true;
|
||||
debug_set_state(DEBUGMODE_WAIT);
|
||||
if(source == BPSRC_SPCRAM) {
|
||||
disas_spc700_op();
|
||||
} else {
|
||||
disas_g65816_op();
|
||||
}
|
||||
}
|
||||
|
||||
void debug_test_breakpoint(byte source, byte flag, ulong offset, byte value) {
|
||||
int i;
|
||||
if(debug_get_state() == DEBUGMODE_DISABLED)return;
|
||||
|
||||
for(i=0;i<16;i++) {
|
||||
if(debugger.bp_list[i].source != source)continue;
|
||||
if(debugger.bp_list[i].flags & flag) {
|
||||
if(debugger.bp_list[i].offset == offset) {
|
||||
if(debugger.bp_list[i].flags & BP_VAL) {
|
||||
if(debugger.bp_list[i].value == value) {
|
||||
debug_test_breakpoint_hit(source, flag, offset, value, i);
|
||||
}
|
||||
} else {
|
||||
debug_test_breakpoint_hit(source, flag, offset, value, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ulong debug_write_status(void) {
|
||||
if(debugger_enabled() == false)return DEBUGWRITE_NONE;
|
||||
|
||||
if(debug_get_state() == DEBUGMODE_RUN) {
|
||||
if(debugger.trace_enabled == false)return DEBUGWRITE_NONE;
|
||||
if(debugger.trace_output_enabled == true) {
|
||||
return DEBUGWRITE_CONSOLE | DEBUGWRITE_TRACE;
|
||||
}
|
||||
return DEBUGWRITE_TRACE;
|
||||
}
|
||||
|
||||
return DEBUGWRITE_CONSOLE;
|
||||
}
|
||||
|
||||
void init_debugstate(void) {
|
||||
debugger.mode = DEBUGMODE_DISABLED;
|
||||
|
||||
debugger.mem_ptr = 0x7e0000;
|
||||
debugger.disas_cpu_op = true;
|
||||
debugger.disas_apu_op = true;
|
||||
debugger.refresh_mem = true;
|
||||
debugger.refresh_bp = true;
|
||||
debugger.refresh_status = true;
|
||||
|
||||
debugger.cpu_op_executed = false;
|
||||
debugger.apu_op_executed = false;
|
||||
|
||||
debugger.output_cpu_instrs = true;
|
||||
debugger.output_apu_instrs = true;
|
||||
debugger.output_debug_info = true;
|
||||
debugger.trace_enabled = false;
|
||||
debugger.trace_output_enabled = false;
|
||||
|
||||
debugger.lock_up = debugger.lock_down = debugger.lock_left = debugger.lock_right = false;
|
||||
debugger.lock_a = debugger.lock_b = debugger.lock_x = debugger.lock_y = false;
|
||||
debugger.lock_l = debugger.lock_r = debugger.lock_select = debugger.lock_start = false;
|
||||
}
|
||||
|
||||
void RunSNES(void) {
|
||||
if(emu_state.rom_loaded == false)return;
|
||||
|
||||
if(debugger_enabled() == false) {
|
||||
gx816->Run();
|
||||
spc700->Run();
|
||||
return;
|
||||
}
|
||||
|
||||
if(debug_get_state() == DEBUGMODE_RUN) {
|
||||
gx816->Run();
|
||||
spc700->Run();
|
||||
if(debugger.trace_enabled == true) {
|
||||
if(debugger.disas_cpu_op == true) {
|
||||
disas_g65816_op();
|
||||
debugger.disas_cpu_op = false;
|
||||
}
|
||||
if(debugger.disas_apu_op == true) {
|
||||
disas_spc700_op();
|
||||
debugger.disas_apu_op = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(debugger.disas_cpu_op == true) {
|
||||
disas_g65816_op();
|
||||
debugger.disas_cpu_op = false;
|
||||
}
|
||||
if(debugger.disas_apu_op == true) {
|
||||
disas_spc700_op();
|
||||
debugger.disas_apu_op = false;
|
||||
}
|
||||
if(debugger.refresh_mem == true) {
|
||||
debug_refresh_mem();
|
||||
debugger.refresh_mem = false;
|
||||
}
|
||||
if(debugger.refresh_bp == true) {
|
||||
debug_refresh_bp();
|
||||
debugger.refresh_bp = false;
|
||||
}
|
||||
if(debugger.refresh_status == true) {
|
||||
debug_update_status();
|
||||
debugger.refresh_status = false;
|
||||
}
|
||||
if(debug_get_state() == DEBUGMODE_WAIT)return;
|
||||
|
||||
if(debug_get_state() == DEBUGMODE_CPUSTEP) {
|
||||
gx816->Run();
|
||||
spc700->Run();
|
||||
if(debugger.cpu_op_executed == true) {
|
||||
debug_set_state(DEBUGMODE_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
if(debug_get_state() == DEBUGMODE_APUSTEP) {
|
||||
gx816->Run();
|
||||
spc700->Run();
|
||||
if(debugger.apu_op_executed == true) {
|
||||
debug_set_state(DEBUGMODE_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
debug_update_status();
|
||||
}
|
||||
|
||||
extern vfunc spc700_optbl[256];
|
||||
|
||||
void InitSNES(void) {
|
||||
int i, z;
|
||||
snes_time = new snes_timer();
|
||||
gx816 = new g65816();
|
||||
gx816->PowerOn(1);
|
||||
spc700 = new sony_spc700();
|
||||
spc700->Reset();
|
||||
snes_time->reset_clock();
|
||||
cpu_apu_bridge = new port_bridge();
|
||||
if(*emu_state.rom_name == 0) {
|
||||
emu_state.rom_loaded = false;
|
||||
} else {
|
||||
gx816->LoadROM();
|
||||
emu_state.rom_loaded = true;
|
||||
}
|
||||
for(i=0;i<16;i++) {
|
||||
debugger.bp_list[i].offset = 0;
|
||||
debugger.bp_list[i].flags = BP_OFF;
|
||||
debugger.bp_list[i].source = BPSRC_MEM;
|
||||
debugger.bp_list[i].value = 0;
|
||||
debugger.bp_list[i].hit_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ResetSNES(void) {
|
||||
int i;
|
||||
gx816->Reset();
|
||||
spc700->Reset();
|
||||
snes_time->reset_clock();
|
||||
for(i=0;i<16;i++) {
|
||||
debugger.bp_list[i].offset = 0;
|
||||
debugger.bp_list[i].flags = BP_OFF;
|
||||
debugger.bp_list[i].source = BPSRC_MEM;
|
||||
debugger.bp_list[i].value = 0;
|
||||
debugger.bp_list[i].hit_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#include <windows.h>
|
||||
int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
|
||||
char fn[MAX_PATH];
|
||||
strcpy(fn, lpcmdline);
|
||||
//remove quotes from filename, if neccesary (if path contains spaces, quotes will be around command line arg)
|
||||
if(*fn == '\"') {
|
||||
strcpy(emu_state.rom_name, fn + 1);
|
||||
emu_state.rom_name[strlen(emu_state.rom_name) - 1] = 0;
|
||||
} else {
|
||||
strcpy(emu_state.rom_name, fn);
|
||||
}
|
||||
//create save ram file name
|
||||
strcpy(emu_state.sram_name, emu_state.rom_name);
|
||||
if(strlen(emu_state.sram_name) > 4) {
|
||||
emu_state.sram_name[strlen(emu_state.sram_name) - 4] = 0;
|
||||
}
|
||||
strcat(emu_state.sram_name, ".srm");
|
||||
|
||||
init_debugstate();
|
||||
__winmain(); //located in win/gui.cpp
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
void __winmain(void);
|
||||
|
||||
/*
|
||||
*1 - how many instructions to execute before saving sram data
|
||||
to emu_state.sram_name
|
||||
*/
|
||||
emustate emu_state = {
|
||||
false, //rom loaded
|
||||
20000000, //sram save tick count *1
|
||||
"", "" //rom name, sram name
|
||||
};
|
||||
|
||||
videostate render = {
|
||||
512, 448, //display resolution
|
||||
256, 224, //snes internal resolution
|
||||
false, //fullscreen
|
||||
true, //show menu
|
||||
0, //frame skip
|
||||
0, //frame count
|
||||
{ true, true, true }, //bg1 enable
|
||||
{ true, true, true }, //bg2 enable
|
||||
{ true, true, true }, //bg3 enable
|
||||
{ true, true, true }, //bg4 enable
|
||||
{ true, true, true, true, true } //oam enable
|
||||
};
|
||||
@@ -1,434 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "../cpu/g65816.h"
|
||||
#include "../timing/timing.h"
|
||||
extern g65816 *gx816;
|
||||
extern emustate emu_state;
|
||||
extern debugstate debugger;
|
||||
extern snes_timer *snes_time;
|
||||
|
||||
void g65816::InitializeROM(byte memory_map) {
|
||||
memset(rom, 0, 0x600000);
|
||||
map = memory_map;
|
||||
}
|
||||
|
||||
void g65816::InitializeWRAM(byte value) {
|
||||
memset(wram, value, 0x020000);
|
||||
memset(sram, 0x00, 0x0e0000);
|
||||
}
|
||||
|
||||
/***********************
|
||||
*** SNES Memory Map ***
|
||||
**************************************************
|
||||
*** 00-3f 0000-1fff First 8k WRAM ***
|
||||
*** 2000-5fff MMIO ***
|
||||
*** 6000-7fff Expansion RAM (Unmapped) ***
|
||||
*** 8000-ffff Cartridge ROM ***
|
||||
*** 40-7d 0000-ffff Cartridge ROM ***
|
||||
*** 7e-7f 0000-ffff 128k WRAM ***
|
||||
*** 80-bf 0000-1fff First 8k WRAM ***
|
||||
*** 2000-5fff MMIO ***
|
||||
*** 6000-7fff Expansion RAM (Unmapped) ***
|
||||
*** 8000-ffff Cartridge ROM ***
|
||||
*** c0-ff 0000-ffff Cartridge ROM ***
|
||||
**************************************************/
|
||||
|
||||
ulong g65816::mirror_offset(ulong addr) {
|
||||
byte db;
|
||||
word a;
|
||||
ulong r = 0;
|
||||
db = (addr >> 16) & 0xff;
|
||||
a = (addr & 0xffff);
|
||||
if(db >= 0x00 && db <= 0x3f) {
|
||||
if(a >= 0x0000 && a <= 0x1fff) {
|
||||
r = 0x7e0000 | (a & 0x1fff);
|
||||
} else if(a >= 0x2000 && a <= 0x5fff) {
|
||||
r = a;
|
||||
} else if(a >= 0x6000 && a <= 0x7fff) {
|
||||
r = (db << 16) | a;
|
||||
} else if(a >= 0x8000 && a <= 0xffff) {
|
||||
r = (db << 16) | a;
|
||||
}
|
||||
} else if(db >= 0x40 && db <= 0x7d) {
|
||||
r = (db << 16) | a;
|
||||
} else if(db >= 0x7e && db <= 0x7f) {
|
||||
r = addr;
|
||||
} else if(db >= 0x80 && db <= 0xbf) {
|
||||
if(a >= 0x0000 && a <= 0x1fff) {
|
||||
r = 0x7e0000 | (a & 0x1fff);
|
||||
} else if(a >= 0x2000 && a <= 0x5fff) {
|
||||
r = a;
|
||||
} else if(a >= 0x6000 && a <= 0x7fff) {
|
||||
r = (db << 16) | a;
|
||||
} else if(a >= 0x8000 && a <= 0xffff) {
|
||||
r = ((db & 0x7f) << 16) | a;
|
||||
}
|
||||
} else if(db >= 0xc0 && db <= 0xff) {
|
||||
r = addr;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ulong g65816::convert_offset(byte read_mode, ulong addr, bool mirror) {
|
||||
byte db;
|
||||
switch(read_mode) {
|
||||
case MEMMODE_DP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case MEMMODE_DPX:
|
||||
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case MEMMODE_DPY:
|
||||
addr = (regs.d + regs.y + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case MEMMODE_IDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
|
||||
addr |= (regs.db << 16);
|
||||
break;
|
||||
case MEMMODE_IDPX:
|
||||
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
|
||||
addr |= (regs.db << 16);
|
||||
break;
|
||||
case MEMMODE_IDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
|
||||
addr += (regs.db << 16) + regs.y;
|
||||
break;
|
||||
case MEMMODE_ILDP:
|
||||
addr = (regs.d + (addr & 0xffff));
|
||||
addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
|
||||
break;
|
||||
case MEMMODE_ILDPY:
|
||||
addr = (regs.d + (addr & 0xffff));
|
||||
addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
|
||||
addr += regs.y;
|
||||
break;
|
||||
case MEMMODE_ADDR:
|
||||
addr = addr & 0xffff;
|
||||
addr |= (regs.db << 16);
|
||||
break;
|
||||
case MEMMODE_ADDR_PC:
|
||||
addr = addr & 0xffff;
|
||||
addr |= (regs.pc & 0xff0000);
|
||||
break;
|
||||
case MEMMODE_ADDRX:
|
||||
addr = (regs.db << 16) + (addr & 0xffff);
|
||||
addr += regs.x;
|
||||
break;
|
||||
case MEMMODE_ADDRY:
|
||||
addr = (regs.db << 16) + (addr & 0xffff);
|
||||
addr += regs.y;
|
||||
break;
|
||||
case MEMMODE_IADDRX:
|
||||
addr += regs.x;
|
||||
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, (addr & 0x00ffff));
|
||||
addr |= (regs.pc & 0xff0000);
|
||||
break;
|
||||
case MEMMODE_ILADDR:
|
||||
addr = mem_read(MEMMODE_LONG, MEMSIZE_LONG, addr);
|
||||
break;
|
||||
case MEMMODE_IADDR_PC:
|
||||
addr |= (regs.pc & 0xff0000);
|
||||
break;
|
||||
case MEMMODE_IADDRX_PC:
|
||||
addr += regs.x;
|
||||
addr |= (regs.pc & 0xff0000);
|
||||
break;
|
||||
case MEMMODE_ILADDR_PC:
|
||||
break;
|
||||
case MEMMODE_LONG:
|
||||
break;
|
||||
case MEMMODE_LONGX:
|
||||
addr += regs.x;
|
||||
break;
|
||||
case MEMMODE_SR:
|
||||
addr = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
break;
|
||||
case MEMMODE_ISRY:
|
||||
addr = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
addr = mem_read(MEMMODE_LONG, MEMSIZE_WORD, addr);
|
||||
addr += (regs.db << 16) + regs.y;
|
||||
break;
|
||||
|
||||
case OPMODE_ADDR:
|
||||
addr &= 0xffff;
|
||||
break;
|
||||
case OPMODE_LONG:
|
||||
addr &= 0xffffff;
|
||||
break;
|
||||
case OPMODE_DBR:
|
||||
addr = (regs.db << 16) + addr;
|
||||
break;
|
||||
case OPMODE_PBR:
|
||||
addr = (regs.pc & 0xff0000) | (addr & 0xffff);
|
||||
break;
|
||||
case OPMODE_DP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPMODE_SP:
|
||||
addr = (regs.s + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
}
|
||||
|
||||
if(mirror == true) {
|
||||
return mirror_offset(addr);
|
||||
} else {
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
ulong g65816::read_operand(byte size) {
|
||||
ulong r;
|
||||
r = gx816->mem_read(MEMMODE_NONE, size, gx816->regs.pc + 1);
|
||||
//add size + 1 cycles. the extra cycle is for the actual opcode
|
||||
//byte itself being read in by the main cpu emulation routine.
|
||||
snes_time->add_cpu_pcycles(size + 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
byte g65816::mem_getbyte_direct(ulong addr, byte access_mode) {
|
||||
byte db;
|
||||
word a;
|
||||
db = (addr >> 16) & 0xff;
|
||||
a = (addr & 0xffff);
|
||||
if(db == 0x00 && a >= 0x2000 && a <= 0x5fff) {
|
||||
if(access_mode == MEMACCESS_DEBUGGER) {
|
||||
return 0x00;
|
||||
} else {
|
||||
return mmio_read(addr);
|
||||
}
|
||||
}
|
||||
|
||||
if(db == 0x7e || db == 0x7f) {
|
||||
return wram[addr & 0x01ffff];
|
||||
} else if(db != 0x7e && db != 0x7f && a >= 0x8000 && a <= 0xffff) {
|
||||
return rom_read(addr, MEMSIZE_BYTE);
|
||||
} else if(db >= 0x30 && db <= 0x3f) {
|
||||
if(a >= 0x6000 && a <= 0x7fff) {
|
||||
addr = ((db - 0x30) * 0x2000) + (a - 0x6000);
|
||||
addr &= (sram_size - 1);
|
||||
return sram[addr];
|
||||
}
|
||||
} else if(db >= 0x70 && db <= 0x7d) {
|
||||
addr -= 0x700000;
|
||||
addr &= (sram_size - 1);
|
||||
return sram[addr];
|
||||
} else if(db >= 0xc0 && db <= 0xff) {
|
||||
return rom_read(addr, MEMSIZE_BYTE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte g65816::mem_getbyte(ulong addr, byte access_mode) {
|
||||
int i;
|
||||
byte r;
|
||||
r = mem_getbyte_direct(addr, access_mode);
|
||||
|
||||
if(debug_get_state() == DEBUGMODE_DISABLED)return r;
|
||||
if(access_mode == MEMACCESS_DEBUGGER)return r; //don't report breakpoint hits from debugger
|
||||
|
||||
debug_test_bp(BPSRC_MEM, BP_READ, addr, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
void g65816::mem_putbyte_direct(ulong addr, byte value, byte access_mode) {
|
||||
byte db;
|
||||
word a;
|
||||
db = (addr >> 16) & 0xff;
|
||||
a = (addr & 0xffff);
|
||||
if(db == 0x00 && a >= 0x2000 && a <= 0x5fff) {
|
||||
mmio_write(a, value);
|
||||
} else if(db == 0x7e || db == 0x7f) {
|
||||
wram[addr & 0x01ffff] = value;
|
||||
} else if(db >= 0x30 && db <= 0x3f) {
|
||||
if(a >= 0x6000 && a <= 0x7fff) {
|
||||
addr = ((db - 0x30) * 0x2000) + (a - 0x6000);
|
||||
addr &= (sram_size - 1);
|
||||
sram[addr] = value;
|
||||
}
|
||||
} else if(db >= 0x70 && db <= 0x7d) {
|
||||
addr -= 0x700000;
|
||||
addr &= (sram_size - 1);
|
||||
sram[addr] = value;
|
||||
}
|
||||
|
||||
if(access_mode == MEMACCESS_DEBUGGER) {
|
||||
if(gx816->map == MEMMAP_LOROM) {
|
||||
if((db >= 0x00 && db <= 0x5f) || (db >= 0x80 && db <= 0xdf)) {
|
||||
if(addr >= 0x8000 && addr <= 0xffff) {
|
||||
rom_write(addr, value, MEMSIZE_BYTE);
|
||||
}
|
||||
}
|
||||
} else if(gx816->map == MEMMAP_HIROM) {
|
||||
if(db >= 0xc0 && db <= 0xff) {
|
||||
rom_write(addr, value, MEMSIZE_BYTE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void g65816::mem_putbyte(ulong addr, byte value, byte access_mode) {
|
||||
int i;
|
||||
mem_putbyte_direct(addr, value, access_mode);
|
||||
|
||||
if(debug_get_state() == DEBUGMODE_DISABLED)return;
|
||||
if(access_mode == MEMACCESS_DEBUGGER)return; //don't report breakpoint hits from debugger
|
||||
|
||||
debug_test_bp(BPSRC_MEM, BP_WRITE, addr, value);
|
||||
}
|
||||
|
||||
ulong g65816::mem_read(byte read_mode, byte read_size, ulong addr, byte access_mode) {
|
||||
ulong r;
|
||||
addr = convert_offset(read_mode, addr);
|
||||
|
||||
switch(read_size) {
|
||||
case MEMSIZE_BYTE:
|
||||
r = mem_getbyte(addr, access_mode);
|
||||
break;
|
||||
case MEMSIZE_WORD:
|
||||
r = mem_getbyte(addr, access_mode) |
|
||||
mem_getbyte(addr+1, access_mode)<<8;
|
||||
break;
|
||||
case MEMSIZE_LONG:
|
||||
r = mem_getbyte(addr, access_mode) |
|
||||
mem_getbyte(addr+1, access_mode)<<8 |
|
||||
mem_getbyte(addr+2, access_mode)<<16;
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void g65816::mem_write(byte write_mode, byte write_size, ulong addr, ulong value, byte access_mode) {
|
||||
addr = convert_offset(write_mode, addr);
|
||||
|
||||
switch(write_size) {
|
||||
case MEMSIZE_BYTE:
|
||||
mem_putbyte(addr, value, access_mode);
|
||||
break;
|
||||
case MEMSIZE_WORD:
|
||||
mem_putbyte(addr, value, access_mode);
|
||||
mem_putbyte(addr+1, value>>8, access_mode);
|
||||
break;
|
||||
case MEMSIZE_LONG:
|
||||
mem_putbyte(addr, value, access_mode);
|
||||
mem_putbyte(addr+1, value>>8, access_mode);
|
||||
mem_putbyte(addr+2, value>>16, access_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
debugger.refresh_mem = true;
|
||||
}
|
||||
|
||||
/*
|
||||
todo: move address mirroring into mem_getbyte
|
||||
in case there are different memory speeds depending
|
||||
on pre-mirrored addresses.
|
||||
*/
|
||||
byte g65816::op_read(byte mode, ulong addr) {
|
||||
byte r;
|
||||
addr = convert_offset(mode, addr);
|
||||
r = mem_getbyte(addr);
|
||||
snes_time->add_cpu_mcycles(1, addr);
|
||||
return r;
|
||||
}
|
||||
|
||||
void g65816::op_write(byte mode, ulong addr, byte value) {
|
||||
mem_putbyte(convert_offset(mode, addr), value);
|
||||
snes_time->add_cpu_mcycles(1, addr);
|
||||
}
|
||||
|
||||
byte g65816::stack_read(void) {
|
||||
byte r;
|
||||
gx816->regs.s++;
|
||||
if(gx816->regs.e == true) {
|
||||
gx816->regs.s = 0x0100 | (gx816->regs.s & 0xff);
|
||||
}
|
||||
r = mem_getbyte(convert_offset(OPMODE_SP, 0));
|
||||
snes_time->add_cpu_mcycles(1, gx816->regs.s);
|
||||
return r;
|
||||
}
|
||||
|
||||
void g65816::stack_write(byte value) {
|
||||
mem_putbyte(convert_offset(OPMODE_SP, 0), value);
|
||||
gx816->regs.s--;
|
||||
if(gx816->regs.e == true) {
|
||||
gx816->regs.s = 0x0100 | (gx816->regs.s & 0xff);
|
||||
}
|
||||
snes_time->add_cpu_mcycles(1, gx816->regs.s);
|
||||
}
|
||||
|
||||
/*
|
||||
note: case 4 (write) condition is handled directly
|
||||
in the opcode, since it is always true.
|
||||
*/
|
||||
void g65816::op_cond(byte c, ulong n0, ulong n1) {
|
||||
switch(c) {
|
||||
case 2: //dl != 0
|
||||
if((regs.d & 0xff) != 0x00) {
|
||||
snes_time->add_cpu_icycles(1);
|
||||
}
|
||||
break;
|
||||
case 4: //read across page boundaries, write, or x=0
|
||||
if((n0 & 0xff00) != (n1 & 0xff00) || !(gx816->regs.p & PF_X)) {
|
||||
snes_time->add_cpu_icycles(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ulong g65816::rom_read(ulong addr, byte read_size) {
|
||||
ulong r;
|
||||
if(map == MEMMAP_LOROM) {
|
||||
if(read_size == MEMSIZE_BYTE) {
|
||||
r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)];
|
||||
} else if(read_size == MEMSIZE_WORD) {
|
||||
r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] |
|
||||
rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] << 8;
|
||||
} else if(read_size == MEMSIZE_LONG) {
|
||||
r = rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] |
|
||||
rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] << 8 |
|
||||
rom[(((addr + 2) & 0x7f0000) >> 1) | ((addr + 2) & 0x7fff)] << 16;
|
||||
}
|
||||
} else if(map == MEMMAP_HIROM) {
|
||||
if(read_size == MEMSIZE_BYTE) {
|
||||
r = rom[addr & 0x3fffff];
|
||||
} else if(read_size == MEMSIZE_WORD) {
|
||||
r = rom[addr & 0x3fffff] |
|
||||
rom[(addr + 1) & 0x3fffff] << 8;
|
||||
} else if(read_size == MEMSIZE_LONG) {
|
||||
r = rom[addr & 0x3fffff] |
|
||||
rom[(addr + 1) & 0x3fffff] << 8 |
|
||||
rom[(addr + 2) & 0x3fffff] << 16;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void g65816::rom_write(ulong addr, ulong v, byte write_size) {
|
||||
if(map == MEMMAP_LOROM) {
|
||||
if(write_size == MEMSIZE_BYTE) {
|
||||
rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
|
||||
} else if(write_size == MEMSIZE_WORD) {
|
||||
rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
|
||||
rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] = v >> 8;
|
||||
} else if(write_size == MEMSIZE_LONG) {
|
||||
rom[((addr & 0x7f0000) >> 1) | (addr & 0x7fff)] = v;
|
||||
rom[(((addr + 1) & 0x7f0000) >> 1) | ((addr + 1) & 0x7fff)] = v >> 8;
|
||||
rom[(((addr + 2) & 0x7f0000) >> 1) | ((addr + 2) & 0x7fff)] = v >> 16;
|
||||
}
|
||||
} else if(map == MEMMAP_HIROM) {
|
||||
if(write_size == MEMSIZE_BYTE) {
|
||||
rom[addr & 0x3fffff] = v;
|
||||
} else if(write_size == MEMSIZE_WORD) {
|
||||
rom[addr & 0x3fffff] = v;
|
||||
rom[(addr + 1) & 0x3fffff] = v >> 8;
|
||||
} else if(write_size == MEMSIZE_LONG) {
|
||||
rom[addr & 0x3fffff] = v;
|
||||
rom[(addr + 1) & 0x3fffff] = v >> 8;
|
||||
rom[(addr + 2) & 0x3fffff] = v >> 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,393 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "libvlist.cpp"
|
||||
|
||||
typedef struct {
|
||||
char *s;
|
||||
ulong size;
|
||||
}string;
|
||||
|
||||
typedef struct {
|
||||
vectorlist list;
|
||||
ulong count;
|
||||
}stringlist;
|
||||
|
||||
/***********************
|
||||
string library functions
|
||||
***********************/
|
||||
|
||||
void strresize(string *str, ulong size) {
|
||||
char *t;
|
||||
int sl;
|
||||
if(str->size == size)return;
|
||||
sl = strlen(str->s);
|
||||
t = (char*)malloc(size + 1);
|
||||
strncpy(t, str->s, size);
|
||||
free(str->s);
|
||||
str->s = t;
|
||||
str->size = size;
|
||||
}
|
||||
|
||||
string *newstr(void) {
|
||||
string *s;
|
||||
s = (string*)malloc(sizeof(string));
|
||||
s->size = 16;
|
||||
s->s = (char*)malloc(s->size + 1);
|
||||
*s->s = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
void memfree(string *s) {
|
||||
if(s->s)free(s->s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
/***************************
|
||||
stringlist library functions
|
||||
***************************/
|
||||
|
||||
void stradd(stringlist *sl, ulong num) {
|
||||
int i;
|
||||
string *s;
|
||||
while(sl->count < (num + 1)) {
|
||||
s = newstr();
|
||||
sl->list.add((ulong)s);
|
||||
sl->count++;
|
||||
}
|
||||
}
|
||||
|
||||
string *strget(stringlist *sl, ulong num) {
|
||||
string *s;
|
||||
if(sl->count < (num + 1)) { stradd(sl, num); }
|
||||
s = (string*)sl->list.get(num);
|
||||
return s;
|
||||
}
|
||||
|
||||
stringlist *newstrlist(void) {
|
||||
stringlist *sl;
|
||||
sl = (stringlist*)malloc(sizeof(stringlist));
|
||||
sl->count = 0;
|
||||
stradd(sl, 1);
|
||||
return sl;
|
||||
}
|
||||
|
||||
ulong count(stringlist *sl) {
|
||||
return sl->count;
|
||||
}
|
||||
|
||||
/****************************
|
||||
string manipulation functions
|
||||
****************************/
|
||||
|
||||
char *strptr(string *s) { return s->s; }
|
||||
char *strptr(stringlist *sl, ulong num) { return strget(sl, num)->s; }
|
||||
|
||||
void strcpy(string *dest, char *src) {
|
||||
int srclen = strlen(src);
|
||||
if(srclen > dest->size) { strresize(dest, srclen); }
|
||||
strncpy(dest->s, src, dest->size);
|
||||
}
|
||||
void strcpy(string *dest, string *src) { strcpy(dest, src->s); }
|
||||
void strcpy(stringlist *dest, ulong num, char *src) { strcpy(strget(dest, num), src); }
|
||||
void strcpy(stringlist *dest, ulong num, string *src) { strcpy(strget(dest, num), src->s); }
|
||||
void strcpy(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { strcpy(strget(dest, destnum), strptr(src, srcnum)); }
|
||||
|
||||
void strset(string *dest, ulong pos, byte c) {
|
||||
char *s;
|
||||
if(pos > dest->size) { strresize(dest, pos); }
|
||||
dest->s[pos] = c;
|
||||
}
|
||||
void strset(stringlist *dest, ulong num, ulong pos, byte c) { strset(strget(dest, num), pos, c); }
|
||||
|
||||
void strcat(string *dest, char *src) {
|
||||
int srclen, destlen;
|
||||
srclen = strlen(src);
|
||||
destlen = strlen(dest->s);
|
||||
if(srclen + destlen > dest->size) { strresize(dest, srclen + destlen); }
|
||||
strncat(dest->s, src, srclen + destlen);
|
||||
}
|
||||
void strcat(string *dest, string *src) { strcat(dest, src->s); }
|
||||
void strcat(stringlist *dest, ulong num, char *src) { strcat(strget(dest, num), src); }
|
||||
void strcat(stringlist *dest, ulong num, string *src) { strcat(strget(dest, num), src->s); }
|
||||
void strcat(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { strcat(strget(dest, destnum), strptr(src, srcnum)); }
|
||||
|
||||
ulong strlen(string *s) { return strlen(s->s); }
|
||||
ulong strlen(stringlist *sl, ulong num) { return strlen(strget(sl, num)->s); }
|
||||
|
||||
void strinsert(string *dest, char *src, ulong pos) {
|
||||
string *s = newstr();
|
||||
strcpy(s, strptr(dest)+pos);
|
||||
strset(dest, pos, 0);
|
||||
strcat(dest, src);
|
||||
strcat(dest, s);
|
||||
memfree(s);
|
||||
}
|
||||
void strinsert(string *dest, string *src, ulong pos) { strinsert(dest, src->s, pos); }
|
||||
void strinsert(stringlist *dest, ulong num, char *src, ulong pos) { strinsert(strget(dest, num), src, pos); }
|
||||
void strinsert(stringlist *dest, ulong num, string *src, ulong pos) { strinsert(strget(dest, num), src->s, pos); }
|
||||
void strinsert(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum, ulong pos) { strinsert(strget(dest, destnum), strptr(src, srcnum), pos); }
|
||||
|
||||
void strremove(string *dest, ulong start, ulong length = 0) {
|
||||
int destlen;
|
||||
char *s;
|
||||
int i, sl = strlen(dest->s);
|
||||
if(start > dest->size) { strresize(dest, start); }
|
||||
if(!length) {
|
||||
strset(dest, start, 0);
|
||||
return;
|
||||
}
|
||||
s = strptr(dest);
|
||||
for(i=start;i<sl;i++) { s[i] = s[i+length]; }
|
||||
s[i] = 0;
|
||||
}
|
||||
void strremove(stringlist *sl, ulong num, ulong start, ulong length = 0) { strremove(strget(sl, num), start, length); }
|
||||
|
||||
ulong strcmp(string *dest, char *src) { return strcmp(dest->s, src); }
|
||||
ulong strcmp(string *dest, string *src) { return strcmp(dest->s, src->s); }
|
||||
ulong strcmp(stringlist *dest, ulong num, char *src) { return strcmp(strget(dest, num)->s, src); }
|
||||
ulong strcmp(stringlist *dest, ulong num, string *src) { return strcmp(strget(dest, num)->s, src->s); }
|
||||
ulong strcmp(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strcmp(strget(dest, destnum)->s, strptr(src, srcnum)); }
|
||||
|
||||
ulong stricmp(char *dest, char *src) {
|
||||
int i, sl = strlen(dest);
|
||||
if(sl != strlen(src))return 1;
|
||||
for(i=0;i<sl;i++) {
|
||||
if(dest[i] >= 'A' && dest[i] <= 'Z') {
|
||||
if(dest[i]!=src[i] && dest[i]+0x20!=src[i])return 1;
|
||||
} else if(dest[i] >='a' && dest[i] <= 'z') {
|
||||
if(dest[i]!=src[i] && dest[i]-0x20!=src[i])return 1;
|
||||
} else {
|
||||
if(dest[i] != src[i])return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ulong stricmp(string *dest, char *src) { return stricmp(dest->s, src); }
|
||||
ulong stricmp(string *dest, string *src) { return stricmp(dest->s, src->s); }
|
||||
ulong stricmp(stringlist *dest, ulong num, char *src) { return stricmp(strget(dest, num)->s, src); }
|
||||
ulong stricmp(stringlist *dest, ulong num, string *src) { return stricmp(strget(dest, num)->s, src->s); }
|
||||
ulong stricmp(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return stricmp(strget(dest, destnum)->s, strptr(src, srcnum)); }
|
||||
|
||||
void strlower(char *str) {
|
||||
int i, sl = strlen(str);
|
||||
for(i=0;i<sl;i++) { if(str[i] >= 'A' && str[i] <= 'Z')str[i] += 0x20; }
|
||||
}
|
||||
void strlower(string *str) { strlower(str->s); }
|
||||
void strlower(stringlist *sl, ulong num) { strlower(strptr(sl, num)); }
|
||||
|
||||
void strupper(char *str) {
|
||||
int i, sl = strlen(str);
|
||||
for(i=0;i<sl;i++) { if(str[i] >='a' && str[i] <='z')str[i] -= 0x20; }
|
||||
}
|
||||
void strupper(string *str) { strupper(str->s); }
|
||||
void strupper(stringlist *sl, ulong num) { strupper(strptr(sl, num)); }
|
||||
|
||||
ulong strpos(char *str, char *key) {
|
||||
int i, ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return null;
|
||||
for(i=0;i<=ssl-ksl;i++) {
|
||||
if(!memcmp(str+i, key, ksl))return i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
ulong strpos(string *dest, char *src) { return strpos(dest->s, src); }
|
||||
ulong strpos(string *dest, string *src) { return strpos(dest->s, src->s); }
|
||||
ulong strpos(stringlist *dest, ulong num, char *src) { return strpos(strget(dest, num)->s, src); }
|
||||
ulong strpos(stringlist *dest, ulong num, string *src) { return strpos(strget(dest, num)->s, src->s); }
|
||||
ulong strpos(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strpos(strget(dest, destnum)->s, strptr(src, srcnum)); }
|
||||
|
||||
ulong strpos_q(char *str, char *key) {
|
||||
int i, z, ssl = strlen(str), ksl = strlen(key);
|
||||
byte x;
|
||||
if(ksl > ssl)return null;
|
||||
for(i=0;i<=ssl-ksl;) {
|
||||
x = str[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
z = i++;
|
||||
while(str[i] != x && i < ssl)i++;
|
||||
if(i >= ssl)i = z;
|
||||
}
|
||||
if(!memcmp(str+i, key, ksl)) {
|
||||
return i;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
ulong strpos_q(string *dest, char *src) { return strpos_q(dest->s, src); }
|
||||
ulong strpos_q(string *dest, string *src) { return strpos_q(dest->s, src->s); }
|
||||
ulong strpos_q(stringlist *dest, ulong num, char *src) { return strpos_q(strget(dest, num)->s, src); }
|
||||
ulong strpos_q(stringlist *dest, ulong num, string *src) { return strpos_q(strget(dest, num)->s, src->s); }
|
||||
ulong strpos_q(stringlist *dest, ulong destnum, stringlist *src, ulong srcnum) { return strpos_q(strget(dest, destnum)->s, strptr(src, srcnum)); }
|
||||
|
||||
void strtr(char *dest, char *before, char *after) {
|
||||
int i, l, sl = strlen(dest), bsl = strlen(before), asl = strlen(after);
|
||||
if((bsl != asl) || bsl == 0)return;
|
||||
for(i=0;i<sl;i++) {
|
||||
for(l=0;l<bsl;l++) {
|
||||
if(dest[i] == before[l])dest[i] = after[l];
|
||||
}
|
||||
}
|
||||
}
|
||||
void strtr(string *dest, char *before, char *after) { strtr(dest->s, before, after); }
|
||||
void strtr(stringlist *dest, ulong num, char *before, char *after) { strtr(strptr(dest, num), before, after); }
|
||||
|
||||
ulong strbegin(char *str, char *key) {
|
||||
int i, ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return 1;
|
||||
if(!memcmp(str, key, ksl))return 0;
|
||||
return 1;
|
||||
}
|
||||
ulong strbegin(string *str, char *key) { return strbegin(str->s, key); }
|
||||
ulong strbegin(stringlist *str, ulong num, char *key) { return strbegin(strptr(str, num), key); }
|
||||
|
||||
ulong stribegin(char *str, char *key) {
|
||||
int i, ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return 1;
|
||||
for(i=0;i<ksl;i++) {
|
||||
if(str[i] >= 'A' && str[i] <= 'Z') {
|
||||
if(str[i] != key[i] && str[i]+0x20 != key[i])return 1;
|
||||
} else if(str[i] >= 'a' && str[i] <= 'z') {
|
||||
if(str[i] != key[i] && str[i]-0x20 != key[i])return 1;
|
||||
} else {
|
||||
if(str[i] != key[i])return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ulong stribegin(string *str, char *key) { return stribegin(str->s, key); }
|
||||
ulong stribegin(stringlist *str, ulong num, char *key) { return stribegin(strptr(str, num), key); }
|
||||
|
||||
ulong strend(char *str, char *key) {
|
||||
int i, ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return 1;
|
||||
if(!memcmp(str + ssl - ksl, key, ksl))return 0;
|
||||
return 1;
|
||||
}
|
||||
ulong strend(string *str, char *key) { return strend(str->s, key); }
|
||||
ulong strend(stringlist *str, ulong num, char *key) { return strend(strptr(str, num), key); }
|
||||
|
||||
ulong striend(char *str, char *key) {
|
||||
int i, z, ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return 1;
|
||||
for(i=ssl-ksl, z=0;i<ssl;i++, z++) {
|
||||
if(str[i] >= 'A' && str[i] <= 'Z') {
|
||||
if(str[i] != key[z] && str[i]+0x20 != key[z])return 1;
|
||||
} else if(str[i] >= 'a' && str[i] <= 'z') {
|
||||
if(str[i] != key[z] && str[i]-0x20 != key[z])return 1;
|
||||
} else {
|
||||
if(str[i] != key[z])return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ulong striend(string *str, char *key) { return striend(str->s, key); }
|
||||
ulong striend(stringlist *str, ulong num, char *key) { return striend(strptr(str, num), key); }
|
||||
|
||||
void strltrim(char *str, char *key) {
|
||||
int i, ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return;
|
||||
if(!strbegin(str, key)) {
|
||||
for(i=0;i<ssl-ksl;i++)str[i] = str[i + ksl];
|
||||
str[i] = 0;
|
||||
}
|
||||
}
|
||||
void strltrim(string *str, char *key) { strltrim(str->s, key); }
|
||||
void strltrim(stringlist *str, ulong num, char *key) { strltrim(strptr(str, num), key); }
|
||||
|
||||
void striltrim(char *str, char *key) {
|
||||
int i, ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return;
|
||||
if(!stribegin(str, key)) {
|
||||
for(i=0;i<ssl-ksl;i++)str[i] = str[i + ksl];
|
||||
str[i] = 0;
|
||||
}
|
||||
}
|
||||
void striltrim(string *str, char *key) { striltrim(str->s, key); }
|
||||
void striltrim(stringlist *str, ulong num, char *key) { striltrim(strptr(str, num), key); }
|
||||
|
||||
void strrtrim(char *str, char *key) {
|
||||
int ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return;
|
||||
if(!strend(str, key)) {
|
||||
str[ssl - ksl] = 0;
|
||||
}
|
||||
}
|
||||
void strrtrim(string *str, char *key) { strrtrim(str->s, key); }
|
||||
void strrtrim(stringlist *str, ulong num, char *key) { strrtrim(strptr(str, num), key); }
|
||||
|
||||
void strirtrim(char *str, char *key) {
|
||||
int ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl)return;
|
||||
if(!striend(str, key)) {
|
||||
str[ssl - ksl] = 0;
|
||||
}
|
||||
}
|
||||
void strirtrim(string *str, char *key) { strirtrim(str->s, key); }
|
||||
void strirtrim(stringlist *str, ulong num, char *key) { strirtrim(strptr(str, num), key); }
|
||||
|
||||
ulong strhex(char *str) {
|
||||
ulong r = 0, m = 0;
|
||||
int i, ssl = strlen(str);
|
||||
byte x;
|
||||
for(i=0;i<ssl;i++) {
|
||||
if(str[i] >= '0' && str[i] <= '9');
|
||||
else if(str[i] >= 'A' && str[i] <= 'F');
|
||||
else if(str[i] >= 'a' && str[i] <= 'f');
|
||||
else break;
|
||||
}
|
||||
for(--i;i>=0;i--, m+=4) {
|
||||
x = str[i];
|
||||
if(x >= '0' && x <= '9')x -= '0';
|
||||
else if(x >= 'A' && x <= 'F')x -= 'A' - 0x0a;
|
||||
else if(x >= 'a' && x <= 'f')x -= 'a' - 0x0a;
|
||||
else return r;
|
||||
r |= x << m;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
ulong strhex(string *str) { return strhex(str->s); }
|
||||
ulong strhex(stringlist *str, ulong num) { return strhex(strptr(str, num)); }
|
||||
|
||||
ulong strdec(char *str) {
|
||||
ulong r = 0, m = 1;
|
||||
int i, ssl = strlen(str);
|
||||
byte x;
|
||||
for(i=0;i<ssl;i++) {
|
||||
if(str[i] >= '0' && str[i] <= '9');
|
||||
else break;
|
||||
}
|
||||
for(--i;i>=0;i--, m*=10) {
|
||||
x = str[i];
|
||||
if(x >= '0' && x <= '9')x -= '0';
|
||||
else return r;
|
||||
r += x * m;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
ulong strdec(string *str) { return strdec(str->s); }
|
||||
ulong strdec(stringlist *str, ulong num) { return strdec(strptr(str, num)); }
|
||||
|
||||
ulong strbin(char *str) {
|
||||
ulong r = 0, m = 0;
|
||||
int i, ssl = strlen(str);
|
||||
byte x;
|
||||
for(i=0;i<ssl;i++) {
|
||||
if(str[i] == '0' || str[i] == '1');
|
||||
else break;
|
||||
}
|
||||
for(--i;i>=0;i--, m++) {
|
||||
x = str[i];
|
||||
if(str[i] == '0' || str[i] == '1')x -= '0';
|
||||
else return r;
|
||||
r |= x << m;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
ulong strbin(string *str) { return strbin(str->s); }
|
||||
ulong strbin(stringlist *str, ulong num) { return strbin(strptr(str, num)); }
|
||||
|
||||
#include "libstr_math.cpp"
|
||||
#include "libstr_split.cpp"
|
||||
#include "libstr_replace.cpp"
|
||||
#include "libstr_sprintf.cpp"
|
||||
@@ -1,181 +0,0 @@
|
||||
#define STRMATH_ADD 1
|
||||
#define STRMATH_SUB 2
|
||||
#define STRMATH_MUL 3
|
||||
#define STRMATH_DIV 4
|
||||
#define STRMATH_MOD 5
|
||||
#define STRMATH_AND 6
|
||||
#define STRMATH_OR 7
|
||||
#define STRMATH_XOR 8
|
||||
#define STRMATH_SHL 9
|
||||
#define STRMATH_SHR 10
|
||||
|
||||
#define STRMATH_LINKED 64
|
||||
|
||||
#define STRMATHMODE_NEG 1
|
||||
#define STRMATHMODE_NOT 2
|
||||
|
||||
#define __strunktonum() \
|
||||
if (s1[0] == '0' && s1[1] == 'x')r = strhex(s1 + 2); \
|
||||
else if(s1[0] == '0' && s1[1] == 'b')r = strbin(s1 + 2); \
|
||||
else r = strdec(s1)
|
||||
|
||||
#define __strmath_setmode() \
|
||||
if (str[i] == '-') { mode = STRMATHMODE_NEG; i++; } \
|
||||
else if(str[i] == '~') { mode = STRMATHMODE_NOT; i++; } \
|
||||
else if(str[i] == '+') { i++; } \
|
||||
else mode=0
|
||||
|
||||
#define __strmath_modeset() \
|
||||
if (mode == STRMATHMODE_NEG)r *= -1; \
|
||||
else if(mode == STRMATHMODE_NOT)r =~ r
|
||||
|
||||
#define __strmath_set(__x) \
|
||||
s1[z] = 0; \
|
||||
z = 0; \
|
||||
__strunktonum(); \
|
||||
__strmath_modeset(); \
|
||||
array[array_size++] = r; \
|
||||
array_gate[array_size] = __x
|
||||
|
||||
/***************************************
|
||||
strmath(str)
|
||||
resolves all math entities from within
|
||||
str, and returns numerical result
|
||||
example: strmath("5+5")=10
|
||||
***************************************/
|
||||
ulong p_strmath(char *str) {
|
||||
int i = 0, ssl = strlen(str);
|
||||
byte x, mode = 0;
|
||||
ulong r, array[128], array_size = 0, z = 0;
|
||||
byte array_gate[128];
|
||||
char *s1;
|
||||
if(!ssl)return 0;
|
||||
s1 = (char*)malloc(ssl + 1);
|
||||
__strmath_setmode();
|
||||
while(i < ssl) {
|
||||
x = str[i++];
|
||||
if (x == '+') { __strmath_set(STRMATH_ADD); __strmath_setmode(); }
|
||||
else if(x == '-') { __strmath_set(STRMATH_SUB); __strmath_setmode(); }
|
||||
else if(x == '*') { __strmath_set(STRMATH_MUL); __strmath_setmode(); }
|
||||
else if(x == '/') { __strmath_set(STRMATH_DIV); __strmath_setmode(); }
|
||||
else if(x == '%') { __strmath_set(STRMATH_MOD); __strmath_setmode(); }
|
||||
else if(x == '&') { __strmath_set(STRMATH_AND); __strmath_setmode(); }
|
||||
else if(x == '|') { __strmath_set(STRMATH_OR ); __strmath_setmode(); }
|
||||
else if(x == '^') { __strmath_set(STRMATH_XOR); __strmath_setmode(); }
|
||||
else if(x == '<' && str[i] == '<') { __strmath_set(STRMATH_SHL); i++; __strmath_setmode(); }
|
||||
else if(x == '>' && str[i] == '>') { __strmath_set(STRMATH_SHR); i++; __strmath_setmode(); }
|
||||
else s1[z++] = x;
|
||||
}
|
||||
s1[z] = 0;
|
||||
__strunktonum();
|
||||
__strmath_modeset();
|
||||
array[array_size++] = r;
|
||||
free(s1);
|
||||
|
||||
for(i=1;i<array_size;i++) {
|
||||
if (array_gate[i] == STRMATH_SHL) { array[i-1] <<= array[i]; array_gate[i] = STRMATH_LINKED; }
|
||||
else if(array_gate[i] == STRMATH_SHR) { array[i-1] >>= array[i]; array_gate[i] = STRMATH_LINKED; }
|
||||
}
|
||||
|
||||
for(i=1;i<array_size;i++) {
|
||||
if (array_gate[i] == STRMATH_MUL) { array[i-1] *= array[i]; array_gate[i] = STRMATH_LINKED; }
|
||||
else if(array_gate[i] == STRMATH_DIV) { array[i-1] /= array[i]; array_gate[i] = STRMATH_LINKED; }
|
||||
}
|
||||
|
||||
r = array[0];
|
||||
for(i=1;i<array_size;i++) {
|
||||
if (array_gate[i] == STRMATH_ADD)r += array[i];
|
||||
else if(array_gate[i] == STRMATH_SUB)r -= array[i];
|
||||
else if(array_gate[i] == STRMATH_MOD)r %= array[i];
|
||||
else if(array_gate[i] == STRMATH_AND)r &= array[i];
|
||||
else if(array_gate[i] == STRMATH_OR )r |= array[i];
|
||||
else if(array_gate[i] == STRMATH_XOR)r ^= array[i];
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ulong strmath(char *in_str) {
|
||||
ulong r = 0;
|
||||
ulong pdepth = 0, cpdepth, maxpdepth = 0;
|
||||
ulong pstart, pend, spos;
|
||||
int i, sc, sl = strlen(in_str);
|
||||
char *str = (char*)malloc(sl + 1), *str0;
|
||||
char *pstr;
|
||||
char num[64];
|
||||
strcpy(str, in_str);
|
||||
|
||||
for(i=0;i<sl;i++) {
|
||||
if(str[i]=='(') {
|
||||
pdepth++;
|
||||
if(pdepth > maxpdepth)maxpdepth = pdepth;
|
||||
} else if(str[i]==')') {
|
||||
if(pdepth == 0) {
|
||||
free(str);
|
||||
return null; //error! too many )'s
|
||||
}
|
||||
pdepth --;
|
||||
}
|
||||
}
|
||||
|
||||
if(pdepth != 0) {
|
||||
free(str);
|
||||
return null; //error! unequal ('s to )'s
|
||||
}
|
||||
|
||||
pdepth = maxpdepth;
|
||||
while(pdepth) {
|
||||
cpdepth = 0;
|
||||
for(i=0;i<sl;) {
|
||||
if(str[i] == '(')cpdepth++;
|
||||
if(str[i] == ')')cpdepth--;
|
||||
i++;
|
||||
if(cpdepth == pdepth) {
|
||||
pstart = i;
|
||||
while(str[i] != ')')i++;
|
||||
pend = i;
|
||||
|
||||
pstr = (char*)malloc(pend-pstart+1);
|
||||
memcpy(pstr, str+pstart, pend-pstart);
|
||||
pstr[pend-pstart]=0;
|
||||
r = p_strmath(pstr);
|
||||
free(pstr);
|
||||
sprintf(num, "%d", r);
|
||||
str0 = (char*)malloc(sl + strlen(num) + 1);
|
||||
memcpy(str0, str, pstart - 1);
|
||||
spos = pstart - 1;
|
||||
memcpy(str0+spos, num, strlen(num));
|
||||
spos += strlen(num);
|
||||
sc = spos;
|
||||
memcpy(str0+spos, str+pend+1, sl-pend-1);
|
||||
spos += sl - pend - 1;
|
||||
sl = spos;
|
||||
str0[sl] = 0;
|
||||
free(str);
|
||||
str = str0;
|
||||
cpdepth--;
|
||||
i = sc;
|
||||
}
|
||||
}
|
||||
pdepth--;
|
||||
}
|
||||
|
||||
r = p_strmath(str);
|
||||
|
||||
free(str);
|
||||
return r;
|
||||
}
|
||||
ulong strmath(string *str) { return strmath(str->s); }
|
||||
ulong strmath(stringlist *str, ulong num) { return strmath(strptr(str, num)); }
|
||||
|
||||
ulong strmathentity(char *str) {
|
||||
int i, ssl = strlen(str);
|
||||
for(i=0;i<ssl;i++) {
|
||||
if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' ||
|
||||
str[i] == '%' || str[i] == '&' || str[i] == '|' || str[i] == '^' ||
|
||||
(str[i] == '<' && str[i+1] == '<') || (str[i] == '>' && str[i+1] == '>'))return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ulong strmathentity(string *str) { return strmathentity(str->s); }
|
||||
ulong strmathentity(stringlist *str, ulong num) { return strmathentity(strptr(str, num)); }
|
||||
@@ -1,82 +0,0 @@
|
||||
void replace(string *str, char *key, char *token) {
|
||||
int i, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str);
|
||||
ulong replace_count = 0, size;
|
||||
char *data;
|
||||
if(ksl > ssl)return;
|
||||
if(tsl > ksl) { //the new string may be longer than the old string...
|
||||
for(i=0;i<=ssl-ksl;) { //so let's find out how big of a string we'll need...
|
||||
if(!memcmp(str->s + i, key, ksl)) {
|
||||
replace_count++;
|
||||
i += ksl;
|
||||
} else i++;
|
||||
}
|
||||
size = ssl + ((tsl - ksl) * replace_count);
|
||||
if(size > str->size)strresize(str, size);
|
||||
}
|
||||
data = (char*)malloc(size + 1);
|
||||
for(i=z=0;i<ssl;) {
|
||||
if(i <= ssl - ksl) {
|
||||
if(!memcmp(str->s + i, key, ksl)) {
|
||||
memcpy(data + z, token, tsl);
|
||||
z += tsl;
|
||||
i += ksl;
|
||||
} else data[z++] = str->s[i++];
|
||||
} else data[z++] = str->s[i++];
|
||||
}
|
||||
data[z] = 0;
|
||||
strcpy(str, data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
void replace_q(string *str, char *key, char *token) {
|
||||
int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str);
|
||||
byte x;
|
||||
ulong replace_count = 0, size;
|
||||
char *data;
|
||||
if(ksl > ssl)return;
|
||||
if(tsl > ksl) {
|
||||
for(i=0;i<=ssl-ksl;) {
|
||||
x = str->s[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
l = i;
|
||||
i++;
|
||||
while(str->s[i++] != x) {
|
||||
if(i == ssl) {
|
||||
i = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!memcmp(str->s + i, key, ksl)) {
|
||||
replace_count++;
|
||||
i += ksl;
|
||||
} else i++;
|
||||
}
|
||||
size = ssl + ((tsl - ksl) * replace_count);
|
||||
if(size > str->size)strresize(str, size);
|
||||
}
|
||||
data = (char*)malloc(size + 1);
|
||||
for(i=z=0;i<ssl;) {
|
||||
x = str->s[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
l = i++;
|
||||
while(str->s[i] != x && i < ssl)i++;
|
||||
if(i >= ssl)i = l;
|
||||
else {
|
||||
memcpy(data + z, str->s + l, i - l);
|
||||
z += i - l;
|
||||
}
|
||||
}
|
||||
if(i <= ssl - ksl) {
|
||||
if(!memcmp(str->s + i, key, ksl)) {
|
||||
memcpy(data + z, token, tsl);
|
||||
z += tsl;
|
||||
i += ksl;
|
||||
replace_count++;
|
||||
} else data[z++] = str->s[i++];
|
||||
} else data[z++] = str->s[i++];
|
||||
}
|
||||
data[z] = 0;
|
||||
strcpy(str, data);
|
||||
free(data);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
void split(stringlist *dest, char *key, char *src) {
|
||||
int i, ssl = strlen(src), ksl = strlen(key);
|
||||
byte x;
|
||||
ulong lp = 0, split_count = 0;
|
||||
for(i=0;i<=ssl-ksl;) {
|
||||
if(!memcmp(src + i, key, ksl)) {
|
||||
x = src[i];
|
||||
src[i] = 0;
|
||||
strcpy(dest, split_count++, src + lp);
|
||||
src[i] = x;
|
||||
i += ksl;
|
||||
lp = i;
|
||||
} else i++;
|
||||
}
|
||||
strcpy(dest, split_count++, src + lp);
|
||||
}
|
||||
void split(stringlist *dest, char *key, string *src) { split(dest, key, src->s); }
|
||||
|
||||
void split_q(stringlist *dest, char *key, char *src) {
|
||||
int i, z, ssl = strlen(src), ksl = strlen(key);
|
||||
byte x;
|
||||
ulong lp = 0, split_count = 0;
|
||||
for(i=0;i<=ssl-ksl;) {
|
||||
x = src[i];
|
||||
if(x=='\"' || x=='\'') {
|
||||
z = i++;
|
||||
while(src[i] != x && i < ssl)i++;
|
||||
if(i >= ssl)i = z;
|
||||
}
|
||||
if(!memcmp(src + i, key, ksl)) {
|
||||
x = src[i];
|
||||
src[i] = 0;
|
||||
strcpy(dest, split_count++, src + lp);
|
||||
src[i] = x;
|
||||
i += ksl;
|
||||
lp = i;
|
||||
} else i++;
|
||||
}
|
||||
strcpy(dest, split_count++, src + lp);
|
||||
}
|
||||
void split_q(stringlist *dest, char *key, string *src) { split_q(dest, key, src->s); }
|
||||
@@ -1,130 +0,0 @@
|
||||
void numtobin(char *s, ulong num) {
|
||||
ulong mask = 0x80000000, len = 0, z = 0;
|
||||
for(;mask;mask>>=1,len++) { if(num&mask)break; }
|
||||
len = 32 - len;
|
||||
do {
|
||||
if(num&(1<<(len-1)))s[z++] = '1';
|
||||
else s[z++] = '0';
|
||||
}while(--len);
|
||||
s[z] = 0;
|
||||
}
|
||||
|
||||
void sprintf(string *str, char *s, ...) {
|
||||
va_list args;
|
||||
char t[2], n[256];
|
||||
int i, l, sl, z;
|
||||
byte pad_type, pad_len;
|
||||
ulong num;
|
||||
char *r;
|
||||
va_start(args, s);
|
||||
strcpy(str, "");
|
||||
for(i=0;i<strlen(s);i++) {
|
||||
if(s[i] == '%') {
|
||||
i++;
|
||||
if(s[i] == '0' && s[i+1] == '.' && (s[i+2] >= '0' && s[i+2] <= '9')) {
|
||||
pad_type = 1;
|
||||
if(s[i+3] >= '0' && s[i+3] <= '9') { pad_len = (s[i+2]-'0')*10 + (s[i+3]-'0'); i+=4; }
|
||||
else { pad_len = (s[i+2]-'0'); i+=3; }
|
||||
}
|
||||
else if(s[i] >= '0' && s[i] <= '9') {
|
||||
pad_type = 2;
|
||||
if(s[i+1] >= '0' && s[i+1] <= '9') { pad_len = (s[i]-'0')*10 + (s[i+1]-'0'); i+=2; }
|
||||
else { pad_len = (s[i]-'0'); i+=1; }
|
||||
}
|
||||
else { pad_type = 0; }
|
||||
|
||||
if(s[i] == 'd') {
|
||||
num = va_arg(args, ulong);
|
||||
sprintf(n, "%d", num);
|
||||
} else if(s[i] == 'x') {
|
||||
num = va_arg(args, ulong);
|
||||
sprintf(n, "%x", num);
|
||||
} else if(s[i] == 'b') {
|
||||
num = va_arg(args, ulong);
|
||||
numtobin(n, num);
|
||||
} else if(s[i] == 's') {
|
||||
r = va_arg(args, char*);
|
||||
}
|
||||
|
||||
if(pad_type != 0) {
|
||||
if(s[i] == 's')sl = strlen(r);
|
||||
else sl = strlen(n);
|
||||
if(sl < pad_len) {
|
||||
while(sl < pad_len) {
|
||||
strcat(str, (pad_type == 1)?"0":" ");
|
||||
sl++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(s[i] == 's')strcat(str, r);
|
||||
else strcat(str, n);
|
||||
} else {
|
||||
t[0] = s[i];
|
||||
t[1] = 0;
|
||||
strcat(str, t);
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void sprintf(stringlist *str_list, ulong str_num, char *s, ...) {
|
||||
va_list args;
|
||||
char t[2], n[256];
|
||||
int i, l, sl, z;
|
||||
byte pad_type, pad_len;
|
||||
ulong num;
|
||||
char *r;
|
||||
string *str = strget(str_list, str_num);
|
||||
va_start(args, s);
|
||||
strcpy(str, "");
|
||||
for(i=0;i<strlen(s);i++) {
|
||||
if(s[i] == '%') {
|
||||
i++;
|
||||
if(s[i] == '0' && s[i+1] == '.' && (s[i+2] >= '0' && s[i+2] <= '9')) {
|
||||
pad_type = 1;
|
||||
if(s[i+3] >= '0' && s[i+3] <= '9') { pad_len = (s[i+2]-'0')*10 + (s[i+3]-'0'); i+=4; }
|
||||
else { pad_len = (s[i+2]-'0'); i+=3; }
|
||||
}
|
||||
else if(s[i] >= '0' && s[i] <= '9') {
|
||||
pad_type = 2;
|
||||
if(s[i+1] >= '0' && s[i+1] <= '9') { pad_len = (s[i]-'0')*10 + (s[i+1]-'0'); i+=2; }
|
||||
else { pad_len = (s[i]-'0'); i+=1; }
|
||||
}
|
||||
else { pad_type = 0; }
|
||||
|
||||
if(s[i] == 'd') {
|
||||
num = va_arg(args, ulong);
|
||||
sprintf(n, "%d", num);
|
||||
} else if(s[i] == 'x') {
|
||||
num = va_arg(args, ulong);
|
||||
sprintf(n, "%x", num);
|
||||
} else if(s[i] == 'b') {
|
||||
num = va_arg(args, ulong);
|
||||
numtobin(n, num);
|
||||
} else if(s[i] == 's') {
|
||||
r = va_arg(args, char*);
|
||||
}
|
||||
|
||||
if(pad_type != 0) {
|
||||
if(s[i] == 's')sl = strlen(r);
|
||||
else sl = strlen(n);
|
||||
if(sl < pad_len) {
|
||||
while(sl < pad_len) {
|
||||
strcat(str, (pad_type == 1)?"0":" ");
|
||||
sl++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(s[i] == 's')strcat(str, r);
|
||||
else strcat(str, n);
|
||||
} else {
|
||||
t[0] = s[i];
|
||||
t[1] = 0;
|
||||
strcat(str, t);
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
ulong __vector_resize(ulong val)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<32;i++) {
|
||||
if((1<<i) >= val)break;
|
||||
}
|
||||
//if the value is >2 million, this will fail, in which case,
|
||||
//just use value. otherwise, use the power of 2.
|
||||
if((1<<i) > val)val = 1<<i;
|
||||
return val;
|
||||
}
|
||||
|
||||
class vectorlist {
|
||||
public:
|
||||
ulong *list, *newlist, size, newsize, max_size;
|
||||
|
||||
void alloc(ulong size) {
|
||||
if(size < max_size)return;
|
||||
newsize = __vector_resize(size);
|
||||
newlist = (ulong*)malloc(newsize*4);
|
||||
memcpy(newlist, list, max_size*4);
|
||||
free(list);
|
||||
list = newlist;
|
||||
max_size = newsize;
|
||||
}
|
||||
|
||||
void add(ulong val) {
|
||||
size++;
|
||||
if(size > max_size)alloc(size + 1);
|
||||
list[size - 1] = val;
|
||||
}
|
||||
|
||||
void set(ulong num, ulong val) {
|
||||
if(num >= max_size)alloc(num + 1);
|
||||
list[num] = val;
|
||||
if(++num > size)size = num;
|
||||
}
|
||||
|
||||
ulong get(ulong num) {
|
||||
if(num >= max_size)return 0;
|
||||
return list[num];
|
||||
}
|
||||
|
||||
vectorlist() {
|
||||
list = 0;
|
||||
size = 0;
|
||||
max_size = 8;
|
||||
list = (ulong*)malloc(8*4);
|
||||
}
|
||||
|
||||
~vectorlist() {
|
||||
if(list)free(list);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,260 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "../timing/timing.h"
|
||||
#include "../cpu/g65816.h"
|
||||
#include "../bridge/bridge.h"
|
||||
|
||||
extern g65816 *gx816;
|
||||
extern snes_timer *snes_time;
|
||||
extern videostate render;
|
||||
extern debugstate debugger;
|
||||
extern port_bridge *cpu_apu_bridge;
|
||||
ppustate ppu;
|
||||
|
||||
#include "ppu_cache.cpp"
|
||||
|
||||
#include "ppu_spc.cpp"
|
||||
#include "ppu_dma.cpp"
|
||||
#include "ppu_screen.cpp"
|
||||
#include "ppu_vram.cpp"
|
||||
#include "ppu_palette.cpp"
|
||||
#include "ppu_timing.cpp"
|
||||
#include "ppu_oam.cpp"
|
||||
#include "ppu_wram.cpp"
|
||||
#include "ppu_mode7.cpp"
|
||||
#include "ppu_scroll.cpp"
|
||||
#include "ppu_muldiv.cpp"
|
||||
#include "ppu_window.cpp"
|
||||
#include "ppu_addsub.cpp"
|
||||
#include "ppu_joypad.cpp"
|
||||
#include "ppu_misc.cpp"
|
||||
|
||||
#include "ppu.cpp"
|
||||
|
||||
byte mmio_read(word addr) {
|
||||
snes_time->update_timer();
|
||||
|
||||
if((snes_time->hscan_pos >= 274 || snes_time->vscan_pos >= (ppu.visible_scanlines + 1)) || ppu.display_disable == true) {
|
||||
switch(addr) {
|
||||
case 0x2139:return mmio_r2139();
|
||||
case 0x213a:return mmio_r213a();
|
||||
case 0x213b:return mmio_r213b();
|
||||
}
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x2134:return mmio_r2134();
|
||||
case 0x2135:return mmio_r2135();
|
||||
case 0x2136:return mmio_r2136();
|
||||
case 0x2137:return mmio_r2137();
|
||||
case 0x2138:return mmio_r2138();
|
||||
case 0x213c:return mmio_r213c();
|
||||
case 0x213d:return mmio_r213d();
|
||||
case 0x213e:return mmio_r213e();
|
||||
case 0x213f:return mmio_r213f();
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x2140:case 0x2141:case 0x2142:case 0x2143:
|
||||
case 0x2144:case 0x2145:case 0x2146:case 0x2147:
|
||||
case 0x2148:case 0x2149:case 0x214a:case 0x214b:
|
||||
case 0x214c:case 0x214d:case 0x214e:case 0x214f:
|
||||
case 0x2150:case 0x2151:case 0x2152:case 0x2153:
|
||||
case 0x2154:case 0x2155:case 0x2156:case 0x2157:
|
||||
case 0x2158:case 0x2159:case 0x215a:case 0x215b:
|
||||
case 0x215c:case 0x215d:case 0x215e:case 0x215f:
|
||||
case 0x2160:case 0x2161:case 0x2162:case 0x2163:
|
||||
case 0x2164:case 0x2165:case 0x2166:case 0x2167:
|
||||
case 0x2168:case 0x2169:case 0x216a:case 0x216b:
|
||||
case 0x216c:case 0x216d:case 0x216e:case 0x216f:
|
||||
case 0x2170:case 0x2171:case 0x2172:case 0x2173:
|
||||
case 0x2174:case 0x2175:case 0x2176:case 0x2177:
|
||||
case 0x2178:case 0x2179:case 0x217a:case 0x217b:
|
||||
case 0x217c:case 0x217d:case 0x217e:case 0x217f:
|
||||
return mmio_rspc((addr & 3));
|
||||
break;
|
||||
|
||||
case 0x2180:return mmio_r2180();
|
||||
|
||||
case 0x21c2:return mmio_r21c2();
|
||||
case 0x21c3:return mmio_r21c3();
|
||||
|
||||
case 0x4016:return mmio_r4016();
|
||||
case 0x4210:return mmio_r4210();
|
||||
case 0x4211:return mmio_r4211();
|
||||
case 0x4212:return mmio_r4212();
|
||||
case 0x4214:return mmio_r4214();
|
||||
case 0x4215:return mmio_r4215();
|
||||
case 0x4216:return mmio_r4216();
|
||||
case 0x4217:return mmio_r4217();
|
||||
case 0x4218:return mmio_r4218();
|
||||
case 0x4219:return mmio_r4219();
|
||||
default:
|
||||
/*
|
||||
dprintf("* mmio: unknown read [%0.4x]", addr);
|
||||
debug_set_state(DEBUGMODE_WAIT);
|
||||
disas_g65816_op();
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
if(addr >= 0x4300 && addr <= 0x437f) {
|
||||
if((addr & 0xf) == 0x8)return mmio_r43x8((addr >> 4) & 7);
|
||||
if((addr & 0xf) == 0x9)return mmio_r43x9((addr >> 4) & 7);
|
||||
if((addr & 0xf) == 0xa)return mmio_r43xa((addr >> 4) & 7);
|
||||
return ppu.mmio_mem_43xx[addr & 0x7f];
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void mmio_write(word addr, byte value) {
|
||||
snes_time->update_timer();
|
||||
|
||||
if((snes_time->hscan_pos >= 274 || snes_time->vscan_pos >= (ppu.visible_scanlines + 1)) || ppu.display_disable == true) {
|
||||
switch(addr) {
|
||||
case 0x2118:mmio_w2118(value);break;
|
||||
case 0x2119:mmio_w2119(value);break;
|
||||
case 0x2122:mmio_w2122(value);break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x2100:mmio_w2100(value);break;
|
||||
case 0x2101:mmio_w2101(value);break;
|
||||
case 0x2102:mmio_w2102(value);break;
|
||||
case 0x2103:mmio_w2103(value);break;
|
||||
case 0x2104:mmio_w2104(value);break;
|
||||
case 0x2105:mmio_w2105(value);break;
|
||||
case 0x2106:mmio_w2106(value);break;
|
||||
case 0x2107:mmio_w2107(value);break;
|
||||
case 0x2108:mmio_w2108(value);break;
|
||||
case 0x2109:mmio_w2109(value);break;
|
||||
case 0x210a:mmio_w210a(value);break;
|
||||
case 0x210b:mmio_w210b(value);break;
|
||||
case 0x210c:mmio_w210c(value);break;
|
||||
case 0x210d:mmio_w210d(value);break;
|
||||
case 0x210e:mmio_w210e(value);break;
|
||||
case 0x210f:mmio_w210f(value);break;
|
||||
case 0x2110:mmio_w2110(value);break;
|
||||
case 0x2111:mmio_w2111(value);break;
|
||||
case 0x2112:mmio_w2112(value);break;
|
||||
case 0x2113:mmio_w2113(value);break;
|
||||
case 0x2114:mmio_w2114(value);break;
|
||||
case 0x2115:mmio_w2115(value);break;
|
||||
case 0x2116:mmio_w2116(value);break;
|
||||
case 0x2117:mmio_w2117(value);break;
|
||||
case 0x211a:mmio_w211a(value);break;
|
||||
case 0x211b:mmio_w211b(value);break;
|
||||
case 0x211c:mmio_w211c(value);break;
|
||||
case 0x211d:mmio_w211d(value);break;
|
||||
case 0x211e:mmio_w211e(value);break;
|
||||
case 0x211f:mmio_w211f(value);break;
|
||||
case 0x2120:mmio_w2120(value);break;
|
||||
case 0x2121:mmio_w2121(value);break;
|
||||
case 0x2123:mmio_w2123(value);break;
|
||||
case 0x2124:mmio_w2124(value);break;
|
||||
case 0x2125:mmio_w2125(value);break;
|
||||
case 0x2126:mmio_w2126(value);break;
|
||||
case 0x2127:mmio_w2127(value);break;
|
||||
case 0x2128:mmio_w2128(value);break;
|
||||
case 0x2129:mmio_w2129(value);break;
|
||||
case 0x212a:mmio_w212a(value);break;
|
||||
case 0x212b:mmio_w212b(value);break;
|
||||
case 0x212c:mmio_w212c(value);break;
|
||||
case 0x212d:mmio_w212d(value);break;
|
||||
case 0x212e:mmio_w212e(value);break;
|
||||
case 0x212f:mmio_w212f(value);break;
|
||||
case 0x2130:mmio_w2130(value);break;
|
||||
case 0x2131:mmio_w2131(value);break;
|
||||
case 0x2132:mmio_w2132(value);break;
|
||||
case 0x2133:mmio_w2133(value);break;
|
||||
}
|
||||
|
||||
if(addr >= 0x2140 && addr <= 0x217f) {
|
||||
mmio_wspc(addr & 3, value);
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x2180:mmio_w2180(value);break;
|
||||
case 0x2181:mmio_w2181(value);break;
|
||||
case 0x2182:mmio_w2182(value);break;
|
||||
case 0x2183:mmio_w2183(value);break;
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x4016:mmio_w4016(value);break;
|
||||
case 0x4200:mmio_w4200(value);break;
|
||||
case 0x4201:mmio_w4201(value);break;
|
||||
case 0x4202:mmio_w4202(value);break;
|
||||
case 0x4203:mmio_w4203(value);break;
|
||||
case 0x4204:mmio_w4204(value);break;
|
||||
case 0x4205:mmio_w4205(value);break;
|
||||
case 0x4206:mmio_w4206(value);break;
|
||||
case 0x4207:mmio_w4207(value);break;
|
||||
case 0x4208:mmio_w4208(value);break;
|
||||
case 0x4209:mmio_w4209(value);break;
|
||||
case 0x420a:mmio_w420a(value);break;
|
||||
case 0x420b:mmio_w420b(value);break;
|
||||
case 0x420c:mmio_w420c(value);break;
|
||||
case 0x420d:mmio_w420d(value);break;
|
||||
|
||||
case 0x4300:case 0x4310:case 0x4320:case 0x4330:
|
||||
case 0x4340:case 0x4350:case 0x4360:case 0x4370:
|
||||
mmio_w43x0((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4301:case 0x4311:case 0x4321:case 0x4331:
|
||||
case 0x4341:case 0x4351:case 0x4361:case 0x4371:
|
||||
mmio_w43x1((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4302:case 0x4312:case 0x4322:case 0x4332:
|
||||
case 0x4342:case 0x4352:case 0x4362:case 0x4372:
|
||||
mmio_w43x2((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4303:case 0x4313:case 0x4323:case 0x4333:
|
||||
case 0x4343:case 0x4353:case 0x4363:case 0x4373:
|
||||
mmio_w43x3((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4304:case 0x4314:case 0x4324:case 0x4334:
|
||||
case 0x4344:case 0x4354:case 0x4364:case 0x4374:
|
||||
mmio_w43x4((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4305:case 0x4315:case 0x4325:case 0x4335:
|
||||
case 0x4345:case 0x4355:case 0x4365:case 0x4375:
|
||||
mmio_w43x5((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4306:case 0x4316:case 0x4326:case 0x4336:
|
||||
case 0x4346:case 0x4356:case 0x4366:case 0x4376:
|
||||
mmio_w43x6((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4307:case 0x4317:case 0x4327:case 0x4337:
|
||||
case 0x4347:case 0x4357:case 0x4367:case 0x4377:
|
||||
mmio_w43x7((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4308:case 0x4318:case 0x4328:case 0x4338:
|
||||
case 0x4348:case 0x4358:case 0x4368:case 0x4378:
|
||||
mmio_w43x8((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x4309:case 0x4319:case 0x4329:case 0x4339:
|
||||
case 0x4349:case 0x4359:case 0x4369:case 0x4379:
|
||||
mmio_w43x9((addr >> 4) & 7, value);
|
||||
break;
|
||||
|
||||
case 0x430a:case 0x431a:case 0x432a:case 0x433a:
|
||||
case 0x434a:case 0x435a:case 0x436a:case 0x437a:
|
||||
mmio_w43xa((addr >> 4) & 7, value);
|
||||
break;
|
||||
}
|
||||
|
||||
if(addr >= 0x4300 && addr <= 0x437f) {
|
||||
ppu.mmio_mem_43xx[addr & 0x7f] = value;
|
||||
}
|
||||
}
|
||||
@@ -1,412 +0,0 @@
|
||||
#define RENDER_MAIN 0
|
||||
#define RENDER_SUB 1
|
||||
|
||||
#include "ppu_render.cpp"
|
||||
|
||||
byte layer_bg_lookup_mode0[12] = {
|
||||
BG4, BG3, OAM, BG4, BG3, OAM, BG2, BG1, OAM, BG2, BG1, OAM
|
||||
};
|
||||
|
||||
void ppu_render_line_mode0(void) {
|
||||
ppu_render_line_bg (7, 10, COLORDEPTH_4, BG1);
|
||||
ppu_render_line_bg (6, 9, COLORDEPTH_4, BG2);
|
||||
ppu_render_line_bg (1, 4, COLORDEPTH_4, BG3);
|
||||
ppu_render_line_bg (0, 3, COLORDEPTH_4, BG4);
|
||||
ppu_render_line_oam(2, 5, 8, 11);
|
||||
ppu_set_layer_pixels(12, layer_bg_lookup_mode0);
|
||||
}
|
||||
|
||||
byte layer_bg_lookup_mode1_pri0[10] = {
|
||||
BG3, OAM, BG3, OAM, BG2, BG1, OAM, BG2, BG1, OAM
|
||||
};
|
||||
|
||||
byte layer_bg_lookup_mode1_pri1[10] = {
|
||||
BG3, OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM, BG3
|
||||
};
|
||||
|
||||
void ppu_render_line_mode1(void) {
|
||||
switch(ppu.bg_priority_mode) {
|
||||
case 0:
|
||||
ppu_render_line_bg (5, 8, COLORDEPTH_16, BG1);
|
||||
ppu_render_line_bg (4, 7, COLORDEPTH_16, BG2);
|
||||
ppu_render_line_bg (0, 2, COLORDEPTH_4, BG3);
|
||||
ppu_render_line_oam(1, 3, 6, 9);
|
||||
ppu_set_layer_pixels(10, layer_bg_lookup_mode1_pri0);
|
||||
break;
|
||||
case 1:
|
||||
ppu_render_line_bg (4, 7, COLORDEPTH_16, BG1);
|
||||
ppu_render_line_bg (3, 6, COLORDEPTH_16, BG2);
|
||||
ppu_render_line_bg (0, 9, COLORDEPTH_4, BG3);
|
||||
ppu_render_line_oam(1, 2, 5, 8);
|
||||
ppu_set_layer_pixels(10, layer_bg_lookup_mode1_pri1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
byte layer_bg_lookup_mode2[8] = {
|
||||
OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM
|
||||
};
|
||||
|
||||
void ppu_render_line_mode2(void) {
|
||||
ppu_render_line_bg (3, 6, COLORDEPTH_16, BG1);
|
||||
ppu_render_line_bg (2, 5, COLORDEPTH_16, BG2);
|
||||
ppu_render_line_oam(0, 1, 4, 7);
|
||||
ppu_set_layer_pixels(8, layer_bg_lookup_mode2);
|
||||
}
|
||||
|
||||
byte layer_bg_lookup_mode3[8] = {
|
||||
OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM
|
||||
};
|
||||
|
||||
void ppu_render_line_mode3(void) {
|
||||
ppu_render_line_bg (3, 6, COLORDEPTH_256, BG1);
|
||||
ppu_render_line_bg (2, 5, COLORDEPTH_16, BG2);
|
||||
ppu_render_line_oam(0, 1, 4, 7);
|
||||
ppu_set_layer_pixels(8, layer_bg_lookup_mode3);
|
||||
}
|
||||
|
||||
byte layer_bg_lookup_mode4[8] = {
|
||||
OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM
|
||||
};
|
||||
|
||||
void ppu_render_line_mode4(void) {
|
||||
ppu_render_line_bg (3, 6, COLORDEPTH_256, BG1);
|
||||
ppu_render_line_bg (2, 5, COLORDEPTH_4, BG2);
|
||||
ppu_render_line_oam(0, 1, 4, 7);
|
||||
ppu_set_layer_pixels(8, layer_bg_lookup_mode4);
|
||||
}
|
||||
|
||||
byte layer_bg_lookup_mode5[8] = {
|
||||
OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM
|
||||
};
|
||||
|
||||
void ppu_render_line_mode5(void) {
|
||||
ppu_render_line_bg (3, 6, COLORDEPTH_16, BG1);
|
||||
ppu_render_line_bg (2, 5, COLORDEPTH_4, BG2);
|
||||
ppu_render_line_oam(0, 1, 4, 7);
|
||||
ppu_set_layer_pixels(8, layer_bg_lookup_mode5);
|
||||
}
|
||||
|
||||
byte layer_bg_lookup_mode6[6] = {
|
||||
OAM, OAM, BG1, OAM, BG1, OAM
|
||||
};
|
||||
|
||||
void ppu_render_line_mode6(void) {
|
||||
ppu_render_line_bg (2, 4, COLORDEPTH_16, BG1);
|
||||
ppu_render_line_oam(0, 1, 3, 5);
|
||||
ppu_set_layer_pixels(8, layer_bg_lookup_mode6);
|
||||
}
|
||||
|
||||
byte layer_bg_lookup_mode7[5] = {
|
||||
OAM, BG1, OAM, OAM, OAM
|
||||
};
|
||||
|
||||
byte layer_bg_lookup_mode7_extbg[6] = {
|
||||
BG2, OAM, OAM, BG2, OAM, OAM
|
||||
};
|
||||
|
||||
void ppu_render_line_mode7(void) {
|
||||
if(ppu.mode7_extbg == false) {
|
||||
ppu_render_line_m7 (1, 0, 0); //bg2 priorities are ignored
|
||||
ppu_render_line_oam(0, 2, 3, 4);
|
||||
ppu_set_layer_pixels(5, layer_bg_lookup_mode7);
|
||||
} else {
|
||||
ppu_render_line_m7 (0, 0, 3); //bg1 priority is ignored
|
||||
ppu_render_line_oam(1, 2, 4, 5);
|
||||
ppu_set_layer_pixels(6, layer_bg_lookup_mode7_extbg);
|
||||
}
|
||||
}
|
||||
|
||||
void ppu_render_scanline(void) {
|
||||
int x, y;
|
||||
ppu.vline_pos = snes_time->vscan_pos;
|
||||
ppu.hirq_triggered = false;
|
||||
|
||||
//new screen initialize
|
||||
if(ppu.vline_pos == 0) {
|
||||
hdma_initialize();
|
||||
ppu.virq_triggered = false;
|
||||
gx816->nmi_pin = 1;
|
||||
}
|
||||
|
||||
//screen refresh
|
||||
if(ppu.vline_pos == ppu.visible_scanlines) {
|
||||
if(render.frame_count == 0) {
|
||||
UpdateDisplay();
|
||||
}
|
||||
render.frame_count++;
|
||||
if(render.frame_count >= render.frame_skip) {
|
||||
render.frame_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//automatic joypad read
|
||||
if(ppu.vline_pos == (ppu.visible_scanlines + 1) && ppu.auto_joypad_read == true) {
|
||||
UpdateJoypad();
|
||||
}
|
||||
|
||||
y = ppu.vline_pos;
|
||||
if(y > 0 && y < ppu.visible_scanlines && (render.frame_skip == 0 || render.frame_count == 0)) {
|
||||
if(ppu.display_disable == true) {
|
||||
memset(ppu.screen + (y << 1) * 512, 0, 2048);
|
||||
} else {
|
||||
ppu_clear_layer_cache();
|
||||
ppu_clear_pixel_cache();
|
||||
switch(ppu.bg_mode) {
|
||||
case 0:ppu_render_line_mode0();break;
|
||||
case 1:ppu_render_line_mode1();break;
|
||||
case 2:ppu_render_line_mode2();break;
|
||||
case 3:ppu_render_line_mode3();break;
|
||||
case 4:ppu_render_line_mode4();break;
|
||||
case 5:ppu_render_line_mode5();break;
|
||||
case 6:ppu_render_line_mode6();break;
|
||||
case 7:ppu_render_line_mode7();break;
|
||||
}
|
||||
ppu_render_line_to_screen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ppu_update_scanline(void) {
|
||||
static bool hdma_triggered = false;
|
||||
word current_vscan_pos;
|
||||
//starting a new screen?
|
||||
if(snes_time->vscan_wrapped == true) {
|
||||
snes_time->vscan_wrapped = false;
|
||||
}
|
||||
|
||||
if(snes_time->hscan_wrapped == true) {
|
||||
snes_time->hscan_wrapped = false;
|
||||
hdma_triggered = false;
|
||||
ppu_render_scanline();
|
||||
}
|
||||
|
||||
if(snes_time->hscan_pos >= 278 && hdma_triggered == false) {
|
||||
hdma_update();
|
||||
hdma_triggered = true;
|
||||
}
|
||||
|
||||
if(gx816->cpu_state == CPUSTATE_STP)return;
|
||||
|
||||
if(!(gx816->regs.p & PF_I)) {
|
||||
if(ppu.vcounter_enabled == true && ppu.hcounter_enabled == true) {
|
||||
if(snes_time->vscan_pos == ppu.virq_pos && ppu.virq_triggered == false) {
|
||||
if(snes_time->hscan_pos >= ppu.hirq_pos && ppu.hirq_triggered == false) {
|
||||
ppu.irq_triggered = true;
|
||||
ppu.virq_triggered = true;
|
||||
ppu.hirq_triggered = true;
|
||||
gx816->InvokeIRQ(0xffee);
|
||||
}
|
||||
}
|
||||
} else if(ppu.vcounter_enabled == true) {
|
||||
if(snes_time->vscan_pos == ppu.virq_pos && ppu.virq_triggered == false) {
|
||||
ppu.irq_triggered = true;
|
||||
ppu.virq_triggered = true;
|
||||
gx816->InvokeIRQ(0xffee);
|
||||
}
|
||||
} else if(ppu.hcounter_enabled == true) {
|
||||
if(snes_time->hscan_pos >= ppu.hirq_pos && ppu.hirq_triggered == false) {
|
||||
ppu.irq_triggered = true;
|
||||
ppu.hirq_triggered = true;
|
||||
gx816->InvokeIRQ(0xffee);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte oam_read(word addr) {
|
||||
byte r;
|
||||
addr &= 1023;
|
||||
if(addr >= 512) {
|
||||
addr &= 31;
|
||||
r = ppu.oam[addr + 512];
|
||||
debug_test_bp(BPSRC_OAM, BP_READ, addr + 512, r);
|
||||
} else {
|
||||
r = ppu.oam[addr];
|
||||
debug_test_bp(BPSRC_OAM, BP_READ, addr, r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void oam_write(word addr, byte value) {
|
||||
addr &= 1023;
|
||||
if(addr >= 512) {
|
||||
addr &= 31;
|
||||
ppu.oam[addr + 512] = value;
|
||||
debug_test_bp(BPSRC_OAM, BP_WRITE, addr + 512, value);
|
||||
} else {
|
||||
ppu.oam[addr] = value;
|
||||
debug_test_bp(BPSRC_OAM, BP_WRITE, addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
void PPUInit(byte first_time) {
|
||||
int i, l;
|
||||
byte r, g, b;
|
||||
double m;
|
||||
word *ptr;
|
||||
if(first_time == 1) {
|
||||
ppu.screen = (word*)malloc(512 * 478 * 2);
|
||||
ppu.vram = (byte*)malloc(0x10000);
|
||||
ppu.cgram = (byte*)malloc(512);
|
||||
ppu.oam = (byte*)malloc(544);
|
||||
ppu.light_table = (word*)malloc(16 * 65536 * 2);
|
||||
ppu_init_tiledata_cache();
|
||||
|
||||
for(l=0;l<16;l++) {
|
||||
ppu.mosaic_table[l] = (word*)malloc(4096 * 2);
|
||||
for(i=0;i<4096;i++) {
|
||||
ppu.mosaic_table[l][i] = (i / (l + 1)) * (l + 1);
|
||||
}
|
||||
}
|
||||
|
||||
ptr = (word*)ppu.light_table;
|
||||
for(l=0;l<16;l++) {
|
||||
m = (double)l / 15.0;
|
||||
for(i=0;i<65536;i++) {
|
||||
r = (i ) & 31;
|
||||
g = (i >> 5) & 31;
|
||||
b = (i >> 10) & 31;
|
||||
if(l == 0) { r = g = b = 0; }
|
||||
else if(l == 15);
|
||||
else {
|
||||
r = (double)r * m;
|
||||
g = (double)g * m;
|
||||
b = (double)b * m;
|
||||
}
|
||||
*ptr++ = (r) | (g << 5) | (b << 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
ppu_clear_tiledata_cache();
|
||||
memset(ppu.screen, 0, 512 * 478 * 2);
|
||||
memset(ppu.vram, 0, 0x10000);
|
||||
memset(ppu.cgram, 0, 512);
|
||||
memset(ppu.oam, 0, 544);
|
||||
ppu.ppu_cycles = 0;
|
||||
ppu.ppu_prev_cycles = 0;
|
||||
ppu.display_disable = true;
|
||||
ppu.display_brightness = 15;
|
||||
|
||||
//ppu.interlace/ppu.interlace_frame initialized in timing/timing.cpp
|
||||
ppu.overscan = false;
|
||||
ppu.visible_scanlines = 224;
|
||||
ppu.sprite_halve = false;
|
||||
ppu.hline_pos = 0;
|
||||
ppu.vline_pos = 0;
|
||||
ppu.irq_triggered = false;
|
||||
ppu.virq_triggered = false;
|
||||
ppu.hirq_triggered = false;
|
||||
ppu.vram_write_pos = 0;
|
||||
ppu.vram_read_buffer = 0;
|
||||
ppu.vram_write_buffer = 0;
|
||||
ppu.cgram_write_pos = 0;
|
||||
ppu.wram_write_pos = 0;
|
||||
ppu.vram_remap_mode = 0;
|
||||
ppu.vram_inc_size = 2;
|
||||
ppu.vram_inc_reg = 0;
|
||||
ppu.oam_write_pos = 0;
|
||||
ppu.oam_tiledata_loc = 0;
|
||||
|
||||
ppu.bg_enabled[OAM] = false;
|
||||
ppu.ss_bg_enabled[OAM] = false;
|
||||
ppu.mosaic_size = 0;
|
||||
ppu.mosaic_enabled[BG4] = false;
|
||||
ppu.mosaic_enabled[BG3] = false;
|
||||
ppu.mosaic_enabled[BG2] = false;
|
||||
ppu.mosaic_enabled[BG1] = false;
|
||||
ppu.bg_windowing_enabled[OAM] = false;
|
||||
ppu.ss_bg_windowing_enabled[OAM] = false;
|
||||
ppu.bg_window1_enabled[OAM] = false;
|
||||
ppu.bg_window2_enabled[OAM] = false;
|
||||
ppu.bg_window1_clipmode[OAM] = false;
|
||||
ppu.bg_window2_clipmode[OAM] = false;
|
||||
ppu.bg_window_mask[OAM] = false;
|
||||
|
||||
for(i=0;i<4;i++) {
|
||||
ppu.bg_enabled[i] = false;
|
||||
ppu.ss_bg_enabled[i] = false;
|
||||
ppu.bg_window1_enabled[i] = false;
|
||||
ppu.bg_window2_enabled[i] = false;
|
||||
ppu.bg_windowing_enabled[i] = false;
|
||||
ppu.ss_bg_windowing_enabled[i] = false;
|
||||
ppu.bg_window1_clipmode[i] = 0;
|
||||
ppu.bg_window2_clipmode[i] = 0;
|
||||
ppu.bg_window_mask[i] = 0;
|
||||
ppu.bg_tilemap_loc[i] = 0;
|
||||
ppu.bg_tiledata_loc[i] = 0;
|
||||
ppu.bg_hscroll_pos[i] = 0;
|
||||
ppu.bg_vscroll_pos[i] = 0;
|
||||
}
|
||||
ppu.bg_priority_mode = 0;
|
||||
ppu.oam_base_size = 0;
|
||||
ppu.oam_name_sel = 0;
|
||||
ppu.bg_mode = 0;
|
||||
|
||||
ppu.mul_a = 0;
|
||||
ppu.mul_b = 0;
|
||||
ppu.div_a = 0;
|
||||
ppu.div_b = 0;
|
||||
ppu.r_4214 = 0;
|
||||
ppu.r_4216 = 0;
|
||||
ppu.r_2134 = 0;
|
||||
|
||||
ppu.window1_left = 0;
|
||||
ppu.window1_right = 0;
|
||||
ppu.window2_left = 0;
|
||||
ppu.window2_right = 0;
|
||||
|
||||
ppu.color_window1_enabled = 0;
|
||||
ppu.color_window2_enabled = 0;
|
||||
ppu.color_window1_clipmode = 0;
|
||||
ppu.color_window2_clipmode = 0;
|
||||
ppu.color_window_mask = 0;
|
||||
ppu.color_mask = 0;
|
||||
ppu.ss_color_mask = 0;
|
||||
ppu.addsub_mode = 0;
|
||||
ppu.color_mode = 0;
|
||||
ppu.color_halve = 0;
|
||||
for(i=0;i<6;i++) {
|
||||
ppu.bg_color_enabled[i] = false;
|
||||
}
|
||||
ppu.color_r = 0;
|
||||
ppu.color_g = 0;
|
||||
ppu.color_b = 0;
|
||||
|
||||
ppu.active_hdma_channels = 0;
|
||||
for(i=0;i<8;i++) {
|
||||
memset(&dma_channel[i], 0, sizeof(dmachannel));
|
||||
ppu.hdma_completed[i] = false;
|
||||
ppu.hdma_scanlines_remaining[i] = 0;
|
||||
ppu.hdma_index_pointer[i] = 0;
|
||||
}
|
||||
hdma_initialize();
|
||||
|
||||
ppu.vcounter_enabled = false;
|
||||
ppu.hcounter_enabled = false;
|
||||
ppu.hirq_pos = 0;
|
||||
ppu.virq_pos = 0;
|
||||
|
||||
ppu.auto_joypad_read = false;
|
||||
ppu.joypad_strobe_value = 0;
|
||||
|
||||
ppu.latch_toggle = 0;
|
||||
ppu.latch_vpos = 0;
|
||||
ppu.latch_hpos = 0;
|
||||
|
||||
ppu.m7a = ppu.m7b =
|
||||
ppu.m7c = ppu.m7d =
|
||||
ppu.m7x = ppu.m7y = 0;
|
||||
|
||||
ppu.m7hofs = ppu.m7vofs = 0x0000;
|
||||
|
||||
ppu.mode7_repeat = 0;
|
||||
ppu.mode7_extbg = false;
|
||||
ppu.mode7_hflip = false;
|
||||
ppu.mode7_vflip = false;
|
||||
|
||||
ppu.io4201 = 0xff;
|
||||
ppu.counter_latched = false;
|
||||
|
||||
memset(ppu.mmio_mem_43xx, 0, 0x80);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
$2130 : fixed color / screen add sub
|
||||
abcd--ef
|
||||
|
||||
ab: main
|
||||
cd: subscreen
|
||||
00: all the time
|
||||
01: inside window only
|
||||
10: outside window only
|
||||
11: all the time
|
||||
e: 0 = enable addsub for fixed color
|
||||
1 = enable addsub for sub screen
|
||||
f: color / chardata = direct color
|
||||
(mode3, 4, 7 only)
|
||||
*/
|
||||
void mmio_w2130(byte value) {
|
||||
ppu.color_mask = (value >> 6) & 3;
|
||||
ppu.ss_color_mask = (value >> 4) & 3;
|
||||
ppu.addsub_mode = (value & 0x02)?1:0;
|
||||
}
|
||||
|
||||
/*
|
||||
$2131 : addsub designation
|
||||
mrgsdcba
|
||||
|
||||
m: 0 = enable add color data mode
|
||||
1 = enable sub color data mode
|
||||
r: 1/2 color mode
|
||||
g: Backarea enable
|
||||
s: OAM enable
|
||||
d: BG4 enable
|
||||
c: BG3 enable
|
||||
b: BG2 enable
|
||||
a: BG1 enable
|
||||
*/
|
||||
void mmio_w2131(byte value) {
|
||||
ppu.color_mode = (value & 0x80)?COLORMODE_SUB:COLORMODE_ADD;
|
||||
ppu.color_halve = (value & 0x40)?1:0;
|
||||
ppu.bg_color_enabled[BACK] = (value & 0x20)?true:false;
|
||||
ppu.bg_color_enabled[OAM] = (value & 0x10)?true:false;
|
||||
ppu.bg_color_enabled[BG4] = (value & 0x08)?true:false;
|
||||
ppu.bg_color_enabled[BG3] = (value & 0x04)?true:false;
|
||||
ppu.bg_color_enabled[BG2] = (value & 0x02)?true:false;
|
||||
ppu.bg_color_enabled[BG1] = (value & 0x01)?true:false;
|
||||
}
|
||||
|
||||
/*
|
||||
$2132 : addsub settings
|
||||
bgrddddd
|
||||
|
||||
b: affect blue
|
||||
g: affect green
|
||||
r: affect red
|
||||
d: color constant
|
||||
*/
|
||||
void mmio_w2132(byte value) {
|
||||
if(value & 0x80)ppu.color_b = (value & 0x1f);
|
||||
if(value & 0x40)ppu.color_g = (value & 0x1f);
|
||||
if(value & 0x20)ppu.color_r = (value & 0x1f);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
#define BLENDTYPE_BACK 0
|
||||
#define BLENDTYPE_MAIN 1
|
||||
#define BLENDTYPE_SUB 2
|
||||
#define BLENDTYPE_COMBINE 3
|
||||
|
||||
#define COLORDEPTH_4 0
|
||||
#define COLORDEPTH_16 1
|
||||
#define COLORDEPTH_256 2
|
||||
|
||||
struct {
|
||||
byte color_main, color_sub;
|
||||
byte src_main, src_sub;
|
||||
byte blend_type;
|
||||
}ppu_pixel_cache[512];
|
||||
|
||||
byte ppu_layer_cache[512 * 12];
|
||||
|
||||
#define TILE_2BIT 0
|
||||
#define TILE_4BIT 1
|
||||
#define TILE_8BIT 2
|
||||
|
||||
byte *ppu_bg_tiledata[3];
|
||||
byte *ppu_bg_tiledata_state[3];
|
||||
|
||||
//this should be reset once every scanline
|
||||
void ppu_clear_pixel_cache(void) {
|
||||
int i;
|
||||
for(i=0;i<render.snes_width;i++) {
|
||||
ppu_pixel_cache[i].color_main =
|
||||
ppu_pixel_cache[i].color_sub = 0;
|
||||
ppu_pixel_cache[i].src_main =
|
||||
ppu_pixel_cache[i].src_sub = BACK;
|
||||
ppu_pixel_cache[i].blend_type = BLENDTYPE_BACK;
|
||||
}
|
||||
}
|
||||
|
||||
//this should be reset once every scanline
|
||||
void ppu_clear_layer_cache(void) {
|
||||
memset(&ppu_layer_cache, 0, render.snes_width * 12);
|
||||
}
|
||||
|
||||
void ppu_init_tiledata_cache(void) {
|
||||
ppu_bg_tiledata[TILE_2BIT] = (byte*)malloc(262144);
|
||||
ppu_bg_tiledata[TILE_4BIT] = (byte*)malloc(131072);
|
||||
ppu_bg_tiledata[TILE_8BIT] = (byte*)malloc( 65536);
|
||||
ppu_bg_tiledata_state[TILE_2BIT] = (byte*)malloc( 4096);
|
||||
ppu_bg_tiledata_state[TILE_4BIT] = (byte*)malloc( 2048);
|
||||
ppu_bg_tiledata_state[TILE_8BIT] = (byte*)malloc( 1024);
|
||||
}
|
||||
|
||||
void ppu_clear_tiledata_cache(void) {
|
||||
memset(ppu_bg_tiledata[TILE_2BIT], 0, 262144);
|
||||
memset(ppu_bg_tiledata[TILE_4BIT], 0, 131072);
|
||||
memset(ppu_bg_tiledata[TILE_4BIT], 0, 65536);
|
||||
memset(ppu_bg_tiledata_state[TILE_2BIT], 0, 4096);
|
||||
memset(ppu_bg_tiledata_state[TILE_4BIT], 0, 2048);
|
||||
memset(ppu_bg_tiledata_state[TILE_8BIT], 0, 1024);
|
||||
}
|
||||
@@ -1,392 +0,0 @@
|
||||
#define DMATRANSFER_CPUTOMMIO 0
|
||||
#define DMATRANSFER_MMIOTOCPU 1
|
||||
|
||||
#define DMAINDEX_ABSOLUTE 0
|
||||
#define DMAINDEX_INDIRECT 1
|
||||
|
||||
#define DMAWRITE_INC 0
|
||||
#define DMAWRITE_DEC 1
|
||||
|
||||
#define HDMAMODE_NORMAL 0
|
||||
#define HDMAMODE_CONTINUOUS 1
|
||||
|
||||
typedef struct {
|
||||
bool active;
|
||||
byte transfer_mode;
|
||||
bool indirect;
|
||||
bool fixed_address;
|
||||
int write_dir;
|
||||
byte transfer_type;
|
||||
byte dest_addr;
|
||||
ulong src_addr;
|
||||
word transfer_size;
|
||||
byte indirect_bank;
|
||||
byte hdma_mode;
|
||||
word hdma_indirect_pointer;
|
||||
|
||||
//hdma specific
|
||||
bool first_line;
|
||||
bool repeat;
|
||||
bool completed;
|
||||
byte line_counter;
|
||||
ulong address, iaddress;
|
||||
|
||||
word r43x8;
|
||||
}dmachannel;
|
||||
|
||||
dmachannel dma_channel[8];
|
||||
|
||||
/*
|
||||
$43x0 : DMA control
|
||||
da-ifttt
|
||||
|
||||
d: (dma only)
|
||||
0=read from cpu mem, write to $21xx
|
||||
1=read from $21xx, write to cpu mem
|
||||
a: (hdma only)
|
||||
0=absolute addressing
|
||||
1=indirect addressing
|
||||
i: 0=increment address, 1=decrement address
|
||||
f: 1=fixed address, 0=inc/dec address
|
||||
t: transfer type
|
||||
*/
|
||||
void mmio_w43x0(byte c, byte value) {
|
||||
dma_channel[c].transfer_mode = (value & 0x80)?DMATRANSFER_MMIOTOCPU:DMATRANSFER_CPUTOMMIO;
|
||||
dma_channel[c].indirect = (value & 0x40)?true:false;
|
||||
dma_channel[c].write_dir = (value & 0x10)?-1:1;
|
||||
dma_channel[c].fixed_address = (value & 0x08)?true:false;
|
||||
dma_channel[c].transfer_type = (value & 0x07);
|
||||
}
|
||||
|
||||
/*
|
||||
$43x1 : DMA destination address
|
||||
bbbbbbbb
|
||||
|
||||
b: $2100 | b = destination register - limited to $21xx regs only
|
||||
*/
|
||||
void mmio_w43x1(byte c, byte value) {
|
||||
dma_channel[c].dest_addr = value;
|
||||
}
|
||||
|
||||
/*
|
||||
$43x2-$43x4 : 24-bit DMA source address
|
||||
|
||||
after a dma transfer, this address must be incremented
|
||||
*/
|
||||
void mmio_w43x2(byte c, byte value) {
|
||||
dma_channel[c].src_addr = (dma_channel[c].src_addr & 0xffff00) | value;
|
||||
}
|
||||
|
||||
void mmio_w43x3(byte c, byte value) {
|
||||
dma_channel[c].src_addr = (dma_channel[c].src_addr & 0xff00ff) | (value << 8);
|
||||
}
|
||||
|
||||
void mmio_w43x4(byte c, byte value) {
|
||||
dma_channel[c].src_addr = (dma_channel[c].src_addr & 0x00ffff) | (value << 16);
|
||||
}
|
||||
|
||||
/*
|
||||
$43x5/$43x6 : DMA transfer size
|
||||
*/
|
||||
void mmio_w43x5(byte c, byte value) {
|
||||
dma_channel[c].transfer_size = (dma_channel[c].transfer_size & 0xff00) | value;
|
||||
}
|
||||
|
||||
void mmio_w43x6(byte c, byte value) {
|
||||
dma_channel[c].transfer_size = (dma_channel[c].transfer_size & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
/*
|
||||
$43x7 : HDMA indirect bank address
|
||||
*/
|
||||
void mmio_w43x7(byte c, byte value) {
|
||||
dma_channel[c].indirect_bank = value;
|
||||
}
|
||||
|
||||
void dma_mmio_write(byte reg, byte value) {
|
||||
mmio_write(0x2100 | reg, value);
|
||||
}
|
||||
|
||||
byte dma_mmio_read(byte reg) {
|
||||
return mmio_read(0x2100 | reg);
|
||||
}
|
||||
|
||||
word dma_cputommio(byte c, byte a) {
|
||||
byte x;
|
||||
x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[c].src_addr);
|
||||
dma_mmio_write(dma_channel[c].dest_addr + a, x);
|
||||
if(dma_channel[c].fixed_address == false) {
|
||||
dma_channel[c].src_addr = (dma_channel[c].src_addr & 0xff0000) | ((dma_channel[c].src_addr + dma_channel[c].write_dir) & 0xffff);
|
||||
}
|
||||
snes_time->add_cpu_cycles(1, 8);
|
||||
return --dma_channel[c].transfer_size;
|
||||
}
|
||||
|
||||
word dma_mmiotocpu(byte c, byte a) {
|
||||
byte x;
|
||||
x = dma_mmio_read(dma_channel[c].dest_addr + a);
|
||||
gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[c].src_addr, x);
|
||||
if(dma_channel[c].fixed_address == false) {
|
||||
dma_channel[c].src_addr = (dma_channel[c].src_addr & 0xff0000) | ((dma_channel[c].src_addr + dma_channel[c].write_dir) & 0xffff);
|
||||
}
|
||||
snes_time->add_cpu_cycles(1, 8);
|
||||
return --dma_channel[c].transfer_size;
|
||||
}
|
||||
|
||||
void dma_transfer_type0(byte c) {
|
||||
if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
|
||||
if(dma_cputommio(c, 0) == 0)return;
|
||||
} else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
|
||||
if(dma_mmiotocpu(c, 0) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void dma_transfer_type1(byte c) {
|
||||
if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
|
||||
if(dma_cputommio(c, 0) == 0)return;
|
||||
if(dma_cputommio(c, 1) == 0)return;
|
||||
} else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
|
||||
if(dma_mmiotocpu(c, 0) == 0)return;
|
||||
if(dma_mmiotocpu(c, 1) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void dma_transfer_type2(byte c) {
|
||||
if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
|
||||
if(dma_cputommio(c, 0) == 0)return;
|
||||
} else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
|
||||
if(dma_mmiotocpu(c, 0) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void dma_transfer_type3(byte c) {
|
||||
if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
|
||||
if(dma_cputommio(c, 0) == 0)return;
|
||||
if(dma_cputommio(c, 0) == 0)return;
|
||||
if(dma_cputommio(c, 1) == 0)return;
|
||||
if(dma_cputommio(c, 1) == 0)return;
|
||||
} else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
|
||||
if(dma_mmiotocpu(c, 0) == 0)return;
|
||||
if(dma_mmiotocpu(c, 0) == 0)return;
|
||||
if(dma_mmiotocpu(c, 1) == 0)return;
|
||||
if(dma_mmiotocpu(c, 1) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void dma_transfer_type4(byte c) {
|
||||
if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
|
||||
if(dma_cputommio(c, 0) == 0)return;
|
||||
if(dma_cputommio(c, 1) == 0)return;
|
||||
if(dma_cputommio(c, 2) == 0)return;
|
||||
if(dma_cputommio(c, 3) == 0)return;
|
||||
} else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
|
||||
if(dma_mmiotocpu(c, 0) == 0)return;
|
||||
if(dma_mmiotocpu(c, 1) == 0)return;
|
||||
if(dma_mmiotocpu(c, 2) == 0)return;
|
||||
if(dma_mmiotocpu(c, 3) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void dma_transfer_type5(byte c) {
|
||||
if(dma_channel[c].transfer_mode == DMATRANSFER_CPUTOMMIO) {
|
||||
if(dma_cputommio(c, 0) == 0)return;
|
||||
if(dma_cputommio(c, 1) == 0)return;
|
||||
if(dma_cputommio(c, 0) == 0)return;
|
||||
if(dma_cputommio(c, 1) == 0)return;
|
||||
} else if(dma_channel[c].transfer_mode == DMATRANSFER_MMIOTOCPU) {
|
||||
if(dma_mmiotocpu(c, 0) == 0)return;
|
||||
if(dma_mmiotocpu(c, 1) == 0)return;
|
||||
if(dma_mmiotocpu(c, 0) == 0)return;
|
||||
if(dma_mmiotocpu(c, 1) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This function is called consecutively until all DMA transfers are completed.
|
||||
Rather than transfer all of the DMA data immediately, control is returned to
|
||||
the main loop after each DMA transfer so that the APU, PPU, renderer, etc.
|
||||
can keep in sync. Otherwise, a transfer of 65536 bytes could prevent the renderer
|
||||
from drawing all scanlines, for example.
|
||||
Each DMA channel must be completed incrementally. The entire transfer from channel 0
|
||||
must complete before any data is transferred for channel 1, etc.
|
||||
*/
|
||||
void ppu_update_dma(void) {
|
||||
int i, z;
|
||||
z = 0;
|
||||
for(i=0;i<8;i++) {
|
||||
if(dma_channel[i].active == false)continue;
|
||||
switch(dma_channel[i].transfer_type) {
|
||||
case 0:dma_transfer_type0(i);break;
|
||||
case 1:dma_transfer_type1(i);break;
|
||||
case 2:dma_transfer_type2(i);break;
|
||||
case 3:dma_transfer_type3(i);break;
|
||||
case 4:dma_transfer_type4(i);break;
|
||||
case 5:dma_transfer_type5(i);break;
|
||||
case 6:dma_transfer_type2(i);break; //6 is the same as 2
|
||||
case 7:dma_transfer_type3(i);break; //7 is the same as 3
|
||||
}
|
||||
if(dma_channel[i].transfer_size == 0) {
|
||||
dma_channel[i].active = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
gx816->cpu_state = CPUSTATE_RUN;
|
||||
}
|
||||
|
||||
/*
|
||||
$420b : DMA enable
|
||||
$420c : HDMA enable
|
||||
|
||||
Each bit corresponds to the respecting DMA channel (7,6,5,4,3,2,1,0)
|
||||
Setting a bit in this register will perform the DMA transfer. Multiple
|
||||
transfers can be done at once. Requires one cycle per byte transferred.
|
||||
*/
|
||||
void mmio_w420b(byte value) {
|
||||
int i;
|
||||
ppu.active_hdma_channels &= ~value;
|
||||
for(i=0;i<8;i++) {
|
||||
if(value & (1 << i)) {
|
||||
dma_channel[i].active = true;
|
||||
gx816->cpu_state = CPUSTATE_DMA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mmio_w420c(byte value) {
|
||||
ppu.active_hdma_channels = value;
|
||||
}
|
||||
|
||||
byte hdma_transfer_lentbl[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
|
||||
|
||||
void hdma_write_byte(byte i, byte l, byte x) {
|
||||
switch(dma_channel[i].transfer_type) {
|
||||
case 0:
|
||||
dma_mmio_write(dma_channel[i].dest_addr, x);
|
||||
break;
|
||||
case 1:
|
||||
dma_mmio_write(dma_channel[i].dest_addr + l, x);
|
||||
break;
|
||||
case 2:
|
||||
dma_mmio_write(dma_channel[i].dest_addr, x);
|
||||
break;
|
||||
case 3:
|
||||
dma_mmio_write(dma_channel[i].dest_addr + (l >> 1), x);
|
||||
break;
|
||||
case 4:
|
||||
dma_mmio_write(dma_channel[i].dest_addr + l, x);
|
||||
break;
|
||||
case 5:
|
||||
dma_mmio_write(dma_channel[i].dest_addr + (l & 1), x);
|
||||
break;
|
||||
case 6:
|
||||
dma_mmio_write(dma_channel[i].dest_addr, x);
|
||||
break;
|
||||
case 7:
|
||||
dma_mmio_write(dma_channel[i].dest_addr + (l >> 1), x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void hdma_update(void) {
|
||||
int i, l;
|
||||
byte x, channels_active = 0;
|
||||
if(snes_time->vscan_pos > ppu.visible_scanlines)return;
|
||||
for(i=0;i<8;i++) {
|
||||
if(dma_channel[i].completed == true)continue;
|
||||
snes_time->add_cpu_cycles(1, 8);
|
||||
channels_active++;
|
||||
if(dma_channel[i].line_counter == 0) {
|
||||
dma_channel[i].line_counter = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[i].address++);
|
||||
dma_channel[i].r43x8 = dma_channel[i].address;
|
||||
if(dma_channel[i].line_counter == 0) {
|
||||
dma_channel[i].completed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(dma_channel[i].line_counter > 0x80) {
|
||||
dma_channel[i].repeat = true;
|
||||
dma_channel[i].line_counter -= 0x80;
|
||||
} else {
|
||||
dma_channel[i].repeat = false;
|
||||
}
|
||||
|
||||
dma_channel[i].first_line = true;
|
||||
if(dma_channel[i].indirect == false) {
|
||||
dma_channel[i].iaddress = dma_channel[i].address;
|
||||
} else {
|
||||
dma_channel[i].iaddress = gx816->mem_read(MEMMODE_NONE, MEMSIZE_WORD, dma_channel[i].address);
|
||||
dma_channel[i].iaddress |= (dma_channel[i].indirect_bank << 16);
|
||||
dma_channel[i].address += 2;
|
||||
snes_time->add_cpu_cycles(1, 16);
|
||||
}
|
||||
}
|
||||
|
||||
dma_channel[i].line_counter--;
|
||||
if(dma_channel[i].first_line == false && dma_channel[i].repeat == false)continue;
|
||||
dma_channel[i].first_line = false;
|
||||
|
||||
if(dma_channel[i].indirect == false) {
|
||||
dma_channel[i].iaddress = dma_channel[i].address;
|
||||
}
|
||||
|
||||
for(l=0;l<hdma_transfer_lentbl[dma_channel[i].transfer_type];l++) {
|
||||
x = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, dma_channel[i].iaddress++);
|
||||
if(dma_channel[i].indirect == false) {
|
||||
dma_channel[i].address++;
|
||||
}
|
||||
hdma_write_byte(i, l, x);
|
||||
snes_time->add_cpu_cycles(1, 8);
|
||||
}
|
||||
}
|
||||
if(channels_active != 0) {
|
||||
snes_time->add_cpu_cycles(1, 18);
|
||||
}
|
||||
}
|
||||
|
||||
void hdma_initialize(void) {
|
||||
int i, active_channels = 0;
|
||||
for(i=0;i<8;i++) {
|
||||
if((ppu.active_hdma_channels & (1 << i)) == 0) {
|
||||
dma_channel[i].completed = true;
|
||||
continue;
|
||||
}
|
||||
active_channels++;
|
||||
dma_channel[i].first_line = true;
|
||||
dma_channel[i].repeat = false;
|
||||
dma_channel[i].line_counter = 0;
|
||||
dma_channel[i].address = dma_channel[i].src_addr;
|
||||
dma_channel[i].completed = false;
|
||||
if(dma_channel[i].indirect == false) {
|
||||
snes_time->add_cpu_cycles(1, 8);
|
||||
} else {
|
||||
snes_time->add_cpu_cycles(1, 24);
|
||||
}
|
||||
}
|
||||
if(active_channels != 0) {
|
||||
snes_time->add_cpu_cycles(1, 18);
|
||||
}
|
||||
}
|
||||
|
||||
byte mmio_r43x8(byte c) {
|
||||
return (dma_channel[c].r43x8);
|
||||
}
|
||||
|
||||
byte mmio_r43x9(byte c) {
|
||||
return (dma_channel[c].r43x8 >> 8);
|
||||
}
|
||||
|
||||
byte mmio_r43xa(byte c) {
|
||||
return (dma_channel[c].line_counter + 1);
|
||||
}
|
||||
|
||||
void mmio_w43x8(byte c, byte x) {
|
||||
dma_channel[c].address = (dma_channel[c].address & 0xff00) | x;
|
||||
}
|
||||
|
||||
void mmio_w43x9(byte c, byte x) {
|
||||
dma_channel[c].address = (dma_channel[c].address & 0x00ff) | (x << 8);
|
||||
}
|
||||
|
||||
void mmio_w43xa(byte c, byte x) {
|
||||
dma_channel[c].line_counter = x;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
joypad_state joypad1;
|
||||
|
||||
/*
|
||||
*1 - The joypad contains a small bit shifter that has 16 bits.
|
||||
Reading from 4016 reads one bit from this buffer, then moves
|
||||
the buffer left one, and adds a '1' to the rightmost bit.
|
||||
Writing a one to $4016 will fill the buffer with the current
|
||||
joypad button states, and lock the bit shifter at position
|
||||
zero. All reads will be the first buffer state, or 'B'.
|
||||
A zero must be written back to $4016 to unlock the buffer,
|
||||
so that reads will increment the bit shifting position.
|
||||
*/
|
||||
byte mmio_r4016(void) {
|
||||
byte r = 0;
|
||||
if(ppu.joypad_strobe_value == 1) { //*1
|
||||
r |= joypad1.b;
|
||||
} else {
|
||||
if (joypad1.read_pos == 0)r |= joypad1.b;
|
||||
else if(joypad1.read_pos == 1)r |= joypad1.y;
|
||||
else if(joypad1.read_pos == 2)r |= joypad1.select;
|
||||
else if(joypad1.read_pos == 3)r |= joypad1.start;
|
||||
else if(joypad1.read_pos == 4)r |= joypad1.up;
|
||||
else if(joypad1.read_pos == 5)r |= joypad1.down;
|
||||
else if(joypad1.read_pos == 6)r |= joypad1.left;
|
||||
else if(joypad1.read_pos == 7)r |= joypad1.right;
|
||||
else if(joypad1.read_pos == 8)r |= joypad1.a;
|
||||
else if(joypad1.read_pos == 9)r |= joypad1.x;
|
||||
else if(joypad1.read_pos == 10)r |= joypad1.l;
|
||||
else if(joypad1.read_pos == 11)r |= joypad1.r;
|
||||
else if(joypad1.read_pos == 16)r |= 1; //joypad connected bit (1=yes, 0=no)
|
||||
else r |= 1; //after 16th read, all subsequent reads return 1
|
||||
if(++joypad1.read_pos > 17)joypad1.read_pos = 17;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
byte mmio_r4218(void) {
|
||||
byte r;
|
||||
if(ppu.auto_joypad_read == false) return 0x00; //cannot read joypad if auto joypad read not enabled
|
||||
if(ppu.vline_pos >= 225 && ppu.vline_pos <= 227)return 0x00; //cannot read joypad while SNES is polling the joypad data
|
||||
r = joypad1.a << 7 |
|
||||
joypad1.x << 6 |
|
||||
joypad1.l << 5 |
|
||||
joypad1.r << 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
byte mmio_r4219(void) {
|
||||
byte r;
|
||||
if(ppu.auto_joypad_read == false) return 0x00; //cannot read joypad if auto joypad read not enabled
|
||||
if(ppu.vline_pos >= 225 && ppu.vline_pos <= 227)return 0x00; //cannot read joypad while SNES is polling the joypad data
|
||||
r = joypad1.b << 7 |
|
||||
joypad1.y << 6 |
|
||||
joypad1.select << 5 |
|
||||
joypad1.start << 4 |
|
||||
joypad1.up << 3 |
|
||||
joypad1.down << 2 |
|
||||
joypad1.left << 1 |
|
||||
joypad1.right;
|
||||
return r;
|
||||
}
|
||||
|
||||
void mmio_w4016(byte value) {
|
||||
ppu.joypad_strobe_value = value;
|
||||
if(value == 1)UpdateJoypad();
|
||||
if(value == 0)joypad1.read_pos = 0;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
$21c2/$21c3
|
||||
|
||||
These seem to be version information registers... I don't know
|
||||
what their purpose is, but I do know that the SNES demo rom
|
||||
expects these values to be returned in order to proceed through
|
||||
the character test.
|
||||
*/
|
||||
byte mmio_r21c2(void) {
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
byte mmio_r21c3(void) {
|
||||
return 0x00;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
$211a : mode7 settings register
|
||||
ab0000yx
|
||||
|
||||
ab:
|
||||
00 = use screen repetition if outside screen area
|
||||
01 = ???
|
||||
10 = use character 0x00 repetition if outside screen area
|
||||
11 = use back color if outside screen area
|
||||
y: vertical screen flip
|
||||
x: horizontal screen flip
|
||||
*/
|
||||
void mmio_w211a(byte value) {
|
||||
ppu.mode7_repeat = (value >> 6) & 3;
|
||||
ppu.mode7_vflip = (value & 0x02)?true:false;
|
||||
ppu.mode7_hflip = (value & 0x01)?true:false;
|
||||
}
|
||||
|
||||
/*
|
||||
$211b : m7a / 16-bit source operand for signed multiplication
|
||||
*/
|
||||
void mmio_w211b(byte value) {
|
||||
ppu.m7a = (value << 8) | (ppu.m7a >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
$211c : m7b / 8-bit source operand for signed multiplication
|
||||
*/
|
||||
void mmio_w211c(byte value) {
|
||||
ppu.m7b = (value << 8) | (ppu.m7b >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
$211d : m7c
|
||||
*/
|
||||
void mmio_w211d(byte value) {
|
||||
ppu.m7c = (value << 8) | (ppu.m7c >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
$211e : m7d
|
||||
*/
|
||||
void mmio_w211e(byte value) {
|
||||
ppu.m7d = (value << 8) | (ppu.m7d >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
$211f : m7x
|
||||
*/
|
||||
void mmio_w211f(byte value) {
|
||||
ppu.m7x = (value << 8) | (ppu.m7x >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
$2120 : m7y
|
||||
*/
|
||||
void mmio_w2120(byte value) {
|
||||
ppu.m7y = (value << 8) | (ppu.m7y >> 8);
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
byte mmio_r2134(void) {
|
||||
ulong r = ((signed short)ppu.m7a * (signed char)(ppu.m7b >> 8));
|
||||
return (r);
|
||||
}
|
||||
|
||||
byte mmio_r2135(void) {
|
||||
ulong r = ((signed short)ppu.m7a * (signed char)(ppu.m7b >> 8));
|
||||
return (r >> 8);
|
||||
}
|
||||
|
||||
byte mmio_r2136(void) {
|
||||
ulong r = ((signed short)ppu.m7a * (signed char)(ppu.m7b >> 8));
|
||||
return (r >> 16);
|
||||
}
|
||||
|
||||
void mmio_w4202(byte value) {
|
||||
ppu.mul_a = value;
|
||||
}
|
||||
|
||||
void mmio_w4203(byte value) {
|
||||
ppu.mul_b = value;
|
||||
ppu.r_4216 = ppu.mul_a * ppu.mul_b;
|
||||
}
|
||||
|
||||
void mmio_w4204(byte value) {
|
||||
ppu.div_a = (ppu.div_a & 0xff00) | value;
|
||||
}
|
||||
|
||||
void mmio_w4205(byte value) {
|
||||
ppu.div_a = (ppu.div_a & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
void mmio_w4206(byte value) {
|
||||
ppu.div_b = value;
|
||||
|
||||
ppu.r_4214 = (ppu.div_b)?ppu.div_a / ppu.div_b : 0;
|
||||
ppu.r_4216 = (ppu.div_b)?ppu.div_a % ppu.div_b : 0;
|
||||
}
|
||||
|
||||
byte mmio_r4214(void) {
|
||||
return ppu.r_4214;
|
||||
}
|
||||
|
||||
byte mmio_r4215(void) {
|
||||
return ppu.r_4214 >> 8;
|
||||
}
|
||||
|
||||
byte mmio_r4216(void) {
|
||||
return ppu.r_4216;
|
||||
}
|
||||
|
||||
byte mmio_r4217(void) {
|
||||
return ppu.r_4216 >> 8;
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
$2101 : OAM settings
|
||||
sssnnbbb
|
||||
|
||||
s: base sprite size
|
||||
small : large
|
||||
000: 8x8 : 16x16
|
||||
001: 8x8 : 32x32
|
||||
010: 8x8 : 64x64
|
||||
011: 16x16 : 32x32
|
||||
100: 16x16 : 64x64
|
||||
101: 32x32 : 64x64
|
||||
110: 16x32 : 32x64
|
||||
111: 16x32 : 32x32
|
||||
small/large is determined by oam size bit
|
||||
n: name selection (0-3)
|
||||
b: oam tiledata location (>>14) -- highest bit ignored
|
||||
*/
|
||||
void mmio_w2101(byte value) {
|
||||
ppu.oam_base_size = (value >> 5);
|
||||
ppu.oam_name_sel = (value >> 3) & 3;
|
||||
ppu.oam_tiledata_loc = (value & 3) << 14;
|
||||
}
|
||||
|
||||
/*
|
||||
$2102/$2103 : OAM access address
|
||||
$2102: llllllll
|
||||
$2103: ???????h
|
||||
|
||||
9-bit address, h = bit 8, l = bits 7-0
|
||||
*/
|
||||
byte ppu_oam_write_posl = 0x00, ppu_oam_write_posh = 0x00;
|
||||
|
||||
void mmio_w2102(byte value) {
|
||||
ppu_oam_write_posl = value;
|
||||
ppu.oam_write_pos = ((ppu_oam_write_posh << 8) | (ppu_oam_write_posl)) * 2;
|
||||
}
|
||||
|
||||
void mmio_w2103(byte value) {
|
||||
ppu_oam_write_posh = value & 0x01;
|
||||
ppu.oam_write_pos = ((ppu_oam_write_posh << 8) | (ppu_oam_write_posl)) * 2;
|
||||
}
|
||||
|
||||
byte ppu_oam_latch_data = 0;
|
||||
|
||||
/*
|
||||
$2104 : OAM write
|
||||
|
||||
write one byte to OAM data. even writes (bit 0 = 0) are cached
|
||||
to the OAM latch, and no data is transferred to OAM ram. odd writes
|
||||
(bit 0 = 1) write the latch value, and then the requested value (2 bytes)
|
||||
to oam data. writes to OAM address 0x0200 and above (priority / x bit 8 table)
|
||||
always write, but even writes still update the latch data.
|
||||
*/
|
||||
void mmio_w2104(byte value) {
|
||||
if(ppu.oam_write_pos >= 0x0200) {
|
||||
if((ppu.oam_write_pos & 1) == 0) {
|
||||
ppu_oam_latch_data = value;
|
||||
}
|
||||
oam_write(ppu.oam_write_pos, value);
|
||||
} else if((ppu.oam_write_pos & 1) == 0) {
|
||||
ppu_oam_latch_data = value;
|
||||
} else {
|
||||
oam_write((ppu.oam_write_pos & 0x03fe), ppu_oam_latch_data);
|
||||
oam_write((ppu.oam_write_pos & 0x03fe) + 1, value);
|
||||
}
|
||||
ppu.oam_write_pos++;
|
||||
ppu.oam_write_pos &= 0x03ff;
|
||||
}
|
||||
|
||||
/*
|
||||
$2138 : OAM read
|
||||
|
||||
read one byte from OAM data. if address is even (bit 0 = 0),
|
||||
latch data is updated.
|
||||
*/
|
||||
byte mmio_r2138(void) {
|
||||
byte r;
|
||||
r = oam_read(ppu.oam_write_pos);
|
||||
if((ppu.oam_write_pos & 1) == 0) {
|
||||
ppu_oam_latch_data = r;
|
||||
}
|
||||
ppu.oam_write_pos++;
|
||||
ppu.oam_write_pos &= 0x03ff;
|
||||
return r;
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
$2121 : cgram write position
|
||||
|
||||
takes an 8-bit value that indexes into color palette cgram data.
|
||||
multiply value by 2 to get actual offset into ppu.cgram
|
||||
*/
|
||||
void mmio_w2121(byte value) {
|
||||
ppu.cgram_write_pos = value << 1;
|
||||
}
|
||||
|
||||
/*
|
||||
$2122 : cgram write
|
||||
|
||||
writes to cgram using cgram_write_pos * 2 as an index
|
||||
*/
|
||||
void mmio_w2122(byte value) {
|
||||
ppu.cgram[ppu.cgram_write_pos] = value;
|
||||
|
||||
debug_test_bp(BPSRC_CGRAM, BP_WRITE, ppu.cgram_write_pos, value);
|
||||
|
||||
ppu.cgram_write_pos++;
|
||||
ppu.cgram_write_pos &= 0x01ff;
|
||||
}
|
||||
|
||||
/*
|
||||
$213b : cgram read
|
||||
|
||||
read from cgram using cgram_write_pos * 2 as an index
|
||||
*/
|
||||
byte mmio_r213b(void) {
|
||||
byte r;
|
||||
r = ppu.cgram[ppu.cgram_write_pos];
|
||||
|
||||
debug_test_bp(BPSRC_CGRAM, BP_READ, ppu.cgram_write_pos, r);
|
||||
|
||||
ppu.cgram_write_pos++;
|
||||
ppu.cgram_write_pos &= 0x01ff;
|
||||
return r;
|
||||
}
|
||||
@@ -1,901 +0,0 @@
|
||||
byte ppu_addsub_adjust_buffer_full[96] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31
|
||||
};
|
||||
|
||||
byte ppu_addsub_adjust_buffer_half[96] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
|
||||
};
|
||||
|
||||
#define ppu_pal_pixel(__i) \
|
||||
(*((word*)ppu.cgram + __i))
|
||||
|
||||
word ppu_addsub_pixels(byte x, byte cdest_index, byte cdest_bg, byte csrc_index, byte csrc_bg) {
|
||||
int r, g, b;
|
||||
word cdest = ppu_pal_pixel(cdest_index);
|
||||
word csrc = ppu_pal_pixel(csrc_index);
|
||||
word res;
|
||||
//oam palettes 0-3 are not affected by color add/sub
|
||||
if(cdest_bg == OAM) {
|
||||
if(cdest_index < 192) {
|
||||
return cdest;
|
||||
}
|
||||
}
|
||||
switch(ppu.color_mode) {
|
||||
case COLORMODE_ADD:
|
||||
if(ppu.bg_color_enabled[cdest_bg] == true && ppu.color_halve == 1) {
|
||||
r = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1;
|
||||
g = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1;
|
||||
b = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1;
|
||||
} else {
|
||||
r = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) ));
|
||||
g = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) ));
|
||||
b = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) ));
|
||||
}
|
||||
break;
|
||||
case COLORMODE_SUB:
|
||||
if(ppu.bg_color_enabled[cdest_bg] == true && ppu.color_halve == 1) {
|
||||
r = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1;
|
||||
g = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1;
|
||||
b = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1;
|
||||
} else {
|
||||
r = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest ) & 31) - ((csrc ) & 31) ));
|
||||
g = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) - ((csrc >> 5) & 31) ));
|
||||
b = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) - ((csrc >> 10) & 31) ));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ((r) | (g << 5) | (b << 10));
|
||||
}
|
||||
|
||||
word ppu_addsub_pixel(byte x, byte cdest_index, byte cdest_bg) {
|
||||
int r, g, b;
|
||||
word cdest = ppu_pal_pixel(cdest_index);
|
||||
word csrc = (ppu.color_r) | (ppu.color_g << 5) | (ppu.color_b << 10);
|
||||
word res;
|
||||
//only oam palettes 4-7 are affected by color add/sub
|
||||
if(cdest_bg == OAM) {
|
||||
if(cdest_index < 192) {
|
||||
return cdest;
|
||||
}
|
||||
}
|
||||
switch(ppu.color_mode) {
|
||||
case COLORMODE_ADD:
|
||||
if(ppu.bg_color_enabled[cdest_bg] == true && ppu.color_halve == 1 && ppu.addsub_mode == 0) {
|
||||
r = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1;
|
||||
g = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1;
|
||||
b = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1;
|
||||
} else {
|
||||
r = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) ));
|
||||
g = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) ));
|
||||
b = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) ));
|
||||
}
|
||||
break;
|
||||
case COLORMODE_SUB:
|
||||
if(ppu.bg_color_enabled[cdest_bg] == true && ppu.color_halve == 1 && ppu.addsub_mode == 0) {
|
||||
r = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1;
|
||||
g = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1;
|
||||
b = *(ppu_addsub_adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1;
|
||||
} else {
|
||||
r = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest ) & 31) - ((csrc ) & 31) ));
|
||||
g = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) - ((csrc >> 5) & 31) ));
|
||||
b = *(ppu_addsub_adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) - ((csrc >> 10) & 31) ));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ((r) | (g << 5) | (b << 10));
|
||||
}
|
||||
|
||||
#define ppu_render_bg_tile_line_4(__m) \
|
||||
col = 0; \
|
||||
if(d0 & __m)col += 1; \
|
||||
if(d1 & __m)col += 2; \
|
||||
*dest++ = col
|
||||
#define ppu_render_bg_tile_line_16(__m) \
|
||||
col = 0; \
|
||||
if(d0 & __m)col += 1; \
|
||||
if(d1 & __m)col += 2; \
|
||||
if(d2 & __m)col += 4; \
|
||||
if(d3 & __m)col += 8; \
|
||||
*dest++ = col
|
||||
#define ppu_render_bg_tile_line_256(__m) \
|
||||
col = 0; \
|
||||
if(d0 & __m)col += 1; \
|
||||
if(d1 & __m)col += 2; \
|
||||
if(d2 & __m)col += 4; \
|
||||
if(d3 & __m)col += 8; \
|
||||
if(d4 & __m)col += 16; \
|
||||
if(d5 & __m)col += 32; \
|
||||
if(d6 & __m)col += 64; \
|
||||
if(d7 & __m)col += 128; \
|
||||
*dest++ = col
|
||||
|
||||
void ppu_render_bg_tile(byte color_depth, byte bg, word tile_num) {
|
||||
byte mask, d0, d1, d2, d3, d4, d5, d6, d7, col;
|
||||
int x, y;
|
||||
ulong pos;
|
||||
byte *dest;
|
||||
switch(color_depth) {
|
||||
case COLORDEPTH_4:
|
||||
dest = (byte*)ppu_bg_tiledata[TILE_2BIT] + tile_num * 64;
|
||||
pos = tile_num * 16;
|
||||
y = 8;
|
||||
while(y--) {
|
||||
d0 = ppu.vram[pos ];
|
||||
d1 = ppu.vram[pos + 1];
|
||||
ppu_render_bg_tile_line_4(0x80);
|
||||
ppu_render_bg_tile_line_4(0x40);
|
||||
ppu_render_bg_tile_line_4(0x20);
|
||||
ppu_render_bg_tile_line_4(0x10);
|
||||
ppu_render_bg_tile_line_4(0x08);
|
||||
ppu_render_bg_tile_line_4(0x04);
|
||||
ppu_render_bg_tile_line_4(0x02);
|
||||
ppu_render_bg_tile_line_4(0x01);
|
||||
pos += 2;
|
||||
}
|
||||
ppu_bg_tiledata_state[TILE_2BIT][tile_num] = 0;
|
||||
break;
|
||||
case COLORDEPTH_16:
|
||||
dest = (byte*)ppu_bg_tiledata[TILE_4BIT] + tile_num * 64;
|
||||
pos = tile_num * 32;
|
||||
y = 8;
|
||||
while(y--) {
|
||||
d0 = ppu.vram[pos ];
|
||||
d1 = ppu.vram[pos + 1];
|
||||
d2 = ppu.vram[pos + 16];
|
||||
d3 = ppu.vram[pos + 17];
|
||||
ppu_render_bg_tile_line_16(0x80);
|
||||
ppu_render_bg_tile_line_16(0x40);
|
||||
ppu_render_bg_tile_line_16(0x20);
|
||||
ppu_render_bg_tile_line_16(0x10);
|
||||
ppu_render_bg_tile_line_16(0x08);
|
||||
ppu_render_bg_tile_line_16(0x04);
|
||||
ppu_render_bg_tile_line_16(0x02);
|
||||
ppu_render_bg_tile_line_16(0x01);
|
||||
pos += 2;
|
||||
}
|
||||
ppu_bg_tiledata_state[TILE_4BIT][tile_num] = 0;
|
||||
break;
|
||||
case COLORDEPTH_256:
|
||||
dest = (byte*)ppu_bg_tiledata[TILE_8BIT] + tile_num * 64;
|
||||
pos = tile_num * 64;
|
||||
y = 8;
|
||||
while(y--) {
|
||||
d0 = ppu.vram[pos ];
|
||||
d1 = ppu.vram[pos + 1];
|
||||
d2 = ppu.vram[pos + 16];
|
||||
d3 = ppu.vram[pos + 17];
|
||||
d4 = ppu.vram[pos + 32];
|
||||
d5 = ppu.vram[pos + 33];
|
||||
d6 = ppu.vram[pos + 48];
|
||||
d7 = ppu.vram[pos + 49];
|
||||
ppu_render_bg_tile_line_256(0x80);
|
||||
ppu_render_bg_tile_line_256(0x40);
|
||||
ppu_render_bg_tile_line_256(0x20);
|
||||
ppu_render_bg_tile_line_256(0x10);
|
||||
ppu_render_bg_tile_line_256(0x08);
|
||||
ppu_render_bg_tile_line_256(0x04);
|
||||
ppu_render_bg_tile_line_256(0x02);
|
||||
ppu_render_bg_tile_line_256(0x01);
|
||||
pos += 2;
|
||||
}
|
||||
ppu_bg_tiledata_state[TILE_8BIT][tile_num] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define PPU_MAIN 0
|
||||
#define PPU_SUB 1
|
||||
|
||||
bool windows_not_obstructing(byte layer, byte bg, word x);
|
||||
bool color_windows_not_obstructing(word x, byte color_mask_type);
|
||||
|
||||
void ppu_render_line_to_screen(void) {
|
||||
int x, x1;
|
||||
word *ptr, *ptri, *light_table, *light_tablei;
|
||||
word c, cx, cy;
|
||||
word screen_width = render.snes_width;
|
||||
|
||||
if(ppu.interlace == false) {
|
||||
ptr = (word*)ppu.screen + ((ppu.vline_pos << 1) ) * 512;
|
||||
ptri = (word*)ppu.screen + ((ppu.vline_pos << 1) + 1) * 512;
|
||||
} else {
|
||||
ptr = (word*)ppu.screen + ((ppu.vline_pos << 1) + ppu.interlace_frame) * 512;
|
||||
}
|
||||
light_table = (word*)ppu.light_table + (ppu.display_brightness * 65536);
|
||||
|
||||
for(x=x1=0;x<screen_width;x++) {
|
||||
switch(ppu_pixel_cache[x].blend_type) {
|
||||
case BLENDTYPE_BACK:
|
||||
if(color_windows_not_obstructing(x, PPU_MAIN) == true) {
|
||||
cx = 0x0000;
|
||||
} else if(ppu.bg_color_enabled[BACK] == true && color_windows_not_obstructing(x, PPU_SUB) == false) {
|
||||
cx = ppu_addsub_pixel(x, 0, BACK);
|
||||
} else {
|
||||
cx = ppu_pal_pixel(0);
|
||||
}
|
||||
break;
|
||||
case BLENDTYPE_MAIN:
|
||||
if(ppu.bg_color_enabled[ppu_pixel_cache[x].src_main] == true && color_windows_not_obstructing(x, PPU_MAIN) == true) {
|
||||
cx = 0x0000;
|
||||
} else if(ppu.bg_color_enabled[ppu_pixel_cache[x].src_main] == true && color_windows_not_obstructing(x, PPU_SUB) == false) {
|
||||
cx = ppu_addsub_pixel(x, ppu_pixel_cache[x].color_main, ppu_pixel_cache[x].src_main);
|
||||
} else {
|
||||
cx = ppu_pal_pixel(ppu_pixel_cache[x].color_main);
|
||||
}
|
||||
break;
|
||||
case BLENDTYPE_SUB:
|
||||
if(ppu.bg_color_enabled[BACK] && color_windows_not_obstructing(x, PPU_SUB) == false) {
|
||||
cx = ppu_addsub_pixels(x, 0, BACK, ppu_pixel_cache[x].color_sub, ppu_pixel_cache[x].src_sub);
|
||||
} else {
|
||||
cx = ppu_pal_pixel(ppu_pixel_cache[x].color_sub);
|
||||
}
|
||||
break;
|
||||
case BLENDTYPE_COMBINE:
|
||||
if(color_windows_not_obstructing(x, PPU_SUB) == false) {
|
||||
if(ppu_pixel_cache[x].src_sub == BACK) {
|
||||
cx = ppu_addsub_pixels(x, ppu_pixel_cache[x].color_main, ppu_pixel_cache[x].src_main, 0, BACK);
|
||||
} else {
|
||||
cx = ppu_addsub_pixels(x, ppu_pixel_cache[x].color_main, ppu_pixel_cache[x].src_main,
|
||||
ppu_pixel_cache[x].color_sub, ppu_pixel_cache[x].src_sub);
|
||||
}
|
||||
} else {
|
||||
cx = ppu_pal_pixel(ppu_pixel_cache[x].color_main);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(ppu.interlace == false) {
|
||||
*(ptr + (x1 )) = *(light_table + cx);
|
||||
*(ptri + (x1++)) = *(light_table + cx);
|
||||
if(screen_width != 256)continue;
|
||||
*(ptr + (x1 )) = *(light_table + cx);
|
||||
*(ptri + (x1++)) = *(light_table + cx);
|
||||
} else {
|
||||
*(ptr + (x1++)) = *(light_table + cx);
|
||||
if(screen_width != 256)continue;
|
||||
*(ptr + (x1++)) = *(light_table + cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ppu_set_pixel(byte bg, word x, byte pal_index) {
|
||||
if(ppu.bg_enabled[bg] == true && ppu.ss_bg_enabled[bg] == true) {
|
||||
if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
|
||||
ppu_pixel_cache[x].blend_type = BLENDTYPE_MAIN;
|
||||
ppu_pixel_cache[x].src_main = bg;
|
||||
ppu_pixel_cache[x].color_main = pal_index;
|
||||
if(color_windows_not_obstructing(x, PPU_SUB) == false) {
|
||||
ppu_pixel_cache[x].src_sub = bg;
|
||||
ppu_pixel_cache[x].color_sub = pal_index;
|
||||
}
|
||||
} else if(ppu.bg_enabled[bg] == true && bg == OAM && pal_index < 192) {
|
||||
if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
|
||||
ppu_pixel_cache[x].blend_type = BLENDTYPE_MAIN;
|
||||
ppu_pixel_cache[x].src_main = bg;
|
||||
ppu_pixel_cache[x].color_main = pal_index;
|
||||
} else if(ppu.bg_enabled[bg] == true) {
|
||||
if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
|
||||
if(ppu.bg_color_enabled[bg] == true && ppu_pixel_cache[x].src_sub != BACK) {
|
||||
ppu_pixel_cache[x].blend_type = BLENDTYPE_COMBINE;
|
||||
} else {
|
||||
ppu_pixel_cache[x].blend_type = BLENDTYPE_MAIN;
|
||||
}
|
||||
ppu_pixel_cache[x].src_main = bg;
|
||||
ppu_pixel_cache[x].color_main = pal_index;
|
||||
} else if(ppu.ss_bg_enabled[bg] == true) {
|
||||
if(windows_not_obstructing(PPU_SUB, bg, x) == false)return;
|
||||
ppu_pixel_cache[x].src_sub = bg;
|
||||
ppu_pixel_cache[x].color_sub = pal_index;
|
||||
if(ppu_pixel_cache[x].blend_type == BLENDTYPE_BACK) {
|
||||
ppu_pixel_cache[x].blend_type = BLENDTYPE_SUB;
|
||||
} else if(ppu_pixel_cache[x].blend_type == BLENDTYPE_MAIN) {
|
||||
if(ppu_pixel_cache[x].src_main != OAM || (ppu_pixel_cache[x].src_main == OAM && ppu_pixel_cache[x].color_main >= 192)) {
|
||||
if(ppu.bg_color_enabled[ppu_pixel_cache[x].src_main] == true) {
|
||||
ppu_pixel_cache[x].blend_type = BLENDTYPE_COMBINE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ppu_set_layer_pixels(byte layer_count, byte *layer_bg_lookup) {
|
||||
int layer, x = 0, x1;
|
||||
byte pal;
|
||||
do {
|
||||
layer = 0;
|
||||
x1 = x * 12;
|
||||
do {
|
||||
pal = ppu_layer_cache[x1 + layer];
|
||||
if(pal) {
|
||||
ppu_set_pixel(layer_bg_lookup[layer], x, pal);
|
||||
}
|
||||
layer++;
|
||||
} while(layer < layer_count);
|
||||
x++;
|
||||
} while(x < render.snes_width);
|
||||
}
|
||||
|
||||
#define ppu_set_layer_pixel(__x, __c) ppu_layer_cache[(__x) * 12 + layer_pos] = __c
|
||||
|
||||
struct {
|
||||
byte num;
|
||||
byte width, height;
|
||||
word x, y;
|
||||
word character;
|
||||
byte v_flip, h_flip;
|
||||
byte palette;
|
||||
byte priority;
|
||||
}current_sprite;
|
||||
|
||||
void ppu_set_sprite_attributes(byte sprite_num) {
|
||||
ulong t;
|
||||
byte size, b;
|
||||
word x;
|
||||
t = *((ulong*)ppu.oam + sprite_num);
|
||||
b = ppu.oam[512 + (sprite_num >> 2)];
|
||||
|
||||
switch(sprite_num & 3) {
|
||||
case 0: size = (b & 0x02)?1:0; x = (b & 0x01)?0x100:0; break;
|
||||
case 1: size = (b & 0x08)?1:0; x = (b & 0x04)?0x100:0; break;
|
||||
case 2: size = (b & 0x20)?1:0; x = (b & 0x10)?0x100:0; break;
|
||||
case 3: size = (b & 0x80)?1:0; x = (b & 0x40)?0x100:0; break;
|
||||
}
|
||||
|
||||
current_sprite.num = sprite_num;
|
||||
current_sprite.priority = (t >> 28) & 3;
|
||||
current_sprite.x = x | (t & 0xff);
|
||||
current_sprite.y = ((t >> 8) + 1) & 0xff;
|
||||
current_sprite.v_flip = (t & 0x80000000)?1:0;
|
||||
current_sprite.h_flip = (t & 0x40000000)?1:0;
|
||||
current_sprite.palette = (t >> 25) & 7;
|
||||
current_sprite.character = (t >> 16) & 0x01ff;
|
||||
|
||||
//size: 0 = small, 1 = large
|
||||
switch(ppu.oam_base_size) {
|
||||
case 0:
|
||||
if(!size) { current_sprite.width = 8; current_sprite.height = 8; }
|
||||
else { current_sprite.width = 16; current_sprite.height = 16; }
|
||||
break;
|
||||
case 1:
|
||||
if(!size) { current_sprite.width = 8; current_sprite.height = 8; }
|
||||
else { current_sprite.width = 32; current_sprite.height = 32; }
|
||||
break;
|
||||
case 2:
|
||||
if(!size) { current_sprite.width = 8; current_sprite.height = 8; }
|
||||
else { current_sprite.width = 64; current_sprite.height = 64; }
|
||||
break;
|
||||
case 3:
|
||||
if(!size) { current_sprite.width = 16; current_sprite.height = 16; }
|
||||
else { current_sprite.width = 32; current_sprite.height = 32; }
|
||||
break;
|
||||
case 4:
|
||||
if(!size) { current_sprite.width = 16; current_sprite.height = 16; }
|
||||
else { current_sprite.width = 64; current_sprite.height = 64; }
|
||||
break;
|
||||
case 5:
|
||||
if(!size) { current_sprite.width = 32; current_sprite.height = 32; }
|
||||
else { current_sprite.width = 64; current_sprite.height = 64; }
|
||||
break;
|
||||
case 6:
|
||||
if(!size) { current_sprite.width = 16; current_sprite.height = 32; }
|
||||
else { current_sprite.width = 32; current_sprite.height = 64; }
|
||||
break;
|
||||
case 7:
|
||||
if(!size) { current_sprite.width = 16; current_sprite.height = 32; }
|
||||
else { current_sprite.width = 32; current_sprite.height = 32; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool windows_not_obstructing(byte layer, byte bg, word x) {
|
||||
byte w1_mask, w2_mask; //1 = masked, 0 = not masked
|
||||
word window1_left, window1_right, window2_left, window2_right;
|
||||
if(layer == PPU_MAIN) {
|
||||
if(ppu.bg_windowing_enabled[bg] == false)return true;
|
||||
} else if(layer == PPU_SUB) {
|
||||
if(ppu.ss_bg_windowing_enabled[bg] == false)return true;
|
||||
}
|
||||
|
||||
window1_left = ppu.window1_left;
|
||||
window1_right = ppu.window1_right;
|
||||
window2_left = ppu.window2_left;
|
||||
window2_right = ppu.window2_right;
|
||||
|
||||
if(ppu.bg_mode == 5 || ppu.bg_mode == 6) {
|
||||
window1_left <<= 1;
|
||||
window1_right <<= 1;
|
||||
window2_left <<= 1;
|
||||
window2_right <<= 1;
|
||||
}
|
||||
|
||||
if(ppu.bg_window1_enabled[bg] == true && ppu.bg_window2_enabled[bg] == false) {
|
||||
if(ppu.bg_window1_clipmode[bg] == CLIPMODE_IN) {
|
||||
if(x >= window1_left && x <= window1_right)return false;
|
||||
return true;
|
||||
} else {
|
||||
if(x < window1_left || x > window1_right)return false;
|
||||
return true;
|
||||
}
|
||||
} else if(ppu.bg_window2_enabled[bg] == true && ppu.bg_window1_enabled[bg] == false) {
|
||||
if(ppu.bg_window2_clipmode[bg] == CLIPMODE_IN) {
|
||||
if(x >= window2_left && x <= window2_right)return false;
|
||||
return true;
|
||||
} else {
|
||||
if(x < window2_left || x > window2_right)return false;
|
||||
return true;
|
||||
}
|
||||
} else if(ppu.bg_window1_enabled[bg] == true && ppu.bg_window2_enabled[bg] == true) {
|
||||
if(ppu.bg_window1_clipmode[bg] == CLIPMODE_IN) {
|
||||
if(x >= window1_left && x <= window1_right)w1_mask = 1;
|
||||
else w1_mask = 0;
|
||||
} else {
|
||||
if(x < window1_left || x > window1_right)w1_mask = 1;
|
||||
else w1_mask = 0;
|
||||
}
|
||||
|
||||
if(ppu.bg_window2_clipmode[bg] == CLIPMODE_IN) {
|
||||
if(x >= window2_left && x <= window2_right)w2_mask = 1;
|
||||
else w2_mask = 0;
|
||||
} else {
|
||||
if(x < window2_left || x > window2_right)w2_mask = 1;
|
||||
else w2_mask = 0;
|
||||
}
|
||||
|
||||
switch(ppu.bg_window_mask[bg]) {
|
||||
case WINDOWMASK_OR:
|
||||
if((w1_mask | w2_mask) == 1)return false;
|
||||
return true;
|
||||
case WINDOWMASK_AND:
|
||||
if((w1_mask & w2_mask) == 1)return false;
|
||||
return true;
|
||||
case WINDOWMASK_XOR:
|
||||
if((w1_mask ^ w2_mask) == 1)return false;
|
||||
return true;
|
||||
case WINDOWMASK_XNOR:
|
||||
if((w1_mask ^ w2_mask) == 0)return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool color_windows_not_obstructing(word x, byte color_mask_type) {
|
||||
byte w1_mask, w2_mask; //1 = masked, 0 = not masked
|
||||
byte color_mask;
|
||||
bool r;
|
||||
word window1_left, window1_right, window2_left, window2_right;
|
||||
if(color_mask_type == PPU_MAIN)color_mask = ppu.color_mask;
|
||||
else color_mask = ppu.ss_color_mask;
|
||||
|
||||
if(color_mask == 0)return false;
|
||||
if(color_mask == 3)return true;
|
||||
|
||||
window1_left = ppu.window1_left;
|
||||
window1_right = ppu.window1_right;
|
||||
window2_left = ppu.window2_left;
|
||||
window2_right = ppu.window2_right;
|
||||
|
||||
if(ppu.bg_mode == 5 || ppu.bg_mode == 6) {
|
||||
window1_left <<= 1;
|
||||
window1_right <<= 1;
|
||||
window2_left <<= 1;
|
||||
window2_right <<= 1;
|
||||
}
|
||||
|
||||
if(ppu.color_window1_enabled == false && ppu.color_window2_enabled == false) {
|
||||
r = true;
|
||||
} else if(ppu.color_window1_enabled == true && ppu.color_window2_enabled == false) {
|
||||
if(ppu.color_window1_clipmode == CLIPMODE_IN) {
|
||||
if(x >= window1_left && x <= window1_right)r = false;
|
||||
else r = true;
|
||||
} else {
|
||||
if(x < window1_left || x > window1_right)r = false;
|
||||
else r = true;
|
||||
}
|
||||
} else if(ppu.color_window1_enabled == false && ppu.color_window2_enabled == true) {
|
||||
if(ppu.color_window2_clipmode == CLIPMODE_IN) {
|
||||
if(x >= window2_left && x <= window2_right)r = false;
|
||||
else r = true;
|
||||
} else {
|
||||
if(x < window2_left || x > window2_right)r = false;
|
||||
else r = true;
|
||||
}
|
||||
} else if(ppu.color_window1_enabled == true && ppu.color_window2_enabled == true) {
|
||||
if(ppu.color_window1_clipmode == CLIPMODE_IN) {
|
||||
if(x >= window1_left && x <= window1_right)w1_mask = 1;
|
||||
else w1_mask = 0;
|
||||
} else {
|
||||
if(x < window1_left || x > window1_right)w1_mask = 1;
|
||||
else w1_mask = 0;
|
||||
}
|
||||
|
||||
if(ppu.color_window2_clipmode == CLIPMODE_IN) {
|
||||
if(x >= window2_left && x <= window2_right)w2_mask = 1;
|
||||
else w2_mask = 0;
|
||||
} else {
|
||||
if(x < window2_left || x > window2_right)w2_mask = 1;
|
||||
else w2_mask = 0;
|
||||
}
|
||||
|
||||
switch(ppu.color_window_mask) {
|
||||
case WINDOWMASK_OR:
|
||||
if((w1_mask | w2_mask) == 1)r = false;
|
||||
else r = true;
|
||||
break;
|
||||
case WINDOWMASK_AND:
|
||||
if((w1_mask & w2_mask) == 1)r = false;
|
||||
else r = true;
|
||||
break;
|
||||
case WINDOWMASK_XOR:
|
||||
if((w1_mask ^ w2_mask) == 1)r = false;
|
||||
else r = true;
|
||||
break;
|
||||
case WINDOWMASK_XNOR:
|
||||
if((w1_mask ^ w2_mask) == 0)r = false;
|
||||
else r = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(color_mask == 2) {
|
||||
r = (r == true)?false:true;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
*1 - When bit 8 of a sprite's character number is set, such that character data
|
||||
is read from the upper half (upper 8k) of sprite vram, bits 4-3 of $2101
|
||||
are added to bits 14-13 of the tiledata location. The address wraps around
|
||||
the 64k bank. Why this happens, or what it's for, I have no idea.
|
||||
*2 - The sprite tiledata is stored with 16 tiles making up the first row, followed
|
||||
by 16 tiles making up the second row, and so on. Therefore, to get the
|
||||
correct y tile, y / 8 * 1 row (16 tiles) must be used.
|
||||
*/
|
||||
|
||||
#define OAM_PRI_NONE 4
|
||||
byte ppu_oam_line_pal[512], ppu_oam_line_pri[512];
|
||||
|
||||
void ppu_render_oam_sprite(void) {
|
||||
word pos, col, chr, tiledata_inc;
|
||||
byte d0, d1, d2, d3, pal_index;
|
||||
int x, y, z, x1, mx, mask, p;
|
||||
int tile_width;
|
||||
if(ppu.bg_enabled[OAM] == false && ppu.ss_bg_enabled[OAM] == false)return;
|
||||
|
||||
tile_width = current_sprite.width >> SH_8; //e.x. 16x16 sprite = 2x2 tiles
|
||||
|
||||
if(ppu.interlace == true && (ppu.bg_mode == 5 || ppu.bg_mode == 6)) {
|
||||
y = (ppu.vline_pos << SH_2) + ppu.interlace_frame;
|
||||
} else {
|
||||
y = ppu.vline_pos;
|
||||
}
|
||||
|
||||
x = current_sprite.x;
|
||||
if(render.snes_width == 512) {
|
||||
x <<= SH_2;
|
||||
}
|
||||
|
||||
if(current_sprite.v_flip) {
|
||||
y = ((current_sprite.height - 1) - (ppu.vline_pos - current_sprite.y));
|
||||
} else {
|
||||
y = (ppu.vline_pos - current_sprite.y);
|
||||
}
|
||||
y &= 255;
|
||||
if(ppu.sprite_halve == true) {
|
||||
y <<= 1;
|
||||
y += ppu.interlace_frame;
|
||||
}
|
||||
|
||||
chr = current_sprite.character;
|
||||
tiledata_inc = (chr & 0x100)?(ppu.oam_name_sel << 13):0; //*1
|
||||
chr += (y >> SH_8) << SH_16; //*2
|
||||
pal_index = (current_sprite.palette << SH_16);
|
||||
for(x1=0;x1<tile_width;x1++) {
|
||||
if(current_sprite.h_flip)mx = (tile_width - 1) - x1;
|
||||
else mx = x1;
|
||||
pos = ppu.oam_tiledata_loc + ((chr + mx) << SH_32) + ((y & 7) << SH_2) + tiledata_inc;
|
||||
d0 = ppu.vram[pos ];
|
||||
d1 = ppu.vram[pos + 1];
|
||||
d2 = ppu.vram[pos + 16];
|
||||
d3 = ppu.vram[pos + 17];
|
||||
for(z=0;z<8;z++) {
|
||||
if(current_sprite.h_flip) {
|
||||
mask = 0x01 << z;
|
||||
} else {
|
||||
mask = 0x80 >> z;
|
||||
}
|
||||
x &= 511;
|
||||
if(x < render.snes_width) {
|
||||
col = 0;
|
||||
if(d0 & mask)col += 1;
|
||||
if(d1 & mask)col += 2;
|
||||
if(d2 & mask)col += 4;
|
||||
if(d3 & mask)col += 8;
|
||||
if(col) {
|
||||
col += pal_index;
|
||||
col += 128;
|
||||
if(ppu_oam_line_pri[x] == OAM_PRI_NONE) {
|
||||
ppu_oam_line_pal[x] = col;
|
||||
ppu_oam_line_pri[x] = current_sprite.priority;
|
||||
}
|
||||
if(render.snes_width == 512) {
|
||||
if(ppu_oam_line_pri[x + 1] == OAM_PRI_NONE) {
|
||||
ppu_oam_line_pal[x + 1] = col;
|
||||
ppu_oam_line_pri[x + 1] = current_sprite.priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
if(render.snes_width == 512) {
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
void ppu_render_line_oam(byte layer_pos_pri0, byte layer_pos_pri1, byte layer_pos_pri2, byte layer_pos_pri3) {
|
||||
int i, s;
|
||||
byte layer_pos;
|
||||
if(ppu.bg_enabled[OAM] != true && ppu.ss_bg_enabled[OAM] != true)return;
|
||||
|
||||
memset(ppu_oam_line_pri, OAM_PRI_NONE, 512);
|
||||
for(s=0;s<128;s++) {
|
||||
ppu_set_sprite_attributes(s);
|
||||
if(ppu.sprite_halve == false) {
|
||||
if(ppu.vline_pos >= current_sprite.y && ppu.vline_pos < (current_sprite.y + current_sprite.height)) {
|
||||
ppu_render_oam_sprite();
|
||||
} else if((current_sprite.y + current_sprite.height) >= 256 && ppu.vline_pos < ((current_sprite.y + current_sprite.height) & 255)) {
|
||||
ppu_render_oam_sprite();
|
||||
}
|
||||
} else {
|
||||
if(ppu.vline_pos >= current_sprite.y && ppu.vline_pos < (current_sprite.y + (current_sprite.height >> 1))) {
|
||||
ppu_render_oam_sprite();
|
||||
} else if((current_sprite.y + current_sprite.height) >= 256 && ppu.vline_pos < ((current_sprite.y + (current_sprite.height >> 1)) & 255)) {
|
||||
ppu_render_oam_sprite();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;i<render.snes_width;i++) {
|
||||
if(ppu_oam_line_pri[i] != OAM_PRI_NONE) {
|
||||
switch(ppu_oam_line_pri[i]) {
|
||||
case 0:layer_pos = layer_pos_pri0;break;
|
||||
case 1:layer_pos = layer_pos_pri1;break;
|
||||
case 2:layer_pos = layer_pos_pri2;break;
|
||||
case 3:layer_pos = layer_pos_pri3;break;
|
||||
}
|
||||
ppu_set_layer_pixel(i, ppu_oam_line_pal[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*1 - map_index
|
||||
The tilemap can be 32x32, 64x32, 32x64, or 64x64. Rather than expanding the width
|
||||
and height of the tilemap, the game instead stores duplicate tilemaps immediately
|
||||
following the previous ones. For example, if you were in 64x64 mode, there would
|
||||
be four tilemaps. Each tilemap would be 2048 bytes in size
|
||||
(32 tiles * 32 tiles * 2 bytes/tile), the first tilemap would make the top left
|
||||
corner, the second the top right, the third the bottom left, and the fourth, the
|
||||
bottom right. Because x / y are divided by the tile size, the tile size setting
|
||||
(8x8 or 16x16) does not affect the result.
|
||||
*2 - pos = ppu.bg_tilemap_loc[bg] + map_index + ((y1 / tile_size) & 31) * 64 + ( ((x / tile_size) & 31) * 2);
|
||||
Format: tilemap start location +
|
||||
map index (either map 0 or map 1; see *1) +
|
||||
((y tile #) mapped to tilemap boundary) * # of bytes per tilemap line +
|
||||
(((x tile #) mapped to tilemap boundary) * 2 (# of bytes per tilemap entry));
|
||||
*/
|
||||
|
||||
void ppu_render_line_bg(byte layer_pos_pri0, byte layer_pos_pri1, byte color_depth, byte bg) {
|
||||
int x, y, z, x1, y1;
|
||||
int mirror_x, mirror_y, p;
|
||||
int screen_x, screen_y;
|
||||
int bg_x, bg_y;
|
||||
int xpos, ypos, mosaic_x, mosaic_y;
|
||||
word t, base_xpos, base_pos, pos, ppos = 0;
|
||||
word col;
|
||||
byte *src, *bg_tiledata, *bg_tiledata_state, *tile_ptr;
|
||||
byte tiledata_size;
|
||||
byte tile_size, tile_width, tile_height, tile_x;
|
||||
byte mask, pal_index, pal_size;
|
||||
word tile_num, screen_width, screen_height, screen_width_mask, screen_height_mask, map_index;
|
||||
word *mosaic_table;
|
||||
byte layer_pos;
|
||||
word opt_valid_bit, voffset, hoffset, vscroll, hscroll;
|
||||
if(ppu.bg_enabled[bg] == false && ppu.ss_bg_enabled[bg] == false)return;
|
||||
|
||||
if (bg == BG1)opt_valid_bit = 0x2000;
|
||||
else if(bg == BG2)opt_valid_bit = 0x4000;
|
||||
else opt_valid_bit = 0x0000;
|
||||
|
||||
switch(color_depth) {
|
||||
case COLORDEPTH_4:
|
||||
pal_size = 4;
|
||||
tiledata_size = SH_16;
|
||||
break;
|
||||
case COLORDEPTH_16:
|
||||
pal_size = 16;
|
||||
tiledata_size = SH_32;
|
||||
break;
|
||||
case COLORDEPTH_256:
|
||||
pal_size = 256;
|
||||
tiledata_size = SH_64;
|
||||
break;
|
||||
}
|
||||
bg_tiledata = (byte*)ppu_bg_tiledata[color_depth];
|
||||
bg_tiledata_state = (byte*)ppu_bg_tiledata_state[color_depth];
|
||||
|
||||
screen_width = render.snes_width;
|
||||
screen_height = render.snes_width; //this is correct -- ppu tilemap is based around 256x256, etc.
|
||||
tile_size = (ppu.bg_tile_size[bg])?SH_16:SH_8;
|
||||
tile_width = tile_size;
|
||||
tile_height = tile_size;
|
||||
|
||||
if(ppu.interlace == true && (ppu.bg_mode == 5 || ppu.bg_mode == 6)) {
|
||||
screen_y = (ppu.vline_pos << SH_2) + ppu.interlace_frame;
|
||||
} else {
|
||||
screen_y = ppu.vline_pos;
|
||||
}
|
||||
|
||||
//Modes 5 and 6 seem to force 16-width tiles due to having twice the resolution.
|
||||
//The tile size attribute in $2105 has no effect on tile width.
|
||||
if(ppu.bg_mode == 5 || ppu.bg_mode == 6) {
|
||||
tile_width = SH_16;
|
||||
}
|
||||
|
||||
if(tile_size == SH_16) {
|
||||
screen_width <<= SH_2;
|
||||
screen_height <<= SH_2;
|
||||
}
|
||||
|
||||
if(ppu.bg_tilemap_size[bg] & 0x01)screen_width <<= SH_2;
|
||||
if(ppu.bg_tilemap_size[bg] & 0x02)screen_height <<= SH_2;
|
||||
|
||||
screen_width_mask = screen_width - 1;
|
||||
screen_height_mask = screen_height - 1;
|
||||
|
||||
if(render.snes_width == 512) {
|
||||
hscroll = (ppu.bg_hscroll_pos[bg] << SH_2) & screen_width_mask;
|
||||
} else {
|
||||
hscroll = ppu.bg_hscroll_pos[bg] & screen_width_mask;
|
||||
}
|
||||
bg_x = hscroll;
|
||||
|
||||
if(render.snes_height == 448) {
|
||||
vscroll = (ppu.bg_vscroll_pos[bg] << SH_2) & screen_height_mask;
|
||||
} else {
|
||||
vscroll = ppu.bg_vscroll_pos[bg] & screen_height_mask;
|
||||
}
|
||||
bg_y = (screen_y + vscroll) & screen_height_mask;
|
||||
|
||||
if(ppu.mosaic_enabled[bg] == true) {
|
||||
mosaic_table = (word*)ppu.mosaic_table[ppu.mosaic_size];
|
||||
} else {
|
||||
mosaic_table = (word*)ppu.mosaic_table[0];
|
||||
}
|
||||
mosaic_x = mosaic_table[bg_x];
|
||||
mosaic_y = mosaic_table[bg_y];
|
||||
|
||||
for(screen_x=0;screen_x<render.snes_width;screen_x++) {
|
||||
if(ppu.bg_mode == 2 || ppu.bg_mode == 4 || ppu.bg_mode == 6) {
|
||||
if(ppu.bg_mode == 6) {
|
||||
tile_x = (mosaic_table[screen_x + (hscroll & 15)] >> SH_16);
|
||||
} else {
|
||||
tile_x = (mosaic_table[screen_x + (hscroll & 7)] >> SH_8);
|
||||
}
|
||||
hoffset = hscroll;
|
||||
voffset = vscroll;
|
||||
if(tile_x != 0) {
|
||||
tile_x = (tile_x - 1) & 31;
|
||||
if(ppu.bg_mode == 4) {
|
||||
pos = ppu.bg_tilemap_loc[BG3] + (tile_x << SH_2);
|
||||
t = *((word*)ppu.vram + (pos >> SH_2));
|
||||
if(t & opt_valid_bit) {
|
||||
if(!(t & 0x8000)) {
|
||||
hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask;
|
||||
} else {
|
||||
voffset = (t & 0x1fff) & screen_height_mask;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pos = ppu.bg_tilemap_loc[BG3] + (tile_x << SH_2);
|
||||
t = *((word*)ppu.vram + (pos >> SH_2));
|
||||
if(t & opt_valid_bit) {
|
||||
hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask;
|
||||
}
|
||||
pos = ppu.bg_tilemap_loc[BG3] + 64 + (tile_x << SH_2);
|
||||
t = *((word*)ppu.vram + (pos >> SH_2));
|
||||
if(t & opt_valid_bit) {
|
||||
voffset = (t & 0x1fff) & screen_height_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
mosaic_x = mosaic_table[(screen_x + hoffset) & screen_width_mask ];
|
||||
mosaic_y = mosaic_table[(screen_y + voffset) & screen_height_mask];
|
||||
}
|
||||
|
||||
switch(ppu.bg_tilemap_size[bg]) {
|
||||
case 0:
|
||||
map_index = 0;
|
||||
break;
|
||||
case 1:
|
||||
map_index = ((mosaic_x >> tile_size) >> SH_32) << SH_2048;
|
||||
break;
|
||||
case 2:
|
||||
map_index = ((mosaic_y >> tile_size) >> SH_32) << SH_2048;
|
||||
break;
|
||||
case 3:
|
||||
map_index = ((mosaic_x >> tile_size) >> SH_32) << SH_2048 |
|
||||
((mosaic_y >> tile_size) >> SH_32) << SH_4096;
|
||||
break;
|
||||
}
|
||||
|
||||
base_xpos = ((mosaic_x >> SH_8) & 31);
|
||||
base_pos = (((mosaic_y >> tile_height) & 31) << SH_32) + ((mosaic_x >> tile_width) & 31);
|
||||
pos = ppu.bg_tilemap_loc[bg] + map_index + (base_pos << SH_2);
|
||||
t = *((word*)ppu.vram + (pos >> SH_2));
|
||||
mirror_y = (t & 0x8000)?1:0;
|
||||
mirror_x = (t & 0x4000)?1:0;
|
||||
|
||||
if((t & 0x2000) == 0) {
|
||||
layer_pos = layer_pos_pri0;
|
||||
} else {
|
||||
layer_pos = layer_pos_pri1;
|
||||
}
|
||||
|
||||
tile_num = t & 0x03ff;
|
||||
if(tile_width == SH_16) {
|
||||
if(((mosaic_x & 15) >= 8 && !mirror_x) ||
|
||||
((mosaic_x & 15) < 8 && mirror_x))tile_num++;
|
||||
tile_num &= 0x03ff;
|
||||
}
|
||||
if(tile_height == SH_16) {
|
||||
if(((mosaic_y & 15) >= 8 && !mirror_y) ||
|
||||
((mosaic_y & 15) < 8 && mirror_y))tile_num += 16;
|
||||
tile_num &= 0x03ff;
|
||||
}
|
||||
tile_num += (ppu.bg_tiledata_loc[bg] >> tiledata_size);
|
||||
|
||||
if(bg_tiledata_state[tile_num] == 1) {
|
||||
ppu_render_bg_tile(color_depth, bg, tile_num);
|
||||
}
|
||||
|
||||
pal_index = ((t >> 10) & 7) * pal_size;
|
||||
|
||||
if(mirror_y) { ypos = (7 - (mosaic_y & 7)); }
|
||||
else { ypos = ( (mosaic_y & 7)); }
|
||||
|
||||
//loop while we are rendering from the same tile, as there's no need to do all of the above work
|
||||
//unless we have rendered all of the visible tile, taking mosaic into account.
|
||||
tile_ptr = (byte*)bg_tiledata + (tile_num << SH_64) + (ypos << SH_8);
|
||||
while(1) {
|
||||
if(mirror_x) { xpos = (7 - (mosaic_x & 7)); }
|
||||
else { xpos = ( (mosaic_x & 7)); }
|
||||
col = *(tile_ptr + xpos);
|
||||
if(col) {
|
||||
ppu_set_layer_pixel(screen_x, col + pal_index);
|
||||
}
|
||||
|
||||
bg_x++;
|
||||
bg_x &= screen_width_mask;
|
||||
mosaic_x = mosaic_table[bg_x];
|
||||
|
||||
if(base_xpos != ((mosaic_x >> SH_8) & 31))break;
|
||||
screen_x++;
|
||||
if(screen_x >= render.snes_width)break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "ppu_render_mode7.cpp"
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
The algorithm in this file was derived from the snes9x source code.
|
||||
The snes9x source code is not public domain. If you wish to use this
|
||||
code, you must abide by the terms of the snes9x license. If you do not
|
||||
wish to abide by the snes9x licensing terms, please define the precompiler
|
||||
variable PUBLIC_DOMAIN so that ppu_render_mode7f.cpp is used instead of
|
||||
this file. You must also remove this file from any work that you release
|
||||
that does not follow the snes9x license.
|
||||
See license.txt for more info on the license of this software and snes9x.
|
||||
*/
|
||||
|
||||
#define CLIP_10BIT_SIGNED(x) \
|
||||
((x) & ((1 << 10) - 1)) + (((((x) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3)
|
||||
|
||||
#define CAST_WORDTOINT(x) \
|
||||
(int)(((x & 0x8000)?(x | 0xffff0000):(x & 0x00007fff)))
|
||||
|
||||
void ppu_render_line_m7(byte layer_pos_bg1, byte layer_pos_bg2_pri0, byte layer_pos_bg2_pri1) {
|
||||
int x;
|
||||
int step_m7a, step_m7c, m7a, m7b, m7c, m7d;
|
||||
int hoffset, voffset;
|
||||
int centerx, centery;
|
||||
int xx, yy;
|
||||
int px, py;
|
||||
int tx, ty, tile, palette, priority;
|
||||
byte layer_pos;
|
||||
hoffset = (CAST_WORDTOINT(ppu.m7hofs) << 7) >> 7;
|
||||
voffset = (CAST_WORDTOINT(ppu.m7vofs) << 7) >> 7;
|
||||
|
||||
centerx = (CAST_WORDTOINT(ppu.m7x) << 7) >> 7;
|
||||
centery = (CAST_WORDTOINT(ppu.m7y) << 7) >> 7;
|
||||
|
||||
if(ppu.mode7_vflip == true) {
|
||||
yy = 223 - ppu.vline_pos;
|
||||
} else {
|
||||
yy = ppu.vline_pos;
|
||||
}
|
||||
yy += CLIP_10BIT_SIGNED(voffset - centery);
|
||||
|
||||
m7b = CAST_WORDTOINT(ppu.m7b) * yy + (centerx << 8);
|
||||
m7d = CAST_WORDTOINT(ppu.m7d) * yy + (centery << 8);
|
||||
|
||||
step_m7a = CAST_WORDTOINT(ppu.m7a);
|
||||
step_m7c = CAST_WORDTOINT(ppu.m7c);
|
||||
|
||||
xx = CLIP_10BIT_SIGNED(hoffset - centerx);
|
||||
|
||||
m7a = CAST_WORDTOINT(ppu.m7a) * xx;
|
||||
m7c = CAST_WORDTOINT(ppu.m7c) * xx;
|
||||
|
||||
for(x=0;x<256;x++) {
|
||||
px = ((m7a + m7b) >> 8);
|
||||
py = ((m7c + m7d) >> 8);
|
||||
|
||||
switch(ppu.mode7_repeat) {
|
||||
case 0: //screen repitition outside of screen area
|
||||
case 1: //same as case 0
|
||||
px &= 1023;
|
||||
py &= 1023;
|
||||
tx = ((px >> SH_8) & 127);
|
||||
ty = ((py >> SH_8) & 127);
|
||||
tile = ppu.vram[(ty * 128 + tx) << 1];
|
||||
palette = ppu.vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1];
|
||||
break;
|
||||
case 2: //character 0 repetition outside of screen area
|
||||
if(px < 0 || px > 1023 || py < 0 || py > 1023) {
|
||||
tx = 0;
|
||||
ty = 0;
|
||||
} else {
|
||||
px &= 1023;
|
||||
py &= 1023;
|
||||
tx = ((px >> SH_8) & 127);
|
||||
ty = ((py >> SH_8) & 127);
|
||||
}
|
||||
tile = ppu.vram[(ty * 128 + tx) << 1];
|
||||
palette = ppu.vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1];
|
||||
break;
|
||||
case 3: //palette color 0 outside of screen area
|
||||
if(px < 0 || px > 1023 || py < 0 || py > 1023) {
|
||||
palette = 0;
|
||||
} else {
|
||||
px &= 1023;
|
||||
py &= 1023;
|
||||
tx = ((px >> SH_8) & 127);
|
||||
ty = ((py >> SH_8) & 127);
|
||||
tile = ppu.vram[(ty * 128 + tx) << 1];
|
||||
palette = ppu.vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(ppu.mode7_extbg == false) {
|
||||
if(palette) {
|
||||
layer_pos = layer_pos_bg1;
|
||||
if(ppu.mode7_hflip == true) {
|
||||
ppu_set_layer_pixel(255 - x, palette);
|
||||
} else {
|
||||
ppu_set_layer_pixel(x, palette);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
priority = (palette >> 7);
|
||||
palette &= 0x7f;
|
||||
if(palette) {
|
||||
if(priority == 0) {
|
||||
layer_pos = layer_pos_bg2_pri0;
|
||||
} else {
|
||||
layer_pos = layer_pos_bg2_pri1;
|
||||
}
|
||||
if(ppu.mode7_hflip == true) {
|
||||
ppu_set_layer_pixel(255 - x, palette);
|
||||
} else {
|
||||
ppu_set_layer_pixel(x, palette);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m7a += step_m7a;
|
||||
m7c += step_m7c;
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
$2100 : screen brightness / enable
|
||||
d---bbbb
|
||||
|
||||
d: display (0=on, 1=off)
|
||||
b: brightness (0-15)
|
||||
*/
|
||||
extern emustate emu_state;
|
||||
|
||||
void mmio_w2100(byte value) {
|
||||
ppu.display_disable = (value & 0x80)?true:false;
|
||||
ppu.display_brightness = (value & 0x0f);
|
||||
}
|
||||
|
||||
/*
|
||||
$2105 : screen mode register
|
||||
dcbapmmm
|
||||
|
||||
d: bg4 tile size (0=8x8, 1=16x16)
|
||||
c: bg3 tile size (0=8x8, 1=16x16)
|
||||
b: bg2 tile size (0=8x8, 1=16x16)
|
||||
a: bg1 tile size (0=8x8, 1=16x16)
|
||||
p: bg priority mode
|
||||
m: screen mode
|
||||
*/
|
||||
void mmio_w2105(byte value) {
|
||||
static byte prev_mode = 0x00;
|
||||
ppu.bg_tile_size[BG4] = (value & 0x80)?1:0;
|
||||
ppu.bg_tile_size[BG3] = (value & 0x40)?1:0;
|
||||
ppu.bg_tile_size[BG2] = (value & 0x20)?1:0;
|
||||
ppu.bg_tile_size[BG1] = (value & 0x10)?1:0;
|
||||
ppu.bg_priority_mode = (value & 0x08)?1:0;
|
||||
ppu.bg_mode = (value & 0x07);
|
||||
if(prev_mode != ppu.bg_mode) {
|
||||
video_setsnesmode();
|
||||
prev_mode = ppu.bg_mode;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
$2106 : mosaic
|
||||
ssssdcba
|
||||
|
||||
s: size (0=smallest, 15=largest)
|
||||
d: affect bg4
|
||||
c: affect bg3
|
||||
b: affect bg2
|
||||
a: affect bg1
|
||||
*/
|
||||
void mmio_w2106(byte value) {
|
||||
ppu.mosaic_size = (value >> 4) & 15;
|
||||
ppu.mosaic_enabled[BG4] = (value & 0x08)?true:false;
|
||||
ppu.mosaic_enabled[BG3] = (value & 0x04)?true:false;
|
||||
ppu.mosaic_enabled[BG2] = (value & 0x02)?true:false;
|
||||
ppu.mosaic_enabled[BG1] = (value & 0x01)?true:false;
|
||||
}
|
||||
|
||||
/*
|
||||
$212c : main screen desgination
|
||||
$212d : sub screen designation
|
||||
---sdcba
|
||||
|
||||
s: oam enable
|
||||
d: bg4 enable
|
||||
c: bg3 enable
|
||||
b: bg2 enable
|
||||
a: bg1 enable
|
||||
*/
|
||||
void mmio_w212c(byte value) {
|
||||
ppu.bg_enabled[OAM] = (value & 0x10)?true:false;
|
||||
ppu.bg_enabled[BG4] = (value & 0x08)?true:false;
|
||||
ppu.bg_enabled[BG3] = (value & 0x04)?true:false;
|
||||
ppu.bg_enabled[BG2] = (value & 0x02)?true:false;
|
||||
ppu.bg_enabled[BG1] = (value & 0x01)?true:false;
|
||||
}
|
||||
|
||||
void mmio_w212d(byte value) {
|
||||
ppu.ss_bg_enabled[OAM] = (value & 0x10)?true:false;
|
||||
ppu.ss_bg_enabled[BG4] = (value & 0x08)?true:false;
|
||||
ppu.ss_bg_enabled[BG3] = (value & 0x04)?true:false;
|
||||
ppu.ss_bg_enabled[BG2] = (value & 0x02)?true:false;
|
||||
ppu.ss_bg_enabled[BG1] = (value & 0x01)?true:false;
|
||||
}
|
||||
|
||||
/*
|
||||
$2133 : screen mode settings
|
||||
?m???ohi
|
||||
|
||||
m: mode7 extbg (0 = off, 1 = on)
|
||||
o: overscan (0 = off, 1 = on)
|
||||
h: sprite halve (0 = off, 1 = on)
|
||||
i: interlace (0 = off, 1 = on)
|
||||
*/
|
||||
void mmio_w2133(byte value) {
|
||||
ppu.mode7_extbg = (value & 0x40)?true:false;
|
||||
ppu.overscan = (value & 0x04)?true:false;
|
||||
ppu.visible_scanlines = (value & 0x04)?239:224;
|
||||
ppu.sprite_halve = (value & 0x02)?true:false;
|
||||
ppu.toggle_interlace = (value & 0x01)?true:false;
|
||||
video_setsnesmode();
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
$210d-$2114 : Scroll registers
|
||||
|
||||
210d/210e: bg1 hscroll/bg1 vscroll
|
||||
210f/2110: bg2 hscroll/bg2 vscroll
|
||||
2111/2112: bg3 hscroll/bg3 vscroll
|
||||
2113/2114: bg4 hscroll/bg4 vscroll
|
||||
|
||||
you must write to this register twice to write the full address.
|
||||
starting positions are 0, 0. only 11 bits of the address are used.
|
||||
*/
|
||||
void mmio_w210d(byte value) {
|
||||
ppu.bg_hscroll_pos[BG1] = (value << 8) | (ppu.bg_hscroll_pos[BG1] >> 8);
|
||||
ppu.m7hofs = (value << 8) | (ppu.m7hofs >> 8);
|
||||
}
|
||||
|
||||
void mmio_w210e(byte value) {
|
||||
ppu.bg_vscroll_pos[BG1] = (value << 8) | (ppu.bg_vscroll_pos[BG1] >> 8);
|
||||
ppu.m7vofs = (value << 8) | (ppu.m7vofs >> 8);
|
||||
}
|
||||
|
||||
void mmio_w210f(byte value) {
|
||||
ppu.bg_hscroll_pos[BG2] = (value << 8) | (ppu.bg_hscroll_pos[BG2] >> 8);
|
||||
}
|
||||
|
||||
void mmio_w2110(byte value) {
|
||||
ppu.bg_vscroll_pos[BG2] = (value << 8) | (ppu.bg_vscroll_pos[BG2] >> 8);
|
||||
}
|
||||
|
||||
void mmio_w2111(byte value) {
|
||||
ppu.bg_hscroll_pos[BG3] = (value << 8) | (ppu.bg_hscroll_pos[BG3] >> 8);
|
||||
}
|
||||
|
||||
void mmio_w2112(byte value) {
|
||||
ppu.bg_vscroll_pos[BG3] = (value << 8) | (ppu.bg_vscroll_pos[BG3] >> 8);
|
||||
}
|
||||
|
||||
void mmio_w2113(byte value) {
|
||||
ppu.bg_hscroll_pos[BG4] = (value << 8) | (ppu.bg_hscroll_pos[BG4] >> 8);
|
||||
}
|
||||
|
||||
void mmio_w2114(byte value) {
|
||||
ppu.bg_vscroll_pos[BG4] = (value << 8) | (ppu.bg_vscroll_pos[BG4] >> 8);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
byte mmio_rspc(byte port) {
|
||||
#ifndef NO_SPC700
|
||||
return cpu_apu_bridge->cpu_read(port);
|
||||
#else
|
||||
static byte t = 0, counter = 0;
|
||||
byte x;
|
||||
if(rand() & 1) {
|
||||
x = rand() & 7;
|
||||
if(x == 0) {
|
||||
if(!(port & 1))t = gx816->regs.a.w;
|
||||
else t = gx816->regs.a.w >> 8;
|
||||
}
|
||||
else if(x == 1) {
|
||||
if(!(port & 1))t = gx816->regs.x;
|
||||
else t = gx816->regs.x >> 8;
|
||||
}
|
||||
else if(x == 2) {
|
||||
if(!(port & 1))t = gx816->regs.y;
|
||||
else t = gx816->regs.y >> 8;
|
||||
}
|
||||
else if(x == 3)t = 0xaa;
|
||||
else if(x == 4)t = 0xbb;
|
||||
else if(x == 5)t = 0xcc;
|
||||
else { t = counter++; }
|
||||
}
|
||||
return t;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mmio_wspc(byte port, byte value) {
|
||||
#ifndef NO_SPC700
|
||||
cpu_apu_bridge->cpu_write(port, value);
|
||||
#endif
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
$2137 : counter latch
|
||||
|
||||
reading from this register will latch the x/y
|
||||
counter positions, but only if bit 7 of $4201
|
||||
is set. the default state of this register is
|
||||
$ff on snes power on/reset.
|
||||
*/
|
||||
byte mmio_r2137(void) {
|
||||
if(ppu.io4201 & 0x80) {
|
||||
snes_time->set_scan_pos(snes_time->master_cycles, false);
|
||||
ppu.latch_toggle = 0;
|
||||
ppu.latch_vpos = snes_time->vscan_pos;
|
||||
ppu.latch_hpos = snes_time->hscan_pos;
|
||||
ppu.counter_latched = true;
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
byte mmio_r213c(void) {
|
||||
word r;
|
||||
r = ppu.latch_hpos;
|
||||
if(ppu.latch_toggle)r >>= 8;
|
||||
ppu.latch_toggle ^= 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
byte mmio_r213d(void) {
|
||||
word r;
|
||||
r = ppu.latch_vpos;
|
||||
if(ppu.latch_toggle)r >>= 8;
|
||||
ppu.latch_toggle ^= 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
$213e : ppu1 status register
|
||||
trm-vvvv
|
||||
|
||||
t: time over (?)
|
||||
r: range over (?)
|
||||
m: master/slave mode select (?)
|
||||
-: open bus (?)
|
||||
v: PPU1 (5c77) version number [1]
|
||||
*/
|
||||
byte mmio_r213e(void) {
|
||||
byte r = 0x00;
|
||||
r |= 0x01; //ppu1 version #
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
$213f : ppu2 status register
|
||||
ilcmvvvv
|
||||
|
||||
i: interlace frame (0=even, 1=odd)
|
||||
l: counter latched
|
||||
c: open bus complement
|
||||
m: ntsc/pal mode (0=ntsc, 1=pal)
|
||||
v: PPU2 (5c78) version number [3]
|
||||
|
||||
notes:
|
||||
bit 6 (l): counter is latched by reading $2137,
|
||||
or a 1->0 transition of $4201 bit 7.
|
||||
|
||||
bit 5 (c): this is not implemented correctly. basically,
|
||||
my copier (super ufo 8.3j) breaks the snes open bus.
|
||||
as a result, 0x00 is always returned instead of the
|
||||
open bus values. since this is the complement of that
|
||||
value, 1 is always returned. I am emulating what my
|
||||
copier returns until I can get a copier that supports
|
||||
open bus correctly.
|
||||
*/
|
||||
byte mmio_r213f(void) {
|
||||
byte r = 0x00;
|
||||
r |= ppu.interlace_frame << 7;
|
||||
if(!(ppu.io4201 & 0x80)) {
|
||||
r |= 1 << 6;
|
||||
} else if(ppu.counter_latched == true) {
|
||||
r |= 1 << 6;
|
||||
ppu.counter_latched = false;
|
||||
}
|
||||
r |= 1 << 5;
|
||||
r |= 0x03; //ppu2 version #
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
$4200 : counter enable
|
||||
n-vh---j
|
||||
|
||||
n: nmi enable
|
||||
v: vertical counter enable
|
||||
h: horizontal counter enable
|
||||
j: automatic joypad enable
|
||||
|
||||
the v/h counters must be enabled to invoke IRQs. the vertical
|
||||
counter will override the horizontal counter. in other words,
|
||||
if both v+h are set, only vertical IRQs will be performed.
|
||||
*/
|
||||
void mmio_w4200(byte value) {
|
||||
gx816->nmi_enabled = (value & 0x80)?true:false;
|
||||
ppu.vcounter_enabled = (value & 0x20)?true:false;
|
||||
ppu.hcounter_enabled = (value & 0x10)?true:false;
|
||||
ppu.auto_joypad_read = (value & 0x01)?true:false;
|
||||
}
|
||||
|
||||
/*
|
||||
$4201 : programmable i/o port
|
||||
l???????
|
||||
|
||||
l: counter latch
|
||||
|
||||
upon power on/reset, this value is set to 0xff.
|
||||
clearing bit 7 will result in the x/y dot position
|
||||
being set in $213c/$213d. the counters cannot be
|
||||
latched again by writing a 0 to bit 7 until a 1 is
|
||||
written to this bit first. reading $2137 while bit 7
|
||||
is cleared will not latch the counters.
|
||||
|
||||
examples (+ = counter latched, - = counter not latched):
|
||||
$00->$4201+
|
||||
$80->$4201-
|
||||
$00->$4201+ $00->$4201- $80->$4201- $00->$4201+
|
||||
$2137->a+ $00->$4201+ $2137->a-
|
||||
*/
|
||||
void mmio_w4201(byte value) {
|
||||
if((ppu.io4201 & 0x80) && !(value & 0x80)) {
|
||||
snes_time->set_scan_pos(snes_time->master_cycles + 4, false);
|
||||
ppu.latch_toggle = 0;
|
||||
ppu.latch_vpos = snes_time->vscan_pos;
|
||||
ppu.latch_hpos = snes_time->hscan_pos;
|
||||
ppu.counter_latched = true;
|
||||
}
|
||||
ppu.io4201 = value;
|
||||
}
|
||||
|
||||
/*
|
||||
$4207/$4208 : horizontal counter position
|
||||
|
||||
9-bit value, used to invoke horizontal IRQs
|
||||
horizontal range: 0-339
|
||||
*/
|
||||
void mmio_w4207(byte value) {
|
||||
ppu.hirq_pos = (ppu.hirq_pos & 0x0100) | value;
|
||||
}
|
||||
void mmio_w4208(byte value) {
|
||||
ppu.hirq_pos = (ppu.hirq_pos & 0x00ff) | (value & 1) << 8;
|
||||
}
|
||||
|
||||
/*
|
||||
$4209/$420a : vertical counter position
|
||||
|
||||
9-bit value, used to invoke vertical IRQs
|
||||
vertical range: 0-261
|
||||
*/
|
||||
void mmio_w4209(byte value) {
|
||||
ppu.virq_pos = (ppu.virq_pos & 0x0100) | value;
|
||||
}
|
||||
void mmio_w420a(byte value) {
|
||||
ppu.virq_pos = (ppu.virq_pos & 0x00ff) | (value & 1) << 8;
|
||||
}
|
||||
|
||||
/*
|
||||
$420d : memory speed
|
||||
0000000x
|
||||
|
||||
x: 0 = SlowROM
|
||||
1 = FastROM
|
||||
*/
|
||||
void mmio_w420d(byte value) {
|
||||
gx816->memory_speed = (value) & 0x01;
|
||||
snes_time->set_speed_map(gx816->memory_speed);
|
||||
}
|
||||
|
||||
/*
|
||||
$4210 : nmi status
|
||||
n---vvvv
|
||||
|
||||
n: nmi occurred (0=no, 1=yes)
|
||||
-: open bus (?)
|
||||
v: CPU (5a22) version number [2]
|
||||
|
||||
value is set/cleared regardless of whether or not
|
||||
NMIs are enabled in $4200 bit 7.
|
||||
*/
|
||||
byte mmio_r4210(void) {
|
||||
byte r = 0x00;
|
||||
r |= (gx816->nmi_pin ^ 1)?0x80:0x00;
|
||||
r |= 0x02; //cpu version #
|
||||
gx816->nmi_pin = 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
$4211 : irq toggle
|
||||
i?------
|
||||
|
||||
i: irq state (1=in irq, 0=not in irq)?
|
||||
?: unknown, always return 1?
|
||||
*/
|
||||
byte mmio_r4211(void) {
|
||||
byte r = 0x00;
|
||||
r |= 0x40;
|
||||
if(ppu.irq_triggered == true)r |= 0x80;
|
||||
ppu.irq_triggered = false;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
$4212 : video status
|
||||
vh-----j
|
||||
|
||||
v: vblank (0=no, 1=yes)
|
||||
h: hblank (0=no, 1=yes)
|
||||
j: joypad ready (for auto joypad mode)
|
||||
*/
|
||||
byte mmio_r4212(void) {
|
||||
byte r;
|
||||
r = 0x00;
|
||||
|
||||
//set when the SNES is updating the joypad data automatically
|
||||
if(snes_time->vscan_pos >= (ppu.visible_scanlines + 1) && snes_time->vscan_pos <= (ppu.visible_scanlines + 3))r |= 0x01;
|
||||
|
||||
//set when the SNES is in hblank/vblank
|
||||
if(snes_time->hcycle_pos <= 4 || snes_time->hcycle_pos >= 1098)r |= 0x40;
|
||||
if(snes_time->vscan_pos == 0 || snes_time->vscan_pos >= (ppu.visible_scanlines + 1)) {
|
||||
if(snes_time->vscan_pos == 0) {
|
||||
if(snes_time->hcycle_pos < 2)r |= 0x80;
|
||||
} else if(snes_time->vscan_pos == (ppu.visible_scanlines + 1)) {
|
||||
if(snes_time->hcycle_pos >= 2)r |= 0x80;
|
||||
} else {
|
||||
r |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
$2107-$210a : bg1-4 tilemap location
|
||||
bbbbbbss
|
||||
|
||||
b: location of bg tilemap - highest bit is ignored
|
||||
s: tilemap size (00 = 32x32, 01 = 64x32, 10 = 32x64, 11 = 64x64)
|
||||
*/
|
||||
void mmio_w2107(byte value) {
|
||||
ppu.bg_tilemap_loc[BG1] = (value & 0x7c) << 9;
|
||||
ppu.bg_tilemap_size[BG1] = value & 3;
|
||||
}
|
||||
void mmio_w2108(byte value) {
|
||||
ppu.bg_tilemap_loc[BG2] = (value & 0x7c) << 9;
|
||||
ppu.bg_tilemap_size[BG2] = value & 3;
|
||||
}
|
||||
void mmio_w2109(byte value) {
|
||||
ppu.bg_tilemap_loc[BG3] = (value & 0x7c) << 9;
|
||||
ppu.bg_tilemap_size[BG3] = value & 3;
|
||||
}
|
||||
void mmio_w210a(byte value) {
|
||||
ppu.bg_tilemap_loc[BG4] = (value & 0x7c) << 9;
|
||||
ppu.bg_tilemap_size[BG4] = value & 3;
|
||||
}
|
||||
|
||||
/*
|
||||
$210b/$210c: bg1-4 tiledata location
|
||||
bbbbaaaa
|
||||
|
||||
a: bg1/3 tiledata location (210b/210c)
|
||||
b: bg2/4 tiledata location (210b/210c)
|
||||
*/
|
||||
void mmio_w210b(byte value) {
|
||||
ppu.bg_tiledata_loc[BG1] = (value & 0x07) << 13;
|
||||
ppu.bg_tiledata_loc[BG2] = (value & 0x70) << 9;
|
||||
}
|
||||
void mmio_w210c(byte value) {
|
||||
ppu.bg_tiledata_loc[BG3] = (value & 0x07) << 13;
|
||||
ppu.bg_tiledata_loc[BG4] = (value & 0x70) << 9;
|
||||
}
|
||||
|
||||
/*
|
||||
$2115 : vram write counter
|
||||
i---mmrr
|
||||
|
||||
i: 0 = increment on $2118/$2139
|
||||
1 = increment on $2119/$213a
|
||||
m: address remapping
|
||||
00 = no remapping
|
||||
01 = aaaaaaaaBBBccccc -> aaaaaaaacccccBBB
|
||||
10 = aaaaaaaBBBcccccc -> aaaaaaaccccccBBB
|
||||
11 = aaaaaaBBBccccccc -> aaaaaacccccccBBB
|
||||
r: increment rate
|
||||
00 = increment by 1
|
||||
01 = increment by 32
|
||||
10 = increment by 128
|
||||
11 = increment by 128
|
||||
*/
|
||||
void mmio_w2115(byte value) {
|
||||
ppu.vram_inc_reg = (value & 0x80)?1:0;
|
||||
ppu.vram_remap_mode = (value >> 2) & 3;
|
||||
switch(value & 3) {
|
||||
case 0x00:ppu.vram_inc_size = 1;break;
|
||||
case 0x01:ppu.vram_inc_size = 32;break;
|
||||
case 0x02:ppu.vram_inc_size = 128;break;
|
||||
case 0x03:ppu.vram_inc_size = 128;break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
$2116/$2117 : vram write position
|
||||
|
||||
15-bit value ($2116/$2117) determining position in vram to write to using $2118
|
||||
this value is doubled to get true write position (0000-ffff)
|
||||
*/
|
||||
void mmio_w2116(byte value) {
|
||||
ppu.vram_write_pos = ((ppu.vram_write_pos & 0xff00) | value);
|
||||
}
|
||||
void mmio_w2117(byte value) {
|
||||
ppu.vram_write_pos = ((value << 8) | (ppu.vram_write_pos & 0xff));
|
||||
}
|
||||
|
||||
word mmio_vram_remap(void) {
|
||||
word addr, t;
|
||||
addr = (ppu.vram_write_pos << 1);
|
||||
switch(ppu.vram_remap_mode) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
t = (addr >> 5) & 7;
|
||||
addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | t;
|
||||
break;
|
||||
case 2:
|
||||
t = (addr >> 6) & 7;
|
||||
addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | t;
|
||||
break;
|
||||
case 3:
|
||||
t = (addr >> 7) & 7;
|
||||
addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | t;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
$2118/$2119 : vram write
|
||||
|
||||
$2118/$2119 write to vram using vram_write_pos, this is then incremented based on
|
||||
the settings of $2115 (vram_inc_size / vram_inc_reg)
|
||||
*/
|
||||
void mmio_w2118(byte value) {
|
||||
word w;
|
||||
w = mmio_vram_remap();
|
||||
ppu.vram[w] = value;
|
||||
if(ppu.vram_inc_reg == 0) {
|
||||
ppu.vram_write_pos += ppu.vram_inc_size;
|
||||
}
|
||||
ppu_bg_tiledata_state[TILE_2BIT][(w >> 4)] = 1;
|
||||
ppu_bg_tiledata_state[TILE_4BIT][(w >> 5)] = 1;
|
||||
ppu_bg_tiledata_state[TILE_8BIT][(w >> 6)] = 1;
|
||||
|
||||
debug_test_bp(BPSRC_VRAM, BP_WRITE, w, value);
|
||||
}
|
||||
|
||||
void mmio_w2119(byte value) {
|
||||
word w;
|
||||
w = mmio_vram_remap() + 1;
|
||||
ppu.vram[w] = value;
|
||||
if(ppu.vram_inc_reg == 1) {
|
||||
ppu.vram_write_pos += ppu.vram_inc_size;
|
||||
}
|
||||
ppu_bg_tiledata_state[TILE_2BIT][(w >> 4)] = 1;
|
||||
ppu_bg_tiledata_state[TILE_4BIT][(w >> 5)] = 1;
|
||||
ppu_bg_tiledata_state[TILE_8BIT][(w >> 6)] = 1;
|
||||
|
||||
debug_test_bp(BPSRC_VRAM, BP_WRITE, w, value);
|
||||
}
|
||||
|
||||
/*
|
||||
$2139/$213a : vram read
|
||||
*/
|
||||
byte mmio_r2139(void) {
|
||||
byte r;
|
||||
word w;
|
||||
w = mmio_vram_remap();
|
||||
r = ppu.vram_read_buffer;
|
||||
if(ppu.vram_inc_reg == 0) {
|
||||
ppu.vram_read_buffer = *((word*)ppu.vram + (w >> 1));
|
||||
ppu.vram_write_pos += ppu.vram_inc_size;
|
||||
}
|
||||
|
||||
debug_test_bp(BPSRC_VRAM, BP_READ, w, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
byte mmio_r213a(void) {
|
||||
byte r;
|
||||
word w;
|
||||
w = mmio_vram_remap() + 1;
|
||||
r = ppu.vram_read_buffer >> 8;
|
||||
if(ppu.vram_inc_reg == 1) {
|
||||
ppu.vram_read_buffer = *((word*)ppu.vram + (w >> 1));
|
||||
ppu.vram_write_pos += ppu.vram_inc_size;
|
||||
}
|
||||
|
||||
debug_test_bp(BPSRC_VRAM, BP_READ, w, r);
|
||||
return r;
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
$2123/$2124/$2125 : window mask settings
|
||||
|
||||
$2123:
|
||||
hgfedcba
|
||||
(bg2)
|
||||
h: enable window 2
|
||||
g: clip window 2 (0=in, 1=out)
|
||||
f: enable window 1
|
||||
e: clip window 1 (0=in, 1=out)
|
||||
(bg1)
|
||||
h: enable window 2
|
||||
g: clip window 2 (0=in, 1=out)
|
||||
f: enable window 1
|
||||
e: clip window 1 (0=in, 1=out)
|
||||
$2124: same as $2123, but with bg4/3
|
||||
$2125:
|
||||
hgfedcba
|
||||
h: enable color window 2
|
||||
g: clip window 2 (0=in, 1=out)
|
||||
f: enable color window 1
|
||||
e: clip window 1 (0=in, 1=out)
|
||||
d: enable OAM window 2
|
||||
c: clip window 2 (0=in, 1=out)
|
||||
b: enable OAM window 1
|
||||
a: clip window 1 (0=in, 1=out)
|
||||
*/
|
||||
void mmio_w2123(byte value) {
|
||||
ppu.bg_window2_enabled [BG2] = (value & 0x80)?true:false;
|
||||
ppu.bg_window2_clipmode[BG2] = (value & 0x40)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.bg_window1_enabled [BG2] = (value & 0x20)?true:false;
|
||||
ppu.bg_window1_clipmode[BG2] = (value & 0x10)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.bg_window2_enabled [BG1] = (value & 0x08)?true:false;
|
||||
ppu.bg_window2_clipmode[BG1] = (value & 0x04)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.bg_window1_enabled [BG1] = (value & 0x02)?true:false;
|
||||
ppu.bg_window1_clipmode[BG1] = (value & 0x01)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
}
|
||||
|
||||
void mmio_w2124(byte value) {
|
||||
ppu.bg_window2_enabled [BG4] = (value & 0x80)?true:false;
|
||||
ppu.bg_window2_clipmode[BG4] = (value & 0x40)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.bg_window1_enabled [BG4] = (value & 0x20)?true:false;
|
||||
ppu.bg_window1_clipmode[BG4] = (value & 0x10)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.bg_window2_enabled [BG3] = (value & 0x08)?true:false;
|
||||
ppu.bg_window2_clipmode[BG3] = (value & 0x04)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.bg_window1_enabled [BG3] = (value & 0x02)?true:false;
|
||||
ppu.bg_window1_clipmode[BG3] = (value & 0x01)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
}
|
||||
|
||||
void mmio_w2125(byte value) {
|
||||
ppu.color_window2_enabled = (value & 0x80)?true:false;
|
||||
ppu.color_window2_clipmode = (value & 0x40)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.color_window1_enabled = (value & 0x20)?true:false;
|
||||
ppu.color_window1_clipmode = (value & 0x10)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.bg_window2_enabled [OAM] = (value & 0x08)?true:false;
|
||||
ppu.bg_window2_clipmode[OAM] = (value & 0x04)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
ppu.bg_window1_enabled [OAM] = (value & 0x02)?true:false;
|
||||
ppu.bg_window1_clipmode[OAM] = (value & 0x01)?CLIPMODE_OUT:CLIPMODE_IN;
|
||||
}
|
||||
|
||||
/*
|
||||
$2126-$2129 : window position settings
|
||||
|
||||
$2126: window 1 left
|
||||
$2127: window 1 right
|
||||
$2128: window 2 left
|
||||
$2129: window 2 right
|
||||
*/
|
||||
void mmio_w2126(byte value) { ppu.window1_left = value; }
|
||||
void mmio_w2127(byte value) { ppu.window1_right = value; }
|
||||
void mmio_w2128(byte value) { ppu.window2_left = value; }
|
||||
void mmio_w2129(byte value) { ppu.window2_right = value; }
|
||||
|
||||
/*
|
||||
$212a/$212b : window mask settings
|
||||
$212a: ddccbbaa (d=bg4, c=bg3, b=bg2, a=bg1)
|
||||
$212b: ----ccss (c=color add/sub, s=oam)
|
||||
|
||||
00=or
|
||||
01=and
|
||||
10=xor
|
||||
11=xnor
|
||||
*/
|
||||
void mmio_w212a(byte value) {
|
||||
ppu.bg_window_mask[BG4] = (value >> 6) & 3;
|
||||
ppu.bg_window_mask[BG3] = (value >> 4) & 3;
|
||||
ppu.bg_window_mask[BG2] = (value >> 2) & 3;
|
||||
ppu.bg_window_mask[BG1] = (value ) & 3;
|
||||
}
|
||||
|
||||
void mmio_w212b(byte value) {
|
||||
ppu.color_window_mask = (value >> 2) & 3;
|
||||
ppu.bg_window_mask[OAM] = (value ) & 3;
|
||||
}
|
||||
|
||||
/*
|
||||
$212e/$212f : main window designation
|
||||
|
||||
---odcba
|
||||
|
||||
o: OAM enable
|
||||
d: BG4 enable
|
||||
c: BG3 enable
|
||||
b: BG2 enable
|
||||
a: BG1 enable
|
||||
*/
|
||||
void mmio_w212e(byte value) {
|
||||
ppu.bg_windowing_enabled[OAM] = (value & 0x10)?true:false;
|
||||
ppu.bg_windowing_enabled[BG4] = (value & 0x08)?true:false;
|
||||
ppu.bg_windowing_enabled[BG3] = (value & 0x04)?true:false;
|
||||
ppu.bg_windowing_enabled[BG2] = (value & 0x02)?true:false;
|
||||
ppu.bg_windowing_enabled[BG1] = (value & 0x01)?true:false;
|
||||
}
|
||||
|
||||
void mmio_w212f(byte value) {
|
||||
ppu.ss_bg_windowing_enabled[OAM] = (value & 0x10)?true:false;
|
||||
ppu.ss_bg_windowing_enabled[BG4] = (value & 0x08)?true:false;
|
||||
ppu.ss_bg_windowing_enabled[BG3] = (value & 0x04)?true:false;
|
||||
ppu.ss_bg_windowing_enabled[BG2] = (value & 0x02)?true:false;
|
||||
ppu.ss_bg_windowing_enabled[BG1] = (value & 0x01)?true:false;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
$2180 : wram read/write
|
||||
|
||||
write byte to wram write pointer ($2181-$2183), then increment pointer.
|
||||
always stays within 7e0000-7fffff, high 7 bits of 24-bit offset ignored.
|
||||
*/
|
||||
byte mmio_r2180(void) {
|
||||
byte r;
|
||||
r = gx816->mem_read(MEMMODE_NONE, MEMSIZE_BYTE, 0x7e0000 | ppu.wram_write_pos);
|
||||
ppu.wram_write_pos++;
|
||||
ppu.wram_write_pos &= 0x01ffff;
|
||||
return r;
|
||||
}
|
||||
|
||||
void mmio_w2180(byte value) {
|
||||
gx816->mem_write(MEMMODE_NONE, MEMSIZE_BYTE, 0x7e0000 | ppu.wram_write_pos, value);
|
||||
ppu.wram_write_pos++;
|
||||
ppu.wram_write_pos &= 0x01ffff;
|
||||
}
|
||||
|
||||
/*
|
||||
$2181-$2183: wram write pointer set
|
||||
*/
|
||||
void mmio_w2181(byte value) {
|
||||
ppu.wram_write_pos = ((ppu.wram_write_pos & 0xffff00) | value) & 0x01ffff;
|
||||
}
|
||||
void mmio_w2182(byte value) {
|
||||
ppu.wram_write_pos = ((ppu.wram_write_pos & 0xff00ff) | (value << 8)) & 0x01ffff;
|
||||
}
|
||||
void mmio_w2183(byte value) {
|
||||
ppu.wram_write_pos = ((ppu.wram_write_pos & 0x00ffff) | (value << 16)) & 0x01ffff;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
del c:\root\bsnes_testrom\bsnes.exe
|
||||
copy bsnes.exe c:\root\bsnes_testrom\bsnes.exe
|
||||
@pause
|
||||
@@ -1,370 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "../cpu/g65816.h"
|
||||
#include "timing.h"
|
||||
|
||||
extern g65816 *gx816;
|
||||
extern ppustate ppu;
|
||||
extern debugstate debugger;
|
||||
snes_timer *snes_time;
|
||||
|
||||
/*
|
||||
apu_cycles is incremented to keep in sync with master_cycles.
|
||||
(n << 5) is only a guess that one apu cycle is equivalent to
|
||||
32 cpu cycles.
|
||||
*/
|
||||
void add_apu_cycles(int n) {
|
||||
snes_time->apu_cycles += n;
|
||||
snes_time->bridge.apu_cycles += (n << 5);
|
||||
}
|
||||
|
||||
void snes_timer::add_cpu_cycles(byte count, byte speed) {
|
||||
ulong cycles = count * speed;
|
||||
master_cycles += cycles;
|
||||
bridge.cpu_cycles += cycles;
|
||||
}
|
||||
|
||||
void snes_timer::add_cpu_pcycles(byte count) {
|
||||
ulong speed = mem_speed_map[(gx816->regs.pc & 0xffffff) >> 9];
|
||||
ulong cycles = count * speed;
|
||||
master_cycles += cycles;
|
||||
bridge.cpu_cycles += cycles;
|
||||
}
|
||||
|
||||
void snes_timer::add_cpu_mcycles(byte count, ulong addr) {
|
||||
ulong speed = mem_speed_map[(addr & 0xffffff) >> 9];
|
||||
ulong cycles = count * speed;
|
||||
master_cycles += cycles;
|
||||
bridge.cpu_cycles += cycles;
|
||||
}
|
||||
|
||||
void snes_timer::add_cpu_scycles(byte count) {
|
||||
ulong cycles = (count << 3); //count * 8
|
||||
master_cycles += cycles;
|
||||
bridge.cpu_cycles += cycles;
|
||||
}
|
||||
|
||||
void snes_timer::add_cpu_icycles(byte count) {
|
||||
ulong cycles = (count << 2) + (count << 1); //count * 6
|
||||
master_cycles += cycles;
|
||||
bridge.cpu_cycles += cycles;
|
||||
}
|
||||
|
||||
void snes_timer::set_speed_map(byte speed) {
|
||||
if(speed == MEMSPEED_SLOWROM) {
|
||||
mem_speed_map = sm_slowrom;
|
||||
} else { //speed == MEMSPEED_FASTROM
|
||||
mem_speed_map = sm_fastrom;
|
||||
}
|
||||
}
|
||||
|
||||
void snes_timer::build_speed_map(void) {
|
||||
int i;
|
||||
byte db;
|
||||
word addr;
|
||||
ulong z;
|
||||
sm_slowrom = (byte*)malloc(0x8000);
|
||||
sm_fastrom = (byte*)malloc(0x8000);
|
||||
for(i=0;i<0x8000;i++) {
|
||||
z = (i << 9);
|
||||
db = (z >> 16);
|
||||
addr = (z & 0xffff);
|
||||
if(db >= 0x00 && db <= 0x3f) {
|
||||
if (addr >= 0x0000 && addr <= 0x1fff) {
|
||||
sm_slowrom[i] = MEMSPEED_SLOW;
|
||||
sm_fastrom[i] = MEMSPEED_SLOW;
|
||||
}
|
||||
else if(addr >= 0x2000 && addr <= 0x3fff) {
|
||||
sm_slowrom[i] = MEMSPEED_FAST;
|
||||
sm_fastrom[i] = MEMSPEED_FAST;
|
||||
}
|
||||
else if(addr >= 0x4000 && addr <= 0x41ff) {
|
||||
sm_slowrom[i] = MEMSPEED_XSLOW;
|
||||
sm_fastrom[i] = MEMSPEED_XSLOW;
|
||||
}
|
||||
else if(addr >= 0x4200 && addr <= 0x5fff) {
|
||||
sm_slowrom[i] = MEMSPEED_FAST;
|
||||
sm_fastrom[i] = MEMSPEED_FAST;
|
||||
}
|
||||
else { //(addr >= 0x6000 && addr <= 0xffff)
|
||||
sm_slowrom[i] = MEMSPEED_SLOW;
|
||||
sm_fastrom[i] = MEMSPEED_SLOW;
|
||||
}
|
||||
} else if(db >= 0x40 && db <= 0x7f) {
|
||||
sm_slowrom[i] = MEMSPEED_SLOW;
|
||||
sm_fastrom[i] = MEMSPEED_SLOW;
|
||||
} else if(db >= 0x80 && db <= 0xbf) {
|
||||
if (addr >= 0x0000 && addr <= 0x1fff) {
|
||||
sm_slowrom[i] = MEMSPEED_SLOW;
|
||||
sm_fastrom[i] = MEMSPEED_SLOW;
|
||||
}
|
||||
else if(addr >= 0x2000 && addr <= 0x3fff) {
|
||||
sm_slowrom[i] = MEMSPEED_FAST;
|
||||
sm_fastrom[i] = MEMSPEED_FAST;
|
||||
}
|
||||
else if(addr >= 0x4000 && addr <= 0x41ff) {
|
||||
sm_slowrom[i] = MEMSPEED_XSLOW;
|
||||
sm_fastrom[i] = MEMSPEED_XSLOW;
|
||||
}
|
||||
else if(addr >= 0x4200 && addr <= 0x5fff) {
|
||||
sm_slowrom[i] = MEMSPEED_FAST;
|
||||
sm_fastrom[i] = MEMSPEED_FAST;
|
||||
}
|
||||
else if(addr >= 0x6000 && addr <= 0x7fff) {
|
||||
sm_slowrom[i] = MEMSPEED_SLOW;
|
||||
sm_fastrom[i] = MEMSPEED_SLOW;
|
||||
}
|
||||
else { //(addr >= 0x8000 && addr <= 0xffff)
|
||||
sm_slowrom[i] = MEMSPEED_SLOW;
|
||||
sm_fastrom[i] = MEMSPEED_FAST;
|
||||
}
|
||||
} else { //(db >= 0xc0 && db <= 0xff)
|
||||
sm_slowrom[i] = MEMSPEED_SLOW;
|
||||
sm_fastrom[i] = MEMSPEED_FAST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
all dots are 4 cycles long, except dots 322 and 326. dots 322 and 326
|
||||
are 6 cycles long. this holds true for all scanlines except scanline
|
||||
240 on non-interlace odd frames. the reason for this is because this
|
||||
scanline is only 1360 cycles long, instead of 1364 like all other
|
||||
scanlines.
|
||||
this makes the effective range of hscan_pos 0-339 at all times.
|
||||
dot 322 range = { 1288, 1290, 1292 }
|
||||
dot 326 range = { 1306, 1308, 1310 }
|
||||
|
||||
latch_table_a is used for interlace-even, interlace-odd, and
|
||||
non-interlace-even frames. this is done to conserve memory.
|
||||
interlace-even frames have one extra scanline, but the
|
||||
cycle-to-x/y positions are still identical.
|
||||
latch_table_b is used for non-interlace-odd, because these
|
||||
frames have one scanline that is 4 master cycles shorter than
|
||||
the others. this would offset all x/y positions from (322,240)
|
||||
and onward without a separate table.
|
||||
|
||||
both tables are one scanline longer than the snes allows so that
|
||||
if the x/y positions are refreshed and the cycle position used
|
||||
goes beyond the end of the frame, it won't access an invalid
|
||||
memory address. the routine will then see that the y position
|
||||
is higher than the current frame allows, and it will reset the
|
||||
y position at that time.
|
||||
*/
|
||||
void snes_timer::build_dot_map(void) {
|
||||
int x, y, cycle;
|
||||
int ptr;
|
||||
latch_table_a = (latch_pos*)malloc(264 * (1364 / 2) * sizeof(latch_pos));
|
||||
latch_table_b = (latch_pos*)malloc(263 * (1364 / 2) * sizeof(latch_pos));
|
||||
|
||||
ptr = 0;
|
||||
for(y=0;y<264;y++) {
|
||||
for(x=cycle=0;x<340;x++) {
|
||||
latch_table_a[ptr].cx = cycle;
|
||||
latch_table_a[ptr].x = x;
|
||||
latch_table_a[ptr].y = y;
|
||||
ptr++;
|
||||
cycle += 2;
|
||||
latch_table_a[ptr].cx = cycle;
|
||||
latch_table_a[ptr].x = x;
|
||||
latch_table_a[ptr].y = y;
|
||||
ptr++;
|
||||
cycle += 2;
|
||||
if(x == 322 || x == 326) {
|
||||
latch_table_a[ptr].cx = cycle;
|
||||
latch_table_a[ptr].x = x;
|
||||
latch_table_a[ptr].y = y;
|
||||
ptr++;
|
||||
cycle += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ptr = 0;
|
||||
for(y=0;y<263;y++) {
|
||||
for(x=cycle=0;x<340;x++) {
|
||||
latch_table_b[ptr].cx = cycle;
|
||||
latch_table_b[ptr].x = x;
|
||||
latch_table_b[ptr].y = y;
|
||||
ptr++;
|
||||
cycle += 2;
|
||||
latch_table_b[ptr].cx = cycle;
|
||||
latch_table_b[ptr].x = x;
|
||||
latch_table_b[ptr].y = y;
|
||||
ptr++;
|
||||
cycle += 2;
|
||||
if(y != 240 && (x == 322 || x == 326)) {
|
||||
latch_table_b[ptr].cx = cycle;
|
||||
latch_table_b[ptr].x = x;
|
||||
latch_table_b[ptr].y = y;
|
||||
ptr++;
|
||||
cycle += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void snes_timer::reset_clock(void) {
|
||||
mem_speed_map = sm_slowrom;
|
||||
|
||||
//upon SNES reset, starts at scanline 0 non-interlace
|
||||
frame_cycles = 262 * 1364;
|
||||
frame_lines = 262;
|
||||
line_cycles = 1364;
|
||||
ppu.interlace = false;
|
||||
ppu.toggle_interlace = false;
|
||||
ppu.interlace_frame = 0;
|
||||
latch_table = latch_table_a;
|
||||
|
||||
vscan_pos = 0;
|
||||
hscan_pos = 0;
|
||||
hcycle_pos = 0;
|
||||
|
||||
dram_refresh_pos = 538;
|
||||
dram_refreshed = false;
|
||||
|
||||
nmi_triggered = false;
|
||||
|
||||
apu_cycles = 0;
|
||||
bridge.cpu_cycles = 0;
|
||||
bridge.apu_cycles = 0;
|
||||
|
||||
/*
|
||||
Initial latch values for $213c/$213d
|
||||
0035:0000 (53.0 -> 212) [lda $2137]
|
||||
0038:0000 (56.5 -> 226) [nop : lda $2137]
|
||||
*/
|
||||
master_cycles = 188;
|
||||
prev_master_cycles = 0;
|
||||
update_timer();
|
||||
}
|
||||
|
||||
snes_timer::snes_timer() {
|
||||
build_speed_map();
|
||||
build_dot_map();
|
||||
}
|
||||
|
||||
snes_timer::~snes_timer() {
|
||||
if(mem_speed_map)free(mem_speed_map);
|
||||
if(latch_table_a)free(latch_table_a);
|
||||
if(latch_table_b)free(latch_table_b);
|
||||
}
|
||||
|
||||
/*
|
||||
all scanlines are 1364 cycles long, except scanline 240
|
||||
on non-interlace odd-frames, which is 1360 cycles long.
|
||||
interlace mode has 525 scanlines: 263 on the even frame,
|
||||
and 262 on the odd.
|
||||
non-interlace mode has 524 scanlines: 262 scanlines on
|
||||
both even and odd frames.
|
||||
*/
|
||||
void snes_timer::inc_vscan_pos(void) {
|
||||
if(vscan_pos >= frame_lines) {
|
||||
master_cycles -= frame_cycles;
|
||||
vscan_pos = 0;
|
||||
nmi_triggered = false;
|
||||
|
||||
ppu.interlace = ppu.toggle_interlace;
|
||||
ppu.interlace_frame ^= 1;
|
||||
if(ppu.interlace == true) {
|
||||
if(ppu.interlace_frame == 0) {
|
||||
frame_cycles = 263 * 1364;
|
||||
frame_lines = 263;
|
||||
} else {
|
||||
frame_cycles = 262 * 1364;
|
||||
frame_lines = 262;
|
||||
}
|
||||
latch_table = latch_table_a;
|
||||
} else { //ppu.interlace == false
|
||||
if(ppu.interlace_frame == 0) {
|
||||
frame_cycles = 262 * 1364;
|
||||
frame_lines = 262;
|
||||
latch_table = latch_table_a;
|
||||
} else {
|
||||
frame_cycles = (262 * 1364) - 4;
|
||||
frame_lines = 262;
|
||||
latch_table = latch_table_b;
|
||||
}
|
||||
}
|
||||
vscan_wrapped = true;
|
||||
}
|
||||
|
||||
if(ppu.interlace == false && ppu.interlace_frame == 1 && vscan_pos == 240) {
|
||||
line_cycles = 1360;
|
||||
} else {
|
||||
line_cycles = 1364;
|
||||
}
|
||||
|
||||
hscan_wrapped = true;
|
||||
dram_refreshed = false;
|
||||
}
|
||||
|
||||
void snes_timer::update_dram_refresh_pos(void) {
|
||||
if(ppu.interlace == false && ppu.interlace_frame == 1 && vscan_pos == 240) {
|
||||
//dram refresh position doesn't change
|
||||
} else {
|
||||
if(dram_refresh_pos == 534) {
|
||||
dram_refresh_pos = 538;
|
||||
} else {
|
||||
dram_refresh_pos = 534;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
this routine is *not* designed to seek to any scan position passed to it.
|
||||
it is intended that cycle_pos is no more than 40 master cycles above the
|
||||
previous cycle_pos given to this routine. the routine has two purposes,
|
||||
one is to actually update the screen x/y positions and trigger system
|
||||
events; the other is to allow the 4 master cycle difference between latching
|
||||
the x/y counters from reading $2137 and writing $4201.
|
||||
the former passes update_frame_info as true, as the changes should be permanent.
|
||||
the latter passes update_frame_info as false, as the real cycle counter will
|
||||
not be incremented at that time (that is handled within the opcodes themselves).
|
||||
|
||||
the cycle_pos passed is divided by 2 because the smallest possible cpu clock
|
||||
frequency is 2 master cycles, and this allows the latch tables to consume only
|
||||
half as much memory.
|
||||
*/
|
||||
void snes_timer::set_scan_pos(ulong cycle_pos, bool update_frame_info) {
|
||||
int y;
|
||||
y = vscan_pos;
|
||||
cycle_pos >>= 1;
|
||||
vscan_pos = latch_table[cycle_pos].y;
|
||||
hscan_pos = latch_table[cycle_pos].x;
|
||||
hcycle_pos = latch_table[cycle_pos].cx;
|
||||
if(update_frame_info == true) {
|
||||
if(vscan_pos > y) {
|
||||
inc_vscan_pos();
|
||||
}
|
||||
} else {
|
||||
if(vscan_pos >= frame_lines) {
|
||||
vscan_pos -= frame_lines;
|
||||
}
|
||||
}
|
||||
|
||||
if(dram_refreshed == false && hcycle_pos >= dram_refresh_pos) {
|
||||
if(update_frame_info == true) {
|
||||
add_cpu_cycles(1, 40);
|
||||
dram_refreshed = true;
|
||||
update_dram_refresh_pos();
|
||||
}
|
||||
hcycle_pos += 40;
|
||||
hscan_pos += 10;
|
||||
}
|
||||
}
|
||||
|
||||
void snes_timer::update_timer(void) {
|
||||
set_scan_pos(master_cycles, true);
|
||||
}
|
||||
|
||||
void snes_timer::update_timer_events(void) {
|
||||
if(gx816->cpu_state == CPUSTATE_STP)return;
|
||||
|
||||
if(snes_time->vscan_pos == (ppu.visible_scanlines + 1) && snes_time->hcycle_pos >= 12 && nmi_triggered == false) {
|
||||
nmi_triggered = true;
|
||||
gx816->nmi_pin = 0;
|
||||
if(gx816->nmi_enabled == true) {
|
||||
gx816->InvokeIRQ(0xffea);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
//mask table (powers of 2)
|
||||
#define TIMING_NONE 0x00
|
||||
#define TIMING_CONDITION2 0x01 //DL != 0
|
||||
#define TIMING_CONDITION4 0x02 //crossed page boundary or p.x = 0
|
||||
|
||||
typedef struct {
|
||||
word cx, x, y;
|
||||
}latch_pos;
|
||||
|
||||
class snes_timer {
|
||||
public:
|
||||
ulong apu_cycles;
|
||||
ulong master_cycles, prev_master_cycles;
|
||||
struct {
|
||||
ulong cpu_cycles, apu_cycles;
|
||||
}bridge;
|
||||
word hcycle_pos, vscan_pos, hscan_pos;
|
||||
bool vscan_wrapped, hscan_wrapped;
|
||||
bool dram_refreshed, nmi_triggered;
|
||||
byte *mem_speed_map, *sm_slowrom, *sm_fastrom;
|
||||
ulong frame_cycles, frame_lines, line_cycles;
|
||||
word dram_refresh_pos;
|
||||
latch_pos *latch_table_a, *latch_table_b, *latch_table;
|
||||
|
||||
void add_cpu_cycles (byte count, byte speed);
|
||||
void add_cpu_pcycles(byte count);
|
||||
void add_cpu_mcycles(byte count, ulong addr);
|
||||
void add_cpu_scycles(byte count);
|
||||
void add_cpu_icycles(byte count);
|
||||
|
||||
ulong get_master_cycle_count(ulong offset);
|
||||
void build_speed_map(void);
|
||||
void build_dot_map(void);
|
||||
void reset_clock(void);
|
||||
void inc_vscan_pos(void);
|
||||
void set_scan_pos(ulong cycle_pos, bool update_frame_info);
|
||||
void set_speed_map(byte speed);
|
||||
void update_dram_refresh_pos(void);
|
||||
void update_timer(void);
|
||||
void update_timer_events(void);
|
||||
snes_timer();
|
||||
~snes_timer();
|
||||
};
|
||||
@@ -1,459 +0,0 @@
|
||||
#include "../base.h"
|
||||
#include "../timing/timing.h"
|
||||
extern snes_timer *snes_time;
|
||||
#include "../cpu/g65816.h"
|
||||
#include "../apu/spc700.h"
|
||||
extern g65816 *gx816;
|
||||
extern sony_spc700 *spc700;
|
||||
extern emustate emu_state;
|
||||
extern debugstate debugger;
|
||||
extern videostate render;
|
||||
extern ppustate ppu;
|
||||
#include <windows.h>
|
||||
|
||||
#define BSNES_TITLE "bsnes v0.0.005a"
|
||||
|
||||
enum {
|
||||
MENU_FILE_LOAD = 100,
|
||||
MENU_FILE_RESET,
|
||||
MENU_FILE_EXIT,
|
||||
MENU_SETTINGS_VIDEOMODE_256x224w,
|
||||
MENU_SETTINGS_VIDEOMODE_512x448w,
|
||||
MENU_SETTINGS_VIDEOMODE_640x480f,
|
||||
MENU_SETTINGS_FRAMESKIP_OFF,
|
||||
MENU_SETTINGS_FRAMESKIP_1,
|
||||
MENU_SETTINGS_FRAMESKIP_2,
|
||||
MENU_SETTINGS_FRAMESKIP_3,
|
||||
MENU_SETTINGS_FRAMESKIP_4,
|
||||
MENU_SETTINGS_FRAMESKIP_5,
|
||||
MENU_SETTINGS_FRAMESKIP_6,
|
||||
MENU_SETTINGS_FRAMESKIP_7,
|
||||
MENU_SETTINGS_FRAMESKIP_8,
|
||||
MENU_SETTINGS_FRAMESKIP_9,
|
||||
MENU_SETTINGS_DEBUGGER,
|
||||
MENU_HELP_ABOUT
|
||||
};
|
||||
|
||||
HWND hwndMain = 0;
|
||||
HMENU hmenuMain;
|
||||
HFONT hFontFixed, hFont;
|
||||
|
||||
extern joypad_state joypad1;
|
||||
|
||||
#define KEY_UP VK_UP
|
||||
#define KEY_DOWN VK_DOWN
|
||||
#define KEY_LEFT VK_LEFT
|
||||
#define KEY_RIGHT VK_RIGHT
|
||||
#define KEY_SHIFT VK_RSHIFT
|
||||
#define KEY_ENTER VK_RETURN
|
||||
#define KEY_A 'A'
|
||||
#define KEY_S 'S'
|
||||
#define KEY_D 'D'
|
||||
#define KEY_Z 'Z'
|
||||
#define KEY_X 'X'
|
||||
#define KEY_C 'C'
|
||||
|
||||
#define KeyState(key) ((GetAsyncKeyState(key) & 0x8000)?1:0)
|
||||
|
||||
void UpdateJoypad(void) {
|
||||
joypad1.up = KeyState(KEY_UP );
|
||||
joypad1.down = (joypad1.up)?0:KeyState(KEY_DOWN);
|
||||
joypad1.left = KeyState(KEY_LEFT );
|
||||
joypad1.right = (joypad1.left)?0:KeyState(KEY_RIGHT);
|
||||
joypad1.select = KeyState(KEY_SHIFT);
|
||||
joypad1.start = KeyState(KEY_ENTER);
|
||||
joypad1.y = KeyState(KEY_A );
|
||||
joypad1.b = KeyState(KEY_Z );
|
||||
joypad1.x = KeyState(KEY_S );
|
||||
joypad1.a = KeyState(KEY_X );
|
||||
joypad1.l = KeyState(KEY_D );
|
||||
joypad1.r = KeyState(KEY_C );
|
||||
|
||||
if(debugger_enabled() == false)return;
|
||||
if(debugger.lock_up == true)joypad1.up = 1;
|
||||
if(debugger.lock_down == true)joypad1.down = 1;
|
||||
if(debugger.lock_left == true)joypad1.left = 1;
|
||||
if(debugger.lock_right == true)joypad1.right = 1;
|
||||
if(debugger.lock_a == true)joypad1.a = 1;
|
||||
if(debugger.lock_b == true)joypad1.b = 1;
|
||||
if(debugger.lock_x == true)joypad1.x = 1;
|
||||
if(debugger.lock_y == true)joypad1.y = 1;
|
||||
if(debugger.lock_l == true)joypad1.l = 1;
|
||||
if(debugger.lock_r == true)joypad1.r = 1;
|
||||
if(debugger.lock_select == true)joypad1.select = 1;
|
||||
if(debugger.lock_start == true)joypad1.start = 1;
|
||||
}
|
||||
|
||||
void alert(char *s, ...) {
|
||||
char str[4096];
|
||||
va_list args;
|
||||
va_start(args, s);
|
||||
vsprintf(str, s, args);
|
||||
va_end(args);
|
||||
MessageBox(0, str, "bsnes", MB_OK);
|
||||
}
|
||||
|
||||
void FixWindowSize(HWND hwnd, ulong width, ulong height, ulong px = null, ulong py = null) {
|
||||
RECT rc;
|
||||
ulong x, y, wx, wy;
|
||||
ShowWindow(hwnd, SW_HIDE);
|
||||
SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOZORDER);
|
||||
GetClientRect(hwnd, &rc);
|
||||
x = width + width - (rc.right - rc.left);
|
||||
y = height + height - (rc.bottom - rc.top);
|
||||
wx = (GetSystemMetrics(SM_CXSCREEN) - x) / 2;
|
||||
wy = (GetSystemMetrics(SM_CYSCREEN) - y) / 2;
|
||||
if(px == null || py == null) {
|
||||
SetWindowPos(hwnd, 0, wx, wy, x, y, SWP_NOZORDER);
|
||||
} else {
|
||||
SetWindowPos(hwnd, 0, px, py, x, y, SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
HBRUSH black_brush;
|
||||
|
||||
long __stdcall wndprocMain(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
void RegisterMainWindow() {
|
||||
WNDCLASS wc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = black_brush;
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = wndprocMain;
|
||||
wc.lpszClassName = "bsnes";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
}
|
||||
|
||||
void CreateMainMenu(void) {
|
||||
HMENU hsubmenu, hbranchmenu;
|
||||
hmenuMain = CreateMenu();
|
||||
|
||||
hsubmenu = CreatePopupMenu();
|
||||
AppendMenu(hsubmenu, MF_STRING, MENU_FILE_LOAD, "&Load ROM");
|
||||
AppendMenu(hsubmenu, MF_STRING, MENU_FILE_RESET, "&Reset");
|
||||
AppendMenu(hsubmenu, MF_SEPARATOR, 0, "");
|
||||
AppendMenu(hsubmenu, MF_STRING, MENU_FILE_EXIT, "E&xit");
|
||||
AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&File");
|
||||
|
||||
hsubmenu = CreatePopupMenu();
|
||||
|
||||
hbranchmenu = CreatePopupMenu();
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_256x224w, "256x224 Windowed");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_512x448w, "512x448 Windowed");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_640x480f, "640x480 Fullscreen");
|
||||
AppendMenu(hsubmenu, MF_STRING | MF_POPUP, (unsigned int)hbranchmenu, "&Video Mode");
|
||||
|
||||
hbranchmenu = CreatePopupMenu();
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_OFF, "Off");
|
||||
AppendMenu(hbranchmenu, MF_SEPARATOR, 0, "");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_1, "1");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_2, "2");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_3, "3");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_4, "4");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_5, "5");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_6, "6");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_7, "7");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_8, "8");
|
||||
AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_FRAMESKIP_9, "9");
|
||||
AppendMenu(hsubmenu, MF_STRING | MF_POPUP, (unsigned int)hbranchmenu, "&Frameskip");
|
||||
|
||||
AppendMenu(hsubmenu, MF_SEPARATOR, 0, "");
|
||||
AppendMenu(hsubmenu, MF_STRING | (debug_get_state() == DEBUGMODE_WAIT)?MF_CHECKED:MF_UNCHECKED, MENU_SETTINGS_DEBUGGER, "&Debug Mode");
|
||||
AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Settings");
|
||||
|
||||
hsubmenu = CreatePopupMenu();
|
||||
AppendMenu(hsubmenu, MF_STRING, MENU_HELP_ABOUT, "&About");
|
||||
AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Help");
|
||||
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_512x448w, MF_CHECKED);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_FRAMESKIP_OFF + render.frame_skip, MF_CHECKED);
|
||||
}
|
||||
|
||||
void CreateMainWindow(void) {
|
||||
hwndMain = CreateWindow("bsnes", BSNES_TITLE, WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
||||
0, 0, 640, 480, 0, 0, GetModuleHandle(0), 0);
|
||||
CreateMainMenu();
|
||||
}
|
||||
|
||||
void SetMainWindowPos(bool update_style) {
|
||||
if(render.fullscreen == true) {
|
||||
if(update_style == true) {
|
||||
SetWindowLong(hwndMain, GWL_STYLE, WS_POPUP);
|
||||
SetWindowLong(hwndMain, GWL_EXSTYLE, WS_EX_TOPMOST);
|
||||
SetWindowPos(hwndMain, HWND_TOPMOST, 0, 0, 640, 480, 0);
|
||||
}
|
||||
if(render.show_menu == true) {
|
||||
ShowCursor(TRUE);
|
||||
} else {
|
||||
ShowCursor(FALSE);
|
||||
}
|
||||
} else {
|
||||
if(update_style == true) {
|
||||
SetWindowLong(hwndMain, GWL_STYLE, WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
|
||||
SetWindowLong(hwndMain, GWL_EXSTYLE, 0);
|
||||
}
|
||||
FixWindowSize(hwndMain, render.display_width, render.display_height);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateMainWindowStyle(bool update_style) {
|
||||
if(render.fullscreen == false) {
|
||||
ShowWindow(hwndMain, SW_HIDE);
|
||||
}
|
||||
|
||||
if(render.show_menu == true) {
|
||||
SetMenu(hwndMain, hmenuMain);
|
||||
SetMainWindowPos(update_style);
|
||||
} else {
|
||||
SetMenu(hwndMain, 0);
|
||||
SetMainWindowPos(update_style);
|
||||
}
|
||||
|
||||
if(render.fullscreen == false) {
|
||||
ShowWindow(hwndMain, SW_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
HWND NewWindow(WNDPROC wndproc, char *classname, char *title, ulong color, ulong width, ulong height) {
|
||||
WNDCLASS wc;
|
||||
HWND hwnd;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = (color == null)?(HBRUSH)(COLOR_WINDOW):black_brush;
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = wndproc;
|
||||
wc.lpszClassName = classname;
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
|
||||
hwnd = CreateWindow(classname, title, WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
||||
0, 0, width, height, 0, 0, wc.hInstance, 0);
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
#include "render.cpp"
|
||||
|
||||
bool GUIOpenFile(char *fn) {
|
||||
OPENFILENAME ofn;
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwndMain;
|
||||
ofn.lpstrFilter = "SNES ROM Images (*.smc;*.swc;*.fig;*.ufo;*.gd3;*.078)\0*.smc;*.swc;*.fig;*.ufo;*.gd3;*.078\0All Files (*.*)\0*.*\0";
|
||||
ofn.lpstrFile = fn;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
|
||||
ofn.lpstrDefExt = "smc";
|
||||
|
||||
if(GetOpenFileName(&ofn)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void EnableDebugger(byte first_time);
|
||||
void DisableDebugger(void);
|
||||
|
||||
long __stdcall wndprocMain(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
char fn[MAX_PATH];
|
||||
bool result;
|
||||
switch(msg) {
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
DrawScene();
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
switch(wparam) {
|
||||
case VK_ESCAPE:
|
||||
if(render.show_menu == true) {
|
||||
render.show_menu = false;
|
||||
} else {
|
||||
render.show_menu = true;
|
||||
}
|
||||
UpdateMainWindowStyle(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch(LOWORD(wparam)) {
|
||||
case MENU_FILE_LOAD:
|
||||
strcpy(fn, "");
|
||||
result = GUIOpenFile(fn);
|
||||
if(result == true) {
|
||||
emu_state.rom_loaded = true;
|
||||
strcpy(emu_state.rom_name, fn);
|
||||
fn[strlen(fn) - 4] = 0;
|
||||
strcat(fn, ".srm");
|
||||
strcpy(emu_state.sram_name, fn);
|
||||
gx816->PowerOn(0);
|
||||
gx816->LoadROM();
|
||||
ResetSNES();
|
||||
if(debugger_enabled() == true) {
|
||||
debug_set_state(DEBUGMODE_WAIT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MENU_FILE_RESET:
|
||||
ResetSNES();
|
||||
break;
|
||||
case MENU_FILE_EXIT:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case MENU_SETTINGS_VIDEOMODE_256x224w:
|
||||
video_setmode(false, 256, 224);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_256x224w, MF_CHECKED);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_512x448w, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_640x480f, MF_UNCHECKED);
|
||||
break;
|
||||
case MENU_SETTINGS_VIDEOMODE_512x448w:
|
||||
video_setmode(false, 512, 448);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_256x224w, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_512x448w, MF_CHECKED);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_640x480f, MF_UNCHECKED);
|
||||
break;
|
||||
case MENU_SETTINGS_VIDEOMODE_640x480f:
|
||||
video_setmode(true, 512, 448);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_256x224w, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_512x448w, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_VIDEOMODE_640x480f, MF_CHECKED);
|
||||
break;
|
||||
case MENU_SETTINGS_FRAMESKIP_OFF:
|
||||
case MENU_SETTINGS_FRAMESKIP_1:
|
||||
case MENU_SETTINGS_FRAMESKIP_2:
|
||||
case MENU_SETTINGS_FRAMESKIP_3:
|
||||
case MENU_SETTINGS_FRAMESKIP_4:
|
||||
case MENU_SETTINGS_FRAMESKIP_5:
|
||||
case MENU_SETTINGS_FRAMESKIP_6:
|
||||
case MENU_SETTINGS_FRAMESKIP_7:
|
||||
case MENU_SETTINGS_FRAMESKIP_8:
|
||||
case MENU_SETTINGS_FRAMESKIP_9:
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_FRAMESKIP_OFF + render.frame_skip, MF_UNCHECKED);
|
||||
render.frame_skip = LOWORD(wparam) - MENU_SETTINGS_FRAMESKIP_OFF;
|
||||
render.frame_count = 0;
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_FRAMESKIP_OFF + render.frame_skip, MF_CHECKED);
|
||||
break;
|
||||
case MENU_SETTINGS_DEBUGGER:
|
||||
if(debugger_enabled() == false) {
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_DEBUGGER, MF_CHECKED);
|
||||
EnableDebugger(0);
|
||||
} else {
|
||||
CheckMenuItem(hmenuMain, MENU_SETTINGS_DEBUGGER, MF_UNCHECKED);
|
||||
DisableDebugger();
|
||||
}
|
||||
break;
|
||||
case MENU_HELP_ABOUT:
|
||||
MessageBox(hwndMain, "bsnes -- written by byuu", "About", MB_OK);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
void CreateFonts(void) {
|
||||
HDC hdc;
|
||||
long height;
|
||||
hdc = GetDC(0);
|
||||
height = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
||||
ReleaseDC(0, hdc);
|
||||
hFontFixed = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New");
|
||||
|
||||
hdc = GetDC(0);
|
||||
height = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
||||
ReleaseDC(0, hdc);
|
||||
hFont = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Tahoma");
|
||||
}
|
||||
|
||||
#include "gui_cpu.cpp"
|
||||
#include "gui_mem.cpp"
|
||||
#include "gui_bp.cpp"
|
||||
#include "gui_bgtoggle.cpp"
|
||||
|
||||
void EnableDebugger(byte first_time) {
|
||||
debug_set_state(DEBUGMODE_WAIT);
|
||||
|
||||
hwndDCPU = NewWindow(wndprocDCPU, "bsnes_cpu", "console", null, DCPU_WIDTH, DCPU_HEIGHT);
|
||||
CreateDCPU();
|
||||
FixWindowSize(hwndDCPU, DCPU_WIDTH, DCPU_HEIGHT, 0, 1024 - 410);
|
||||
|
||||
hwndDMEM = NewWindow(wndprocDMEM, "bsnes_mem", "memory editor", null, DMEM_WIDTH, DMEM_HEIGHT);
|
||||
CreateDMEM();
|
||||
FixWindowSize(hwndDMEM, DMEM_WIDTH, DMEM_HEIGHT, 386, 321);
|
||||
|
||||
hwndDBP = NewWindow(wndprocDBP, "bsnes_bp", "breakpoint editor", null, DBP_WIDTH, DBP_HEIGHT);
|
||||
CreateDBP();
|
||||
FixWindowSize(hwndDBP, DBP_WIDTH, DBP_HEIGHT, 0, 346);
|
||||
|
||||
hwndDBGToggle = NewWindow(wndprocDBGToggle, "bsnes_bgtoggle", "ppu bg toggle", null, 275, 90);
|
||||
CreateDBGToggle();
|
||||
FixWindowSize(hwndDBGToggle, 275, 90, 0, 231);
|
||||
|
||||
FixWindowSize(hwndMain, 256, 223, 871, 1024 - 410);
|
||||
|
||||
ShowWindow(hwndDCPU, SW_NORMAL);
|
||||
ShowWindow(hwndDMEM, SW_NORMAL);
|
||||
ShowWindow(hwndDBP, SW_NORMAL);
|
||||
ShowWindow(hwndDBGToggle, SW_NORMAL);
|
||||
ShowWindow(hwndMain, SW_NORMAL);
|
||||
|
||||
if(first_time == 0) {
|
||||
debug_refresh_mem();
|
||||
debug_refresh_bp();
|
||||
debug_update_status();
|
||||
dprintf("* Debugger Enabled");
|
||||
UpdateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
void DisableDebugger(void) {
|
||||
debug_set_state(DEBUGMODE_DISABLED);
|
||||
|
||||
DestroyWindow(hwndDCPU);
|
||||
DestroyWindow(hwndDBP);
|
||||
DestroyWindow(hwndDMEM);
|
||||
DestroyWindow(hwndDBGToggle);
|
||||
}
|
||||
|
||||
void __winmain(void) {
|
||||
MSG msg;
|
||||
CreateFonts();
|
||||
black_brush = CreateSolidBrush(RGB(0, 0, 0));
|
||||
RegisterMainWindow();
|
||||
CreateMainWindow();
|
||||
UpdateMainWindowStyle(false);
|
||||
|
||||
if(debug_get_state() == DEBUGMODE_WAIT) {
|
||||
EnableDebugger(1);
|
||||
}
|
||||
video_setmode(render.fullscreen, render.display_width, render.display_height);
|
||||
|
||||
InitDisplay();
|
||||
CreateColorTable();
|
||||
|
||||
InitSNES();
|
||||
|
||||
UpdateDisplay();
|
||||
UpdateDisplay();
|
||||
|
||||
while(1) {
|
||||
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
|
||||
if(msg.message == WM_QUIT)break;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
RunSNES();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
#define DBGTOGGLE_BG1ENABLE 100
|
||||
#define DBGTOGGLE_BG1ENABLE0 101
|
||||
#define DBGTOGGLE_BG1ENABLE1 102
|
||||
#define DBGTOGGLE_BG2ENABLE 103
|
||||
#define DBGTOGGLE_BG2ENABLE0 104
|
||||
#define DBGTOGGLE_BG2ENABLE1 105
|
||||
#define DBGTOGGLE_BG3ENABLE 106
|
||||
#define DBGTOGGLE_BG3ENABLE0 107
|
||||
#define DBGTOGGLE_BG3ENABLE1 108
|
||||
#define DBGTOGGLE_BG4ENABLE 109
|
||||
#define DBGTOGGLE_BG4ENABLE0 110
|
||||
#define DBGTOGGLE_BG4ENABLE1 111
|
||||
#define DBGTOGGLE_OAMENABLE 112
|
||||
#define DBGTOGGLE_OAMENABLE0 113
|
||||
#define DBGTOGGLE_OAMENABLE1 114
|
||||
#define DBGTOGGLE_OAMENABLE2 115
|
||||
#define DBGTOGGLE_OAMENABLE3 116
|
||||
|
||||
#define BGTOGGLE_CLICK(src, val) \
|
||||
case src: \
|
||||
state = SendDlgItemMessage(hwndDBGToggle, src, BM_GETCHECK, 0, 0); \
|
||||
if(state == 0) { \
|
||||
val = true; \
|
||||
SendDlgItemMessage(hwndDBGToggle, src, BM_SETCHECK, 1, 0); \
|
||||
} else { \
|
||||
val = false; \
|
||||
SendDlgItemMessage(hwndDBGToggle, src, BM_SETCHECK, 0, 0); \
|
||||
} \
|
||||
break
|
||||
|
||||
HWND hwndDBGToggle;
|
||||
|
||||
long __stdcall wndprocDBGToggle(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
int state;
|
||||
if(msg == WM_DESTROY || msg == WM_CLOSE)return 0;
|
||||
if(msg == WM_COMMAND) {
|
||||
if(HIWORD(wparam) == BN_CLICKED) {
|
||||
switch(LOWORD(wparam)) {
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG1ENABLE, render.bg1_enabled[DEBUG_BGENABLED_ALL ]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG1ENABLE0, render.bg1_enabled[DEBUG_BGENABLED_PRI0]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG1ENABLE1, render.bg1_enabled[DEBUG_BGENABLED_PRI1]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG2ENABLE, render.bg2_enabled[DEBUG_BGENABLED_ALL ]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG2ENABLE0, render.bg2_enabled[DEBUG_BGENABLED_PRI0]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG2ENABLE1, render.bg2_enabled[DEBUG_BGENABLED_PRI1]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG3ENABLE, render.bg3_enabled[DEBUG_BGENABLED_ALL ]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG3ENABLE0, render.bg3_enabled[DEBUG_BGENABLED_PRI0]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG3ENABLE1, render.bg3_enabled[DEBUG_BGENABLED_PRI1]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG4ENABLE, render.bg4_enabled[DEBUG_BGENABLED_ALL ]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG4ENABLE0, render.bg4_enabled[DEBUG_BGENABLED_PRI0]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_BG4ENABLE1, render.bg4_enabled[DEBUG_BGENABLED_PRI1]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE, render.oam_enabled[DEBUG_BGENABLED_ALL ]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE0, render.oam_enabled[DEBUG_BGENABLED_PRI0]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE1, render.oam_enabled[DEBUG_BGENABLED_PRI1]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE2, render.oam_enabled[DEBUG_BGENABLED_PRI2]);
|
||||
BGTOGGLE_CLICK(DBGTOGGLE_OAMENABLE3, render.oam_enabled[DEBUG_BGENABLED_PRI3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
void CreateDBGToggle(void) {
|
||||
int x, y, wl, wr, h;
|
||||
x = 5;
|
||||
y = 5;
|
||||
wl = 90;
|
||||
wr = 45;
|
||||
h = 16;
|
||||
CreateWindow("BUTTON", "Enable BG1", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG1ENABLE, GetModuleHandle(0), 0);
|
||||
x += wl;
|
||||
CreateWindow("BUTTON", "Pri 0", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG1ENABLE0, GetModuleHandle(0), 0);
|
||||
x += wr;
|
||||
CreateWindow("BUTTON", "Pri 1", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG1ENABLE1, GetModuleHandle(0), 0);
|
||||
|
||||
x = 5;
|
||||
y += h;
|
||||
CreateWindow("BUTTON", "Enable BG2", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG2ENABLE, GetModuleHandle(0), 0);
|
||||
x += wl;
|
||||
CreateWindow("BUTTON", "Pri 0", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG2ENABLE0, GetModuleHandle(0), 0);
|
||||
x += wr;
|
||||
CreateWindow("BUTTON", "Pri 1", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG2ENABLE1, GetModuleHandle(0), 0);
|
||||
|
||||
x = 5;
|
||||
y += h;
|
||||
CreateWindow("BUTTON", "Enable BG3", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG3ENABLE, GetModuleHandle(0), 0);
|
||||
x += wl;
|
||||
CreateWindow("BUTTON", "Pri 0", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG3ENABLE0, GetModuleHandle(0), 0);
|
||||
x += wr;
|
||||
CreateWindow("BUTTON", "Pri 1", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG3ENABLE1, GetModuleHandle(0), 0);
|
||||
|
||||
x = 5;
|
||||
y += h;
|
||||
CreateWindow("BUTTON", "Enable BG4", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG4ENABLE, GetModuleHandle(0), 0);
|
||||
x += wl;
|
||||
CreateWindow("BUTTON", "Pri 0", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG4ENABLE0, GetModuleHandle(0), 0);
|
||||
x += wr;
|
||||
CreateWindow("BUTTON", "Pri 1", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_BG4ENABLE1, GetModuleHandle(0), 0);
|
||||
|
||||
x = 5;
|
||||
y += h;
|
||||
CreateWindow("BUTTON", "Enable OAM", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wl, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE, GetModuleHandle(0), 0);
|
||||
x += wl;
|
||||
CreateWindow("BUTTON", "Pri 0", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE0, GetModuleHandle(0), 0);
|
||||
x += wr;
|
||||
CreateWindow("BUTTON", "Pri 1", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE1, GetModuleHandle(0), 0);
|
||||
x += wr;
|
||||
CreateWindow("BUTTON", "Pri 2", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE2, GetModuleHandle(0), 0);
|
||||
x += wr;
|
||||
CreateWindow("BUTTON", "Pri 3", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, x, y, wr, h,
|
||||
hwndDBGToggle, (HMENU)DBGTOGGLE_OAMENABLE3, GetModuleHandle(0), 0);
|
||||
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG1ENABLE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG1ENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG1ENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG2ENABLE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG2ENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG2ENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG3ENABLE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG3ENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG3ENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG4ENABLE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG4ENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_BG4ENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE0, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE1, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE2, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBGToggle, DBGTOGGLE_OAMENABLE3, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
|
||||
for(int i=DBGTOGGLE_BG1ENABLE;i<=DBGTOGGLE_OAMENABLE3;i++) {
|
||||
SendDlgItemMessage(hwndDBGToggle, i, BM_SETCHECK, 1, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
#define DBP_WIDTH 380
|
||||
#define DBP_HEIGHT 243
|
||||
|
||||
#define DBP_LIST 100
|
||||
#define DBP_ADDBP 101
|
||||
#define DBP_REMBP 102
|
||||
#define DBP_CLRBP 103
|
||||
#define DBP_STATIC1 104
|
||||
#define DBP_BPNUM 105
|
||||
#define DBP_BPOFFSET 106
|
||||
#define DBP_BPR 107
|
||||
#define DBP_BPW 108
|
||||
#define DBP_BPX 109
|
||||
#define DBP_BPV 110
|
||||
#define DBP_BPVAL 111
|
||||
#define DBP_STATIC2 112
|
||||
#define DBP_SRCMEM 113
|
||||
#define DBP_SRCVRAM 114
|
||||
#define DBP_SRCCGRAM 115
|
||||
#define DBP_SRCOAM 116
|
||||
#define DBP_SRCSPCRAM 117
|
||||
#define DBP_SRCMODE 118
|
||||
|
||||
HWND hwndDBP;
|
||||
byte debug_bp_src;
|
||||
|
||||
void debug_refresh_bp(void) {
|
||||
char str[128*16], t[128];
|
||||
if(debugger_enabled() == false)return;
|
||||
|
||||
strcpy(str, "");
|
||||
for(int i=0;i<16;i++) {
|
||||
sprintf(t, "%0.2d: ", i);
|
||||
strcat(str, t);
|
||||
if(debugger.bp_list[i].flags == BP_OFF) {
|
||||
strcat(str, "------ ---- -- ------ (Disabled)");
|
||||
} else {
|
||||
sprintf(t, "%0.6x %c%c%c%c ", debugger.bp_list[i].offset,
|
||||
(debugger.bp_list[i].flags & BP_READ )?'R':'r',
|
||||
(debugger.bp_list[i].flags & BP_WRITE)?'W':'w',
|
||||
(debugger.bp_list[i].flags & BP_EXEC )?'X':'x',
|
||||
(debugger.bp_list[i].flags & BP_VAL )?'V':'v');
|
||||
strcat(str, t);
|
||||
if(debugger.bp_list[i].flags & BP_VAL) {
|
||||
sprintf(t, "%0.2x ", debugger.bp_list[i].value);
|
||||
strcat(str, t);
|
||||
} else strcat(str, "-- ");
|
||||
|
||||
switch(debugger.bp_list[i].source) {
|
||||
case BPSRC_MEM: strcat(str, "DRAM ");break;
|
||||
case BPSRC_VRAM: strcat(str, "VRAM ");break;
|
||||
case BPSRC_CGRAM: strcat(str, "CGRAM ");break;
|
||||
case BPSRC_OAM: strcat(str, "OAM ");break;
|
||||
case BPSRC_SPCRAM:strcat(str, "SPCRAM ");break;
|
||||
}
|
||||
|
||||
sprintf(t, "%10d", debugger.bp_list[i].hit_count);
|
||||
strcat(str, t);
|
||||
}
|
||||
if(i != 15)strcat(str, "\r\n");
|
||||
}
|
||||
|
||||
SetDlgItemText(hwndDBP, DBP_LIST, str);
|
||||
}
|
||||
|
||||
long __stdcall wndprocDBP(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
char str[256];
|
||||
ulong num, offset, val, flags;
|
||||
int i, pos;
|
||||
if(msg == WM_DESTROY || msg == WM_CLOSE)return 0; //don't allow debugger to be closed (yet)
|
||||
|
||||
if(msg == WM_COMMAND) {
|
||||
switch(LOWORD(wparam)) {
|
||||
case DBP_BPNUM:
|
||||
if(HIWORD(wparam) == CBN_SELCHANGE) {
|
||||
num = SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_GETCURSEL, 0, 0);
|
||||
sprintf(str, "%0.6x", debugger.bp_list[num].offset);
|
||||
SetDlgItemText(hwndDBP, DBP_BPOFFSET, str);
|
||||
sprintf(str, "%0.2x", debugger.bp_list[num].value);
|
||||
SetDlgItemText(hwndDBP, DBP_BPVAL, str);
|
||||
switch(debugger.bp_list[num].source) {
|
||||
case BPSRC_MEM: pos = 0; break;
|
||||
case BPSRC_VRAM: pos = 1; break;
|
||||
case BPSRC_CGRAM: pos = 2; break;
|
||||
case BPSRC_OAM: pos = 3; break;
|
||||
case BPSRC_SPCRAM: pos = 4; break;
|
||||
}
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMODE, CB_SETCURSEL, (WPARAM)pos, 0);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPR, BM_SETCHECK, (debugger.bp_list[num].flags & BP_READ )?1:0, 0);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPW, BM_SETCHECK, (debugger.bp_list[num].flags & BP_WRITE)?1:0, 0);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPX, BM_SETCHECK, (debugger.bp_list[num].flags & BP_EXEC )?1:0, 0);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPV, BM_SETCHECK, (debugger.bp_list[num].flags & BP_VAL )?1:0, 0);
|
||||
}
|
||||
break;
|
||||
case DBP_ADDBP:
|
||||
num = SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_GETCURSEL, 0, 0);
|
||||
GetDlgItemText(hwndDBP, DBP_BPOFFSET, str, 255);
|
||||
offset = strhex(str) & 0xffffff;
|
||||
GetDlgItemText(hwndDBP, DBP_BPVAL, str, 255);
|
||||
val = strhex(str);
|
||||
|
||||
flags = 0;
|
||||
if(SendDlgItemMessage(hwndDBP, DBP_BPR, BM_GETCHECK, 0, 0))flags |= BP_READ;
|
||||
if(SendDlgItemMessage(hwndDBP, DBP_BPW, BM_GETCHECK, 0, 0))flags |= BP_WRITE;
|
||||
if(SendDlgItemMessage(hwndDBP, DBP_BPX, BM_GETCHECK, 0, 0))flags |= BP_EXEC;
|
||||
if(SendDlgItemMessage(hwndDBP, DBP_BPV, BM_GETCHECK, 0, 0))flags |= BP_VAL;
|
||||
|
||||
debugger.bp_list[num].offset = offset;
|
||||
debugger.bp_list[num].flags = flags;
|
||||
debugger.bp_list[num].source = debug_bp_src;
|
||||
if(debugger.bp_list[num].flags & BP_VAL) {
|
||||
debugger.bp_list[num].value = val;
|
||||
} else {
|
||||
debugger.bp_list[num].value = 0;
|
||||
}
|
||||
debugger.bp_list[num].hit_count = 0;
|
||||
debugger.refresh_bp = true;
|
||||
break;
|
||||
case DBP_REMBP:
|
||||
num = SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_GETCURSEL, 0, 0);
|
||||
debugger.bp_list[num].offset = 0;
|
||||
debugger.bp_list[num].flags = BP_OFF;
|
||||
debugger.bp_list[num].source = BPSRC_MEM;
|
||||
debugger.bp_list[num].value = 0;
|
||||
debugger.bp_list[num].hit_count = 0;
|
||||
debugger.refresh_bp = true;
|
||||
break;
|
||||
case DBP_CLRBP:
|
||||
for(i=0;i<16;i++) {
|
||||
debugger.bp_list[i].offset = 0;
|
||||
debugger.bp_list[i].flags = BP_OFF;
|
||||
debugger.bp_list[i].source = BPSRC_MEM;
|
||||
debugger.bp_list[i].value = 0;
|
||||
debugger.bp_list[i].hit_count = 0;
|
||||
}
|
||||
debugger.refresh_bp = true;
|
||||
break;
|
||||
case DBP_SRCMODE:
|
||||
if(HIWORD(wparam) == CBN_SELCHANGE) {
|
||||
pos = SendDlgItemMessage(hwndDBP, DBP_SRCMODE, CB_GETCURSEL, 0, 0);
|
||||
if(pos == 0) {
|
||||
debug_bp_src = BPSRC_MEM;
|
||||
} else if(pos == 1) {
|
||||
debug_bp_src = BPSRC_VRAM;
|
||||
} else if(pos == 2) {
|
||||
debug_bp_src = BPSRC_CGRAM;
|
||||
} else if(pos == 3) {
|
||||
debug_bp_src = BPSRC_OAM;
|
||||
} else if(pos == 4) {
|
||||
debug_bp_src = BPSRC_SPCRAM;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
void CreateDBP(void) {
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
|
||||
WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_READONLY,
|
||||
5, 5, 260, 233, hwndDBP, (HMENU)DBP_LIST, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindow("STATIC", "BP #: Offset:", WS_CHILD|WS_VISIBLE, 270, 5, 90, 15, hwndDBP, (HMENU)DBP_STATIC1, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindow("COMBOBOX", "",
|
||||
WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST|CBS_HASSTRINGS,
|
||||
270, 20, 45, 300, hwndDBP, (HMENU)DBP_BPNUM, GetModuleHandle(0), 0);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"00");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"01");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"02");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"03");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"04");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"05");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"06");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"07");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"08");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"09");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"10");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"11");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"12");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"13");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"14");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_ADDSTRING, 0, (LPARAM)"15");
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, CB_SETCURSEL, 0, 0);
|
||||
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "000000", WS_CHILD|WS_VISIBLE, 315, 20, 60, 23, hwndDBP, (HMENU)DBP_BPOFFSET, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "R", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, 270, 44, 30, 18, hwndDBP, (HMENU)DBP_BPR, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "W", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, 300, 44, 30, 18, hwndDBP, (HMENU)DBP_BPW, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "X", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, 330, 44, 30, 18, hwndDBP, (HMENU)DBP_BPX, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "V", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, 270, 65, 30, 18, hwndDBP, (HMENU)DBP_BPV, GetModuleHandle(0), 0);
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "00", WS_CHILD|WS_VISIBLE, 300, 62, 30, 23, hwndDBP, (HMENU)DBP_BPVAL, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindow("STATIC", "Source:", WS_CHILD|WS_VISIBLE, 270, 85, 90, 15, hwndDBP, (HMENU)DBP_STATIC2, GetModuleHandle(0), 0);
|
||||
CreateWindow("COMBOBOX", "",
|
||||
WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST|CBS_HASSTRINGS,
|
||||
270, 100, 105, 200, hwndDBP, (HMENU)DBP_SRCMODE, GetModuleHandle(0), 0);
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMODE, CB_ADDSTRING, 0, (LPARAM)"DRAM");
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMODE, CB_ADDSTRING, 0, (LPARAM)"VRAM");
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMODE, CB_ADDSTRING, 0, (LPARAM)"CGRAM");
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMODE, CB_ADDSTRING, 0, (LPARAM)"OAM");
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMODE, CB_ADDSTRING, 0, (LPARAM)"SPCRAM");
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMODE, CB_SETCURSEL, 0, 0);
|
||||
|
||||
CreateWindow("BUTTON", "Set BP", WS_CHILD|WS_VISIBLE, 270, 125, 105, 20, hwndDBP, (HMENU)DBP_ADDBP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Clear BP", WS_CHILD|WS_VISIBLE, 270, 145, 105, 20, hwndDBP, (HMENU)DBP_REMBP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Clear All BPs", WS_CHILD|WS_VISIBLE, 270, 165, 105, 20, hwndDBP, (HMENU)DBP_CLRBP, GetModuleHandle(0), 0);
|
||||
|
||||
SendDlgItemMessage(hwndDBP, DBP_LIST, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_STATIC1, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPNUM, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPOFFSET, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPR, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPW, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPX, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPV, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_BPVAL, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMODE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_STATIC2, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_ADDBP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_REMBP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDBP, DBP_CLRBP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
|
||||
SendDlgItemMessage(hwndDBP, DBP_SRCMEM, BM_SETCHECK, 1, 0);
|
||||
debug_bp_src = BPSRC_MEM;
|
||||
}
|
||||
@@ -1,409 +0,0 @@
|
||||
#define DCPU_WIDTH 865
|
||||
#define DCPU_HEIGHT 385
|
||||
|
||||
enum {
|
||||
DCPU_DISAS = 100,
|
||||
DCPU_CPUGROUP,
|
||||
DCPU_CPUSTEP,
|
||||
DCPU_CPUPROCEED,
|
||||
DCPU_CPUSKIP,
|
||||
DCPU_CPUTRACENUM,
|
||||
DCPU_CPUTRACE,
|
||||
DCPU_CPUDISABLE,
|
||||
DCPU_APUGROUP,
|
||||
DCPU_APUSTEP,
|
||||
DCPU_APUPROCEED,
|
||||
DCPU_APUSKIP,
|
||||
DCPU_APUTRACENUM,
|
||||
DCPU_APUTRACE,
|
||||
DCPU_APUDISABLE,
|
||||
DCPU_SYSGROUP,
|
||||
DCPU_SYSRUN,
|
||||
DCPU_SYSRUNTOFRAME,
|
||||
DCPU_SYSRUNTOVBLANK,
|
||||
DCPU_SYSRUNTONMI,
|
||||
DCPU_SYSRUNTOIRQ,
|
||||
DCPU_SYSRUNTOINT,
|
||||
DCPU_CFGGROUP,
|
||||
DCPU_CFGCPUOUT,
|
||||
DCPU_CFGAPUOUT,
|
||||
DCPU_CFGDBGOUT,
|
||||
DCPU_CFGTRACE,
|
||||
DCPU_CFGTRACEPRINT,
|
||||
DCPU_CFGREGTYPE,
|
||||
DCPU_CFGREGNUM,
|
||||
DCPU_CFGREGVAL,
|
||||
DCPU_CFGREGSET,
|
||||
DCPU_CFGLOCK,
|
||||
DCPU_CFGLOCKUP,
|
||||
DCPU_CFGLOCKDOWN,
|
||||
DCPU_CFGLOCKLEFT,
|
||||
DCPU_CFGLOCKRIGHT,
|
||||
DCPU_CFGLOCKA,
|
||||
DCPU_CFGLOCKB,
|
||||
DCPU_CFGLOCKX,
|
||||
DCPU_CFGLOCKY,
|
||||
DCPU_CFGLOCKL,
|
||||
DCPU_CFGLOCKR,
|
||||
DCPU_CFGLOCKSELECT,
|
||||
DCPU_CFGLOCKSTART,
|
||||
DCPU_STATUS
|
||||
};
|
||||
|
||||
HWND hwndDCPU;
|
||||
#define DEBUG_CONSOLE_LINES 250
|
||||
char dcpu_disas_mem[DEBUG_CONSOLE_LINES][256];
|
||||
|
||||
void debug_update_console(void) {
|
||||
int i;
|
||||
char str[256 * DEBUG_CONSOLE_LINES];
|
||||
if(debug_write_status() == DEBUGWRITE_NONE)return;
|
||||
|
||||
strcpy(str, "");
|
||||
for(i=0;i<DEBUG_CONSOLE_LINES;i++) {
|
||||
strcat(str, dcpu_disas_mem[i]);
|
||||
if(i != DEBUG_CONSOLE_LINES-1)strcat(str, "\r\n");
|
||||
}
|
||||
|
||||
SetDlgItemText(hwndDCPU, DCPU_DISAS, str);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_DISAS, EM_SETSEL, 0, -1);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_DISAS, EM_SCROLLCARET, 0, 0);
|
||||
}
|
||||
|
||||
void debug_update_status(void) {
|
||||
char str[4096];
|
||||
if(!(debug_write_status() & DEBUGWRITE_CONSOLE))return;
|
||||
|
||||
sprintf(str,
|
||||
"Scanline: %3d, HCycle Pos: %4d, HDot Pos: %3d, Master Cycle Pos: %10d\r\n"
|
||||
"NMI: %s, VIRQ: %s, HIRQ: %s, VIRQ Pos: %3d, HIRQ Pos: %3d\r\n"
|
||||
"CPU Status: { PC:%0.6x A:%0.4x X:%0.4x Y:%0.4x S:%0.4x D:%0.4x DB:%0.2x }\r\n"
|
||||
"APU Status: { PC:%0.4x A:%0.2x X:%0.2x Y:%0.2x SP:%0.2x YA:%0.4x }",
|
||||
snes_time->vscan_pos, snes_time->hcycle_pos, snes_time->hscan_pos, snes_time->master_cycles,
|
||||
(gx816->nmi_enabled == true)?" Enabled":"Disabled",
|
||||
(ppu.vcounter_enabled == true)?" Enabled":"Disabled",
|
||||
(ppu.hcounter_enabled == true)?" Enabled":"Disabled",
|
||||
ppu.virq_pos, ppu.hirq_pos,
|
||||
gx816->regs.pc, gx816->regs.a.w, gx816->regs.x, gx816->regs.y,
|
||||
gx816->regs.s, gx816->regs.d, gx816->regs.db,
|
||||
spc700->regs.pc, spc700->regs.a, spc700->regs.x, spc700->regs.y,
|
||||
spc700->regs.sp, (spc700->regs.y << 8) | spc700->regs.a);
|
||||
SetDlgItemText(hwndDCPU, DCPU_STATUS, str);
|
||||
}
|
||||
|
||||
void debug_write(ulong msg_type, char *s) {
|
||||
int i;
|
||||
if(debugger_enabled() == false)return;
|
||||
|
||||
switch(msg_type) {
|
||||
case DEBUGMSG_INFO:
|
||||
if(debugger.output_debug_info == false)return;
|
||||
break;
|
||||
case DEBUGMSG_CPU:
|
||||
if(debugger.output_cpu_instrs == false)return;
|
||||
break;
|
||||
case DEBUGMSG_APU:
|
||||
if(debugger.output_apu_instrs == false)return;
|
||||
break;
|
||||
}
|
||||
|
||||
if(debugger.trace_enabled == true) {
|
||||
fprintf(debugger.trace_fp, "%s\r\n", s);
|
||||
}
|
||||
|
||||
if(debug_write_status() & DEBUGWRITE_CONSOLE) {
|
||||
for(i=0;i<DEBUG_CONSOLE_LINES-1;i++)strcpy(dcpu_disas_mem[i], dcpu_disas_mem[i+1]);
|
||||
strcpy(dcpu_disas_mem[DEBUG_CONSOLE_LINES - 1], s);
|
||||
debug_update_console();
|
||||
}
|
||||
}
|
||||
|
||||
void dprintf(char *s, ...) {
|
||||
char str[4096];
|
||||
va_list args;
|
||||
int i;
|
||||
if(debugger_enabled() == false)return;
|
||||
|
||||
va_start(args, s);
|
||||
vsprintf(str, s, args);
|
||||
va_end(args);
|
||||
|
||||
debug_write(DEBUGMSG_INFO, str);
|
||||
}
|
||||
|
||||
void dprintf(ulong msg_type, char *s, ...) {
|
||||
char str[4096];
|
||||
va_list args;
|
||||
int i;
|
||||
if(debugger_enabled() == false)return;
|
||||
|
||||
va_start(args, s);
|
||||
vsprintf(str, s, args);
|
||||
va_end(args);
|
||||
|
||||
debug_write(msg_type, str);
|
||||
}
|
||||
|
||||
void debug_set_state(byte state) {
|
||||
debugger.mode = state;
|
||||
if(hwndDCPU && state != DEBUGMODE_DISABLED) {
|
||||
if(state == DEBUGMODE_WAIT) {
|
||||
SetDlgItemText(hwndDCPU, DCPU_SYSRUN, "Run");
|
||||
} else if(state == DEBUGMODE_RUN) {
|
||||
SetDlgItemText(hwndDCPU, DCPU_SYSRUN, "Stop");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long __stdcall wndprocDCPU(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
FILE *fp;
|
||||
int state;
|
||||
if(msg == WM_DESTROY || msg == WM_CLOSE)return 0; //don't allow debugger to be closed (yet)
|
||||
|
||||
if(msg == WM_COMMAND) {
|
||||
switch(LOWORD(wparam)) {
|
||||
case DCPU_SYSRUN:
|
||||
if(debug_get_state() == DEBUGMODE_WAIT) {
|
||||
debug_set_state(DEBUGMODE_RUN);
|
||||
} else if(debug_get_state() == DEBUGMODE_RUN) {
|
||||
debug_set_state(DEBUGMODE_WAIT);
|
||||
debug_update_console();
|
||||
debug_update_status();
|
||||
}
|
||||
break;
|
||||
case DCPU_CPUSTEP:
|
||||
if(debug_get_state() == DEBUGMODE_WAIT) {
|
||||
debug_set_state(DEBUGMODE_CPUSTEP);
|
||||
}
|
||||
debugger.cpu_op_executed = false;
|
||||
break;
|
||||
case DCPU_APUSTEP:
|
||||
if(debug_get_state() == DEBUGMODE_WAIT) {
|
||||
debug_set_state(DEBUGMODE_APUSTEP);
|
||||
}
|
||||
debugger.apu_op_executed = false;
|
||||
break;
|
||||
case DCPU_CFGCPUOUT:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGCPUOUT, BM_GETCHECK, 0, 0);
|
||||
debugger.output_cpu_instrs = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGAPUOUT:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGAPUOUT, BM_GETCHECK, 0, 0);
|
||||
debugger.output_apu_instrs = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGDBGOUT:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGDBGOUT, BM_GETCHECK, 0, 0);
|
||||
debugger.output_debug_info = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGTRACE:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGTRACE, BM_GETCHECK, 0, 0);
|
||||
if(state == 0) {
|
||||
fclose(debugger.trace_fp);
|
||||
debugger.trace_enabled = false;
|
||||
} else {
|
||||
debugger.trace_fp = fopen("trace.log", "wb");
|
||||
debugger.trace_enabled = true;
|
||||
}
|
||||
break;
|
||||
case DCPU_CFGTRACEPRINT:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGTRACEPRINT, BM_GETCHECK, 0, 0);
|
||||
debugger.trace_output_enabled = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGLOCKUP:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKUP, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_up = (state == 1)?true:false;
|
||||
debugger.lock_down = false;
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKDOWN, BM_SETCHECK, 0, 0);
|
||||
break;
|
||||
case DCPU_CFGLOCKDOWN:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKDOWN, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_down = (state == 1)?true:false;
|
||||
debugger.lock_up = false;
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKUP, BM_SETCHECK, 0, 0);
|
||||
break;
|
||||
case DCPU_CFGLOCKLEFT:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKLEFT, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_left = (state == 1)?true:false;
|
||||
debugger.lock_right = false;
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKRIGHT, BM_SETCHECK, 0, 0);
|
||||
break;
|
||||
case DCPU_CFGLOCKRIGHT:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKRIGHT, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_right = (state == 1)?true:false;
|
||||
debugger.lock_left = false;
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKLEFT, BM_SETCHECK, 0, 0);
|
||||
break;
|
||||
case DCPU_CFGLOCKA:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKA, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_a = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGLOCKB:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKB, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_b = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGLOCKX:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKX, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_x = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGLOCKY:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKY, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_y = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGLOCKL:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKL, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_l = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGLOCKR:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKR, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_r = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGLOCKSELECT:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKSELECT, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_select = (state == 1)?true:false;
|
||||
break;
|
||||
case DCPU_CFGLOCKSTART:
|
||||
state = SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKSTART, BM_GETCHECK, 0, 0);
|
||||
debugger.lock_start = (state == 1)?true:false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
void CreateDCPU(void) {
|
||||
int i;
|
||||
for(i=0;i<20;i++)strcpy(dcpu_disas_mem[i], "");
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
|
||||
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY, 5, 5, 600, 290,
|
||||
hwndDCPU, (HMENU)DCPU_DISAS, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindow("BUTTON", "cpu (wdc 65816)", WS_CHILD|WS_VISIBLE|BS_GROUPBOX, 610, 5, 250, 60, hwndDCPU, (HMENU)DCPU_CPUGROUP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Step", WS_CHILD|WS_VISIBLE, 615, 20, 80, 20, hwndDCPU, (HMENU)DCPU_CPUSTEP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Proceed", WS_CHILD|WS_VISIBLE|WS_DISABLED, 695, 20, 80, 20, hwndDCPU, (HMENU)DCPU_CPUPROCEED, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Skip", WS_CHILD|WS_VISIBLE|WS_DISABLED, 775, 20, 80, 20, hwndDCPU, (HMENU)DCPU_CPUSKIP, GetModuleHandle(0), 0);
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0",
|
||||
WS_CHILD|WS_VISIBLE|ES_RIGHT|WS_DISABLED, 615, 40, 80, 20, hwndDCPU, (HMENU)DCPU_CPUTRACENUM, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Trace", WS_CHILD|WS_VISIBLE|WS_DISABLED, 695, 40, 80, 20, hwndDCPU, (HMENU)DCPU_CPUTRACE, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Disable", WS_CHILD|WS_VISIBLE|WS_DISABLED, 775, 40, 80, 20, hwndDCPU, (HMENU)DCPU_CPUDISABLE, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindow("BUTTON", "apu (sony spc700)", WS_CHILD|WS_VISIBLE|BS_GROUPBOX, 610, 70, 250, 60, hwndDCPU, (HMENU)DCPU_APUGROUP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Step", WS_CHILD|WS_VISIBLE, 615, 85, 80, 20, hwndDCPU, (HMENU)DCPU_APUSTEP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Proceed", WS_CHILD|WS_VISIBLE|WS_DISABLED, 695, 85, 80, 20, hwndDCPU, (HMENU)DCPU_APUPROCEED, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Skip", WS_CHILD|WS_VISIBLE|WS_DISABLED, 775, 85, 80, 20, hwndDCPU, (HMENU)DCPU_APUSKIP, GetModuleHandle(0), 0);
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0",
|
||||
WS_CHILD|WS_VISIBLE|ES_RIGHT|WS_DISABLED, 615, 105, 80, 20, hwndDCPU, (HMENU)DCPU_APUTRACENUM, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Trace", WS_CHILD|WS_VISIBLE|WS_DISABLED, 695, 105, 80, 20, hwndDCPU, (HMENU)DCPU_APUTRACE, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Disable", WS_CHILD|WS_VISIBLE|WS_DISABLED, 775, 105, 80, 20, hwndDCPU, (HMENU)DCPU_APUDISABLE, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindow("BUTTON", "System", WS_CHILD|WS_VISIBLE|BS_GROUPBOX, 610, 135, 250, 60, hwndDCPU, (HMENU)DCPU_SYSGROUP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Run", WS_CHILD|WS_VISIBLE, 615, 150, 80, 20, hwndDCPU, (HMENU)DCPU_SYSRUN, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "To Frame", WS_CHILD|WS_VISIBLE|WS_DISABLED, 695, 150, 80, 20, hwndDCPU, (HMENU)DCPU_SYSRUNTOFRAME, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "To VBlank", WS_CHILD|WS_VISIBLE|WS_DISABLED, 775, 150, 80, 20, hwndDCPU, (HMENU)DCPU_SYSRUNTOVBLANK, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "To NMI", WS_CHILD|WS_VISIBLE|WS_DISABLED, 615, 170, 80, 20, hwndDCPU, (HMENU)DCPU_SYSRUNTONMI, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "To IRQ", WS_CHILD|WS_VISIBLE|WS_DISABLED, 695, 170, 80, 20, hwndDCPU, (HMENU)DCPU_SYSRUNTOIRQ, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "To Interrupt", WS_CHILD|WS_VISIBLE|WS_DISABLED, 775, 170, 80, 20, hwndDCPU, (HMENU)DCPU_SYSRUNTOINT, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindow("BUTTON", "Settings", WS_CHILD|WS_VISIBLE|BS_GROUPBOX, 610, 200, 250, 180, hwndDCPU, (HMENU)DCPU_CFGGROUP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Output CPU instructions to console", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
615, 215, 240, 15, hwndDCPU, (HMENU)DCPU_CFGCPUOUT, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Output APU instructions to console", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
615, 230, 240, 15, hwndDCPU, (HMENU)DCPU_CFGAPUOUT, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Output debug info to console", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
615, 245, 240, 15, hwndDCPU, (HMENU)DCPU_CFGDBGOUT, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Trace output to file (very slow)", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
615, 260, 240, 15, hwndDCPU, (HMENU)DCPU_CFGTRACE, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Print debug info while tracing (very slow)", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
615, 275, 240, 15, hwndDCPU, (HMENU)DCPU_CFGTRACEPRINT, GetModuleHandle(0), 0);
|
||||
CreateWindow("COMBOBOX", "", WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST|CBS_HASSTRINGS|WS_DISABLED,
|
||||
615, 290, 60, 200, hwndDCPU, (HMENU)DCPU_CFGREGTYPE, GetModuleHandle(0), 0);
|
||||
CreateWindow("COMBOBOX", "", WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST|CBS_HASSTRINGS|WS_DISABLED,
|
||||
675, 290, 60, 200, hwndDCPU, (HMENU)DCPU_CFGREGNUM, GetModuleHandle(0), 0);
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "000000", WS_CHILD|WS_VISIBLE|ES_RIGHT|WS_DISABLED,
|
||||
735, 290, 60, 20, hwndDCPU, (HMENU)DCPU_CFGREGVAL, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Set Reg", WS_CHILD|WS_VISIBLE|WS_DISABLED,
|
||||
795, 290, 60, 20, hwndDCPU, (HMENU)DCPU_CFGREGSET, GetModuleHandle(0), 0);
|
||||
CreateWindow("STATIC", "Lock Joypad Buttons Down:", WS_CHILD|WS_VISIBLE, 615, 315, 240, 15, hwndDCPU, (HMENU)DCPU_CFGLOCK, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Up", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
615, 330, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKUP, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Down", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
675, 330, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKDOWN, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Left", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
735, 330, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKLEFT, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Right", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
795, 330, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKRIGHT, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "A", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
615, 345, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKA, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "B", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
675, 345, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKB, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "X", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
735, 345, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKX, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Y", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
795, 345, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKY, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "L", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
615, 360, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKL, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "R", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
675, 360, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKR, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Select", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
735, 360, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKSELECT, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Start", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
|
||||
795, 360, 60, 15, hwndDCPU, (HMENU)DCPU_CFGLOCKSTART, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
|
||||
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY, 5, 300, 600, 80,
|
||||
hwndDCPU, (HMENU)DCPU_STATUS, GetModuleHandle(0), 0);
|
||||
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_DISAS, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CPUGROUP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CPUSTEP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CPUPROCEED, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CPUSKIP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CPUTRACENUM, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CPUTRACE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CPUDISABLE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_APUGROUP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_APUSTEP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_APUPROCEED, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_APUSKIP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_APUTRACENUM, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_APUTRACE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_APUDISABLE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_SYSGROUP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_SYSRUN, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_SYSRUNTOFRAME, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_SYSRUNTOVBLANK, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_SYSRUNTONMI, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_SYSRUNTOIRQ, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_SYSRUNTOINT, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGGROUP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGCPUOUT, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGAPUOUT, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGDBGOUT, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGTRACE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGTRACEPRINT, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGREGTYPE, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGREGNUM, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGREGVAL, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGREGSET, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCK, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKUP, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKDOWN, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKLEFT, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKRIGHT, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKA, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKB, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKX, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKY, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKL, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKR, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKSELECT, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGLOCKSTART, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_STATUS, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGCPUOUT, BM_SETCHECK, (WPARAM)(debugger.output_cpu_instrs == true)?1:0, 0);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGAPUOUT, BM_SETCHECK, (WPARAM)(debugger.output_apu_instrs == true)?1:0, 0);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGDBGOUT, BM_SETCHECK, (WPARAM)(debugger.output_debug_info == true)?1:0, 0);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGTRACE, BM_SETCHECK, (WPARAM)(debugger.trace_enabled == true)?1:0, 0);
|
||||
SendDlgItemMessage(hwndDCPU, DCPU_CFGTRACEPRINT, BM_SETCHECK, (WPARAM)(debugger.trace_output_enabled == true)?1:0, 0);
|
||||
}
|
||||
|
||||
@@ -1,288 +0,0 @@
|
||||
#define DMEM_WIDTH 500
|
||||
#define DMEM_HEIGHT 268
|
||||
|
||||
#define DMEM_VIEW 100
|
||||
#define DMEM_EDITWRAM 101
|
||||
#define DMEM_UP40 102
|
||||
#define DMEM_DOWN40 103
|
||||
#define DMEM_UP400 104
|
||||
#define DMEM_DOWN400 105
|
||||
#define DMEM_UP4000 106
|
||||
#define DMEM_DOWN4000 107
|
||||
#define DMEM_UP40000 108
|
||||
#define DMEM_DOWN40000 109
|
||||
#define DMEM_TOWRAM 110
|
||||
#define DMEM_TOROM 111
|
||||
#define DMEM_TOVRAM 112
|
||||
#define DMEM_TOCGRAM 113
|
||||
#define DMEM_TOSRAM 114
|
||||
#define DMEM_TOSPCRAM 115
|
||||
#define DMEM_TOOAM 116
|
||||
#define DMEM_TOOFFSET 117
|
||||
#define DMEM_EDITLOC 118
|
||||
#define DMEM_EDITVAL 119
|
||||
#define DMEM_STATIC1 120
|
||||
#define DMEM_STATIC2 121
|
||||
#define DMEM_VIEWMODE 122
|
||||
#define DMEM_GOTOADDR 123
|
||||
#define DMEM_GOTO 124
|
||||
|
||||
#define DMEMMODE_WRAM 0
|
||||
#define DMEMMODE_VRAM 1
|
||||
#define DMEMMODE_CGRAM 2
|
||||
#define DMEMMODE_OAM 3
|
||||
#define DMEMMODE_SPCRAM 4
|
||||
ulong dmem_mode = DMEMMODE_WRAM;
|
||||
|
||||
HWND hwndDMEM;
|
||||
|
||||
void debug_refresh_mem(void) {
|
||||
char str[64*16], t[16];
|
||||
ulong ptr;
|
||||
int x, y;
|
||||
if(debugger_enabled() == false)return;
|
||||
|
||||
ptr = debugger.mem_ptr;
|
||||
strcpy(str, "");
|
||||
|
||||
if(dmem_mode == DMEMMODE_WRAM) {
|
||||
ptr &= 0xffffff;
|
||||
for(y=0;y<16;y++) {
|
||||
sprintf(t, "%0.6x: ", ptr);
|
||||
strcat(str, t);
|
||||
for(x=0;x<16;x++) {
|
||||
sprintf(t, "%0.2x", gx816->mem_read(MEMMODE_LONG, MEMSIZE_BYTE, ptr++, MEMACCESS_DEBUGGER));
|
||||
ptr &= 0xffffff;
|
||||
strcat(str, t);
|
||||
if(x != 15)strcat(str, " ");
|
||||
}
|
||||
if(y != 15)strcat(str, "\r\n");
|
||||
}
|
||||
} else if(dmem_mode == DMEMMODE_VRAM) {
|
||||
ptr &= 0xffff;
|
||||
for(y=0;y<16;y++) {
|
||||
sprintf(t, "--%0.4x: ", ptr);
|
||||
strcat(str, t);
|
||||
for(x=0;x<16;x++) {
|
||||
sprintf(t, "%0.2x", ppu.vram[ptr++]);
|
||||
ptr &= 0xffff;
|
||||
strcat(str, t);
|
||||
if(x != 15)strcat(str, " ");
|
||||
}
|
||||
if(y != 15)strcat(str, "\r\n");
|
||||
}
|
||||
} else if(dmem_mode == DMEMMODE_CGRAM) {
|
||||
ptr &= 0x01ff;
|
||||
for(y=0;y<16;y++) {
|
||||
sprintf(t, "---%0.3x: ", ptr);
|
||||
strcat(str, t);
|
||||
for(x=0;x<16;x++) {
|
||||
sprintf(t, "%0.2x", ppu.cgram[ptr++]);
|
||||
ptr &= 0x01ff;
|
||||
strcat(str, t);
|
||||
if(x != 15)strcat(str, " ");
|
||||
}
|
||||
if(y != 15)strcat(str, "\r\n");
|
||||
}
|
||||
} else if(dmem_mode == DMEMMODE_OAM) {
|
||||
ptr &= 0x03ff;
|
||||
for(y=0;y<16;y++) {
|
||||
sprintf(t, "---%0.3x: ", ptr);
|
||||
strcat(str, t);
|
||||
for(x=0;x<16;x++) {
|
||||
sprintf(t, "%0.2x", oam_read(ptr++));
|
||||
ptr &= 0x03ff;
|
||||
strcat(str, t);
|
||||
if(x != 15)strcat(str, " ");
|
||||
}
|
||||
if(y != 15)strcat(str, "\r\n");
|
||||
}
|
||||
} else if(dmem_mode == DMEMMODE_SPCRAM) {
|
||||
ptr &= 0xffff;
|
||||
for(y=0;y<16;y++) {
|
||||
sprintf(t, "--%0.4x: ", ptr);
|
||||
strcat(str, t);
|
||||
for(x=0;x<16;x++) {
|
||||
sprintf(t, "%0.2x", spc700->ram[ptr++]);
|
||||
ptr &= 0xffff;
|
||||
strcat(str, t);
|
||||
if(x != 15)strcat(str, " ");
|
||||
}
|
||||
if(y != 15)strcat(str, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
SetDlgItemText(hwndDMEM, DMEM_VIEW, str);
|
||||
}
|
||||
|
||||
void __mask_mem_ptr(void) {
|
||||
if(dmem_mode == DMEMMODE_WRAM )debugger.mem_ptr &= 0xffffff;
|
||||
if(dmem_mode == DMEMMODE_VRAM )debugger.mem_ptr &= 0x00ffff;
|
||||
if(dmem_mode == DMEMMODE_CGRAM )debugger.mem_ptr &= 0x0001ff;
|
||||
if(dmem_mode == DMEMMODE_OAM )debugger.mem_ptr &= 0x0003ff;
|
||||
if(dmem_mode == DMEMMODE_SPCRAM)debugger.mem_ptr &= 0x00ffff;
|
||||
}
|
||||
|
||||
long __stdcall wndprocDMEM(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
char str[256];
|
||||
ulong pos, val;
|
||||
if(msg == WM_DESTROY || msg == WM_CLOSE) {
|
||||
return 0; //don't allow debugger to be closed (yet)
|
||||
}
|
||||
|
||||
if(emu_state.rom_loaded == false) {
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
if(msg == WM_COMMAND) {
|
||||
switch(LOWORD(wparam)) {
|
||||
case DMEM_EDITWRAM:
|
||||
GetDlgItemText(hwndDMEM, DMEM_EDITLOC, str, 255);
|
||||
pos = strhex(str);
|
||||
GetDlgItemText(hwndDMEM, DMEM_EDITVAL, str, 255);
|
||||
val = strhex(str);
|
||||
if(dmem_mode == DMEMMODE_WRAM) {
|
||||
gx816->mem_write(MEMMODE_LONG, MEMSIZE_BYTE, pos & 0xffffff, val, MEMACCESS_DEBUGGER);
|
||||
} else if(dmem_mode == DMEMMODE_VRAM) {
|
||||
ppu.vram[pos & 0xffff] = val;
|
||||
} else if(dmem_mode == DMEMMODE_CGRAM) {
|
||||
ppu.cgram[pos & 0x01ff] = val;
|
||||
} else if(dmem_mode == DMEMMODE_OAM) {
|
||||
oam_write(pos, val);
|
||||
} else if(dmem_mode == DMEMMODE_SPCRAM) {
|
||||
spc700->ram[pos & 0xffff] = val;
|
||||
}
|
||||
debug_refresh_mem();
|
||||
break;
|
||||
case DMEM_UP40:
|
||||
debugger.mem_ptr -= 0x40;
|
||||
debug_refresh_mem();
|
||||
__mask_mem_ptr();
|
||||
break;
|
||||
case DMEM_DOWN40:
|
||||
debugger.mem_ptr += 0x40;
|
||||
debug_refresh_mem();
|
||||
__mask_mem_ptr();
|
||||
break;
|
||||
case DMEM_UP400:
|
||||
debugger.mem_ptr -= 0x400;
|
||||
debug_refresh_mem();
|
||||
__mask_mem_ptr();
|
||||
break;
|
||||
case DMEM_DOWN400:
|
||||
debugger.mem_ptr += 0x400;
|
||||
debug_refresh_mem();
|
||||
__mask_mem_ptr();
|
||||
break;
|
||||
case DMEM_UP4000:
|
||||
debugger.mem_ptr -= 0x4000;
|
||||
debug_refresh_mem();
|
||||
__mask_mem_ptr();
|
||||
break;
|
||||
case DMEM_DOWN4000:
|
||||
debugger.mem_ptr += 0x4000;
|
||||
debug_refresh_mem();
|
||||
__mask_mem_ptr();
|
||||
break;
|
||||
case DMEM_UP40000:
|
||||
debugger.mem_ptr -= 0x40000;
|
||||
debug_refresh_mem();
|
||||
__mask_mem_ptr();
|
||||
break;
|
||||
case DMEM_DOWN40000:
|
||||
debugger.mem_ptr += 0x40000;
|
||||
debug_refresh_mem();
|
||||
__mask_mem_ptr();
|
||||
break;
|
||||
case DMEM_VIEWMODE:
|
||||
if(HIWORD(wparam) == CBN_SELCHANGE) {
|
||||
pos = SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_GETCURSEL, 0, 0);
|
||||
if(pos == 0) {
|
||||
dmem_mode = DMEMMODE_WRAM;
|
||||
debugger.mem_ptr = 0x7e0000;
|
||||
} else if(pos == 1) {
|
||||
dmem_mode = DMEMMODE_WRAM;
|
||||
if (gx816->map == MEMMAP_LOROM)debugger.mem_ptr = 0x008000;
|
||||
else if(gx816->map == MEMMAP_HIROM)debugger.mem_ptr = 0xc00000;
|
||||
} else if(pos == 2) {
|
||||
dmem_mode = DMEMMODE_WRAM;
|
||||
if (gx816->map == MEMMAP_LOROM)debugger.mem_ptr = 0x306000;
|
||||
else if(gx816->map == MEMMAP_HIROM)debugger.mem_ptr = 0x700000;
|
||||
} else if(pos == 3) {
|
||||
dmem_mode = DMEMMODE_VRAM;
|
||||
debugger.mem_ptr = 0x0000;
|
||||
} else if(pos == 4) {
|
||||
dmem_mode = DMEMMODE_CGRAM;
|
||||
debugger.mem_ptr = 0x0000;
|
||||
} else if(pos == 5) {
|
||||
dmem_mode = DMEMMODE_OAM;
|
||||
debugger.mem_ptr = 0x0000;
|
||||
} else if(pos == 6) {
|
||||
dmem_mode = DMEMMODE_SPCRAM;
|
||||
debugger.mem_ptr = 0x0000;
|
||||
}
|
||||
debug_refresh_mem();
|
||||
}
|
||||
break;
|
||||
case DMEM_GOTO:
|
||||
GetDlgItemText(hwndDMEM, DMEM_GOTOADDR, str, 255);
|
||||
debugger.mem_ptr = strhex(str);
|
||||
__mask_mem_ptr();
|
||||
debug_refresh_mem();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
void CreateDMEM(void) {
|
||||
CreateWindow("COMBOBOX", "",
|
||||
WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST|CBS_HASSTRINGS,
|
||||
5, 5, 200, 200, hwndDMEM, (HMENU)DMEM_VIEWMODE, GetModuleHandle(0), 0);
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "000000", WS_CHILD|WS_VISIBLE, 210, 5, 60, 21, hwndDMEM, (HMENU)DMEM_GOTOADDR, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Goto", WS_CHILD|WS_VISIBLE, 270, 5, 50, 20, hwndDMEM, (HMENU)DMEM_GOTO, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
|
||||
WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_READONLY,
|
||||
5, 30, 395, 233, hwndDMEM, (HMENU)DMEM_VIEW, GetModuleHandle(0), 0);
|
||||
|
||||
CreateWindow("STATIC", "Offset: Val:", WS_CHILD|WS_VISIBLE, 405, 15, 100, 15, hwndDMEM, (HMENU)DMEM_STATIC1, GetModuleHandle(0), 0);
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "000000", WS_CHILD|WS_VISIBLE, 405, 30, 60, 23, hwndDMEM, (HMENU)DMEM_EDITLOC, GetModuleHandle(0), 0);
|
||||
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "00", WS_CHILD|WS_VISIBLE, 465, 30, 30, 23, hwndDMEM, (HMENU)DMEM_EDITVAL, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "Edit Memory", WS_CHILD|WS_VISIBLE, 405, 55, 90, 20, hwndDMEM, (HMENU)DMEM_EDITWRAM, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "-40", WS_CHILD|WS_VISIBLE, 405, 80, 45, 20, hwndDMEM, (HMENU)DMEM_UP40, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "+40", WS_CHILD|WS_VISIBLE, 450, 80, 45, 20, hwndDMEM, (HMENU)DMEM_DOWN40, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "-400", WS_CHILD|WS_VISIBLE, 405, 100, 45, 20, hwndDMEM, (HMENU)DMEM_UP400, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "+400", WS_CHILD|WS_VISIBLE, 450, 100, 45, 20, hwndDMEM, (HMENU)DMEM_DOWN400, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "-4000", WS_CHILD|WS_VISIBLE, 405, 120, 45, 20, hwndDMEM, (HMENU)DMEM_UP4000, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "+4000", WS_CHILD|WS_VISIBLE, 450, 120, 45, 20, hwndDMEM, (HMENU)DMEM_DOWN4000, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "-40000", WS_CHILD|WS_VISIBLE, 405, 140, 45, 20, hwndDMEM, (HMENU)DMEM_UP40000, GetModuleHandle(0), 0);
|
||||
CreateWindow("BUTTON", "+40000", WS_CHILD|WS_VISIBLE, 450, 140, 45, 20, hwndDMEM, (HMENU)DMEM_DOWN40000, GetModuleHandle(0), 0);
|
||||
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_ADDSTRING, 0, (LPARAM)"DRAM [7e0000-7fffff]");
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_ADDSTRING, 0, (LPARAM)"ROM [008000/c00000]");
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_ADDSTRING, 0, (LPARAM)"SRAM [306000/700000]");
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_ADDSTRING, 0, (LPARAM)"VRAM [0000-ffff]");
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_ADDSTRING, 0, (LPARAM)"CGRAM [0000-01ff]");
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_ADDSTRING, 0, (LPARAM)"OAM [0000-03ff]");
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_ADDSTRING, 0, (LPARAM)"SPCRAM [0000-ffff]");
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, CB_SETCURSEL, 0, 0);
|
||||
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_GOTOADDR, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEW, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_EDITLOC, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_EDITVAL, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_GOTO, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_STATIC1, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_EDITWRAM, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_UP40, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_DOWN40, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_UP400, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_DOWN400, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_UP4000, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_DOWN4000, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_UP40000, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_DOWN40000, WM_SETFONT, (WPARAM)hFont, TRUE);
|
||||
SendDlgItemMessage(hwndDMEM, DMEM_VIEWMODE, WM_SETFONT, (WPARAM)hFontFixed, TRUE);
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
#include <ddraw.h>
|
||||
|
||||
LPDIRECTDRAW lpdd = 0;
|
||||
LPDIRECTDRAWSURFACE lpdds = 0, lpddsb = 0;
|
||||
LPDIRECTDRAWCLIPPER lpddc = 0;
|
||||
DDSURFACEDESC ddsd;
|
||||
DDSCAPS ddscaps;
|
||||
|
||||
void DestroyDDraw(void) {
|
||||
if(lpddc) {
|
||||
lpddc->Release();
|
||||
lpddc = 0;
|
||||
}
|
||||
if(lpddsb) {
|
||||
lpddsb->Release();
|
||||
lpddsb = 0;
|
||||
}
|
||||
if(lpdds) {
|
||||
lpdds->Release();
|
||||
lpdds = 0;
|
||||
}
|
||||
if(lpdd) {
|
||||
lpdd->Release();
|
||||
lpdd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateDDraw_Win(void) {
|
||||
DestroyDDraw();
|
||||
|
||||
DirectDrawCreate(0, &lpdd, 0);
|
||||
lpdd->SetCooperativeLevel(hwndMain, DDSCL_NORMAL);
|
||||
|
||||
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||
ddsd.dwFlags = DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
lpdd->CreateSurface(&ddsd, &lpdds, 0);
|
||||
|
||||
lpdd->CreateClipper(0, &lpddc, 0);
|
||||
lpddc->SetHWnd(0, hwndMain);
|
||||
lpdds->SetClipper(lpddc);
|
||||
|
||||
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
ddsd.dwWidth = 512;
|
||||
ddsd.dwHeight = 478;
|
||||
lpdd->CreateSurface(&ddsd, &lpddsb, 0);
|
||||
}
|
||||
|
||||
void CreateDDraw_Full(void) {
|
||||
DestroyDDraw();
|
||||
|
||||
DirectDrawCreate(0, &lpdd, 0);
|
||||
lpdd->SetCooperativeLevel(hwndMain, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
|
||||
lpdd->SetDisplayMode(640, 480, 16);
|
||||
|
||||
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||
ddsd.dwFlags = DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
lpdd->CreateSurface(&ddsd, &lpdds, 0);
|
||||
|
||||
lpdd->CreateClipper(0, &lpddc, 0);
|
||||
lpddc->SetHWnd(0, hwndMain);
|
||||
lpdds->SetClipper(lpddc);
|
||||
|
||||
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
ddsd.dwWidth = 512;
|
||||
ddsd.dwHeight = 478;
|
||||
lpdd->CreateSurface(&ddsd, &lpddsb, 0);
|
||||
}
|
||||
|
||||
void InitDisplay(void) {
|
||||
CreateDDraw_Win();
|
||||
}
|
||||
|
||||
//size is doubled (mirrored) to prevent having to mask the top unused bit of snes color data
|
||||
ulong render_color_lookup[65536];
|
||||
|
||||
void InitColorTable16(void) {
|
||||
int i, r, g, b;
|
||||
for(i=0;i<65536;i++) {
|
||||
r = (i ) & 31;
|
||||
g = (i >> 5) & 31;
|
||||
b = (i >> 10) & 31;
|
||||
render_color_lookup[i] = (r << 11) | (g << 6) | (b);
|
||||
}
|
||||
}
|
||||
|
||||
void InitColorTable24(void) {
|
||||
int i, r, g, b;
|
||||
for(i=0;i<65536;i++) {
|
||||
r = (i ) & 31;
|
||||
g = (i >> 5) & 31;
|
||||
b = (i >> 10) & 31;
|
||||
render_color_lookup[i] = (r << 19) | (g << 11) | (b << 3);
|
||||
}
|
||||
}
|
||||
|
||||
vfunc RenderScene;
|
||||
|
||||
#include "render_modes.cpp"
|
||||
|
||||
//sets up color table and sets render proc
|
||||
void CreateColorTable(void) {
|
||||
lpdds->GetSurfaceDesc(&ddsd);
|
||||
switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
|
||||
case 16:
|
||||
InitColorTable16();
|
||||
RenderScene = RenderScene16;
|
||||
break;
|
||||
case 32:
|
||||
InitColorTable24();
|
||||
RenderScene = RenderScene32;
|
||||
break;
|
||||
default:
|
||||
alert("Error: Bit depth [%d] unsupported (supported depths: 16, 32)", ddsd.ddpfPixelFormat.dwRGBBitCount);
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawScene(void) {
|
||||
RECT rsrc, rdest;
|
||||
POINT p;
|
||||
HRESULT hr;
|
||||
p.x = p.y = 0;
|
||||
if(render.fullscreen == true) {
|
||||
SetRect(&rdest, 0, 0, 512, 448);
|
||||
OffsetRect(&rdest, (640 - 512) / 2, (480 - 448) / 2);
|
||||
} else {
|
||||
ClientToScreen(hwndMain, &p);
|
||||
GetClientRect(hwndMain, &rdest);
|
||||
OffsetRect(&rdest, p.x, p.y);
|
||||
}
|
||||
|
||||
if(ppu.overscan == false) {
|
||||
SetRect(&rsrc, 0, 2, 512, 448);
|
||||
} else {
|
||||
SetRect(&rsrc, 0, 2 + 15, 512, 448 + 15);
|
||||
}
|
||||
|
||||
hr = lpdds->Blt(&rdest, lpddsb, &rsrc, DDBLT_WAIT, 0);
|
||||
if(hr == DDERR_SURFACELOST) {
|
||||
lpdds->Restore();
|
||||
lpddsb->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateDisplay(void) {
|
||||
RenderScene();
|
||||
DrawScene();
|
||||
}
|
||||
|
||||
void video_setmode(bool fullscreen, word width, word height) {
|
||||
bool prev_mode = render.fullscreen;
|
||||
if(debug_get_state() != DEBUGMODE_DISABLED)return;
|
||||
render.fullscreen = fullscreen;
|
||||
render.display_width = width;
|
||||
render.display_height = height;
|
||||
|
||||
//remove top scanline that is not rendered
|
||||
if (height == 224)height = 223;
|
||||
else if(height == 239)height = 238;
|
||||
else if(height == 448)height = 446;
|
||||
else if(height == 478)height = 476;
|
||||
|
||||
FixWindowSize(hwndMain, width, height);
|
||||
ShowWindow(hwndMain, SW_NORMAL);
|
||||
|
||||
if(prev_mode != fullscreen) {
|
||||
if(fullscreen == true) {
|
||||
render.show_menu = false;
|
||||
UpdateMainWindowStyle(true);
|
||||
CreateDDraw_Full();
|
||||
ShowWindow(hwndMain, SW_NORMAL);
|
||||
} else {
|
||||
render.show_menu = true;
|
||||
UpdateMainWindowStyle(true);
|
||||
CreateDDraw_Win();
|
||||
FixWindowSize(hwndMain, width, height);
|
||||
ShowWindow(hwndMain, SW_NORMAL);
|
||||
}
|
||||
CreateColorTable();
|
||||
}
|
||||
}
|
||||
|
||||
void video_setsnesmode(void) {
|
||||
if(ppu.bg_mode == 5 || ppu.bg_mode == 6) {
|
||||
render.snes_width = 512;
|
||||
} else {
|
||||
render.snes_width = 256;
|
||||
}
|
||||
if(ppu.interlace == false) {
|
||||
if(ppu.overscan == false) {
|
||||
render.snes_height = 224;
|
||||
} else {
|
||||
render.snes_height = 239;
|
||||
}
|
||||
} else {
|
||||
if(ppu.overscan == false) {
|
||||
render.snes_height = 448;
|
||||
} else {
|
||||
render.snes_height = 478;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
void RenderScene16(void) {
|
||||
HRESULT hr;
|
||||
hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
|
||||
if(hr != DD_OK)return;
|
||||
__asm {
|
||||
mov edi,ddsd.lpSurface
|
||||
mov edx,ddsd.lPitch
|
||||
add edi,edx
|
||||
add edi,edx
|
||||
sub edx,1024
|
||||
mov esi,ppu.screen
|
||||
add esi,2048
|
||||
mov ebx,478-2
|
||||
xor eax,eax
|
||||
loop_y:
|
||||
mov ecx,512
|
||||
loop_x:
|
||||
lodsw
|
||||
mov eax,dword ptr[render_color_lookup+eax*4]
|
||||
stosw
|
||||
dec ecx
|
||||
jnz loop_x
|
||||
add edi,edx
|
||||
dec ebx
|
||||
jnz loop_y
|
||||
}
|
||||
/*
|
||||
word *screen, *src;
|
||||
word pitch;
|
||||
int x, y;
|
||||
pitch = ddsd.lPitch >> 1;
|
||||
for(y=2;y<478;y++) {
|
||||
screen = (word*)ddsd.lpSurface + (pitch * y);
|
||||
src = (word*)ppu.screen + y * 512;
|
||||
for(x=0;x<512;x++) {
|
||||
*screen++ = render_color_lookup[*src++];
|
||||
}
|
||||
}
|
||||
*/
|
||||
lpddsb->Unlock(0);
|
||||
}
|
||||
|
||||
void RenderScene32(void) {
|
||||
HRESULT hr;
|
||||
hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0);
|
||||
if(hr != DD_OK)return;
|
||||
__asm {
|
||||
mov edi,ddsd.lpSurface
|
||||
mov edx,ddsd.lPitch
|
||||
add edi,edx
|
||||
add edi,edx
|
||||
sub edx,2048
|
||||
mov esi,ppu.screen
|
||||
add esi,2048
|
||||
mov ebx,478-2
|
||||
loop_y:
|
||||
mov ecx,512
|
||||
loop_x:
|
||||
lodsw
|
||||
and eax,0xffff
|
||||
mov eax,dword ptr[render_color_lookup+eax*4]
|
||||
stosd
|
||||
dec ecx
|
||||
jnz loop_x
|
||||
add edi,edx
|
||||
dec ebx
|
||||
jnz loop_y
|
||||
}
|
||||
/*
|
||||
ulong *screen;
|
||||
word *src;
|
||||
word pitch;
|
||||
int x, y;
|
||||
pitch = ddsd.lPitch >> 2;
|
||||
for(y=2;y<478;y++) {
|
||||
screen = (ulong*)ddsd.lpSurface + (pitch * y);
|
||||
src = (word*)ppu.screen + y * 512;
|
||||
for(x=0;x<512;x++) {
|
||||
*screen++ = render_color_lookup[*src++];
|
||||
}
|
||||
}
|
||||
*/
|
||||
lpddsb->Unlock(0);
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
bsnes (TM) Reference License
|
||||
Copyright (C) 2004 - 2008 byuu
|
||||
All rights reserved
|
||||
|
||||
1. Definitions
|
||||
|
||||
The terms "reproduce", "reproduction", "distribute" and "distribution" have the
|
||||
same meaning here as under U.S. copyright law.
|
||||
|
||||
"The software" means this software package as a whole, including, but not
|
||||
limited to, this license, binaries, source code, documentation, and data.
|
||||
|
||||
"You" means the licensee of the software.
|
||||
|
||||
"The licensor" means the copyright holder of the software, byuu.
|
||||
|
||||
2. Grant of Rights
|
||||
|
||||
Subject to the terms of this license, the licensor grants you a
|
||||
non-transferable, non-exclusive, worldwide, royalty-free copyright license to
|
||||
reproduce the software for non-commercial use only, provided the software
|
||||
remains unmodified, and there is no charge for the software itself, its' use,
|
||||
nor for the medium upon which the software is distributed. The reproduction of
|
||||
modified or derivative works of the software is strictly prohibited, except when
|
||||
transmitted solely to the licensor.
|
||||
|
||||
3. Limitations
|
||||
|
||||
This license does not grant you any rights to use the licensor's name, logo or
|
||||
trademarks.
|
||||
|
||||
The software is provided "as is", and any express or implied warranties,
|
||||
including, but not limited to, the implied warranties of merchantability and
|
||||
fitness for a particular purpose are disclaimed. In no event shall the licensor
|
||||
be liable for any direct, indirect, incidental, special, exemplary, or
|
||||
consequential damages (including, but not limited to, procurement of substitute
|
||||
goods or services; loss of use, data, or profits; or business interruption)
|
||||
however caused and on any theory of liability, whether in contract, strict
|
||||
liability, or tort (including negligence or otherwise) arising in any way out of
|
||||
the use of the software, even if advised of the possibility of such damage.
|
||||
|
||||
In the event that this license is determined to be invalid or unenforceable, the
|
||||
Grant of Rights will become null and void, and no rights shall be granted to the
|
||||
licensee, within the scope of U.S. copyright law.
|
||||
|
||||
4. Exemptions
|
||||
|
||||
The software includes the work of other copyright holders, which is licensed
|
||||
under different agreements, and exempt from this license. Below is a complete
|
||||
list of all such software, and their respective copyright holders and licenses.
|
||||
Further, respective source code files are labeled with their correct licensing
|
||||
information in the header. The lack of such a header indicates said file falls
|
||||
under the bsnes license.
|
||||
|
||||
HQ2x filter, author: MaxST, license: LGPL
|
||||
JMA decompressor, author: NSRT Team, license: GPL (*)
|
||||
NTSC filter, author: blargg, license: LGPL
|
||||
zlib decompressor, license: zlib license
|
||||
|
||||
(*) bsnes has received an exemption from the copyright holder to use this work.
|
||||
|
||||
The software also includes works which have been released to the public domain,
|
||||
which are not bound to any licensing agreements. Below is a complete list of all
|
||||
such software.
|
||||
|
||||
libco, author: byuu
|
||||
libui, author: byuu
|
||||
OBC-1 emu, author: byuu
|
||||
S-DD1 emu, author: Andreas Naive
|
||||
S-RTC emu, author: byuu
|
||||
|
||||
Any software listed above as exemptions may be relicensed individually from
|
||||
bsnes under their respective terms. However, no bsnes licensed portions can be
|
||||
combined with such a derivative work.
|
||||
|
||||
The software also includes the work of other copyright holders, which is
|
||||
licensed under the terms of the bsnes license, with permission to do so from the
|
||||
respective authors. Below is a complete list of all such software.
|
||||
|
||||
Cx4 emu, authors: anomie, Overload, zsKnight, Nach
|
||||
DSP-1 emu, authors: Overload, John Weidman, Neviksti, Andreas Naive
|
||||
DSP-2 emu, author: Overload
|
||||
DSP-3 emu, authors: John Weidman, Kris Bleakley, Lancer, z80 gaiden
|
||||
DSP-4 emu, authors: Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden
|
||||
S-DSP emu, author: blargg
|
||||
ST-010 emu, authors: John Weidman, Matthew Kendora, Overload, Feather
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
bsnes
|
||||
Version: 0.032a
|
||||
Author: byuu
|
||||
|
||||
--------
|
||||
General:
|
||||
--------
|
||||
bsnes is a Super Nintendo / Super Famicom emulator that began on
|
||||
October 14th, 2004.
|
||||
|
||||
The latest version can be downloaded from:
|
||||
http://byuu.org/
|
||||
|
||||
Please see license.txt for important licensing information.
|
||||
|
||||
--------------
|
||||
Configuration:
|
||||
--------------
|
||||
bsnes has two configuration files: bsnes.cfg, for program settings; and
|
||||
locale.cfg, for localization.
|
||||
|
||||
For each file, bsnes will start by looking inside the same folder where the
|
||||
bsnes executable is located. If said file is not found, it will then check your
|
||||
user profile folder. On Windows, this is located at "%APPDATA%/.bsnes". On all
|
||||
other operating systems, this is located at "~/.bsnes". If said file is still
|
||||
not found, it will automatically be created in your user profile folder.
|
||||
|
||||
If you wish to use bsnes in single-user mode, be sure that both files exist
|
||||
inside the same folder as the bsnes executable. If they do not, you can simply
|
||||
create new blank files and bsnes will use them in the future.
|
||||
|
||||
If you wish to use bsnes in multi-user mode, simply delete these two files from
|
||||
the bsnes executable directory if they exist.
|
||||
|
||||
If you wish to have multiple configuration profiles for the same user, you will
|
||||
need to make copies of the bsnes executable, and use each one in single-user
|
||||
mode.
|
||||
|
||||
------------------
|
||||
Known Limitations:
|
||||
------------------
|
||||
S-CPU
|
||||
- Multiply / divide register delays not implemented
|
||||
|
||||
S-PPU
|
||||
- Uses scanline-based renderer. This is very inaccurate, but few (if any)
|
||||
games rely on mid-scanline writes to function correctly
|
||||
- Does not support FirstSprite+Y priority
|
||||
- OAM / CGRAM accesses during active display not supported correctly
|
||||
- RTO flags are not calculated on frames that are skipped when frameskipping
|
||||
is enabled. This provides a major speedup, however it will cause in issues
|
||||
in games that test these flags, eg the SNES Test Program Electronics Test.
|
||||
Turning frameskipping off will allow RTO flag calculation on every frame
|
||||
|
||||
Hardware Bugs
|
||||
- S-CPU.r1 HDMA crashing bug not emulated
|
||||
- S-CPU<>S-SMP communication bus conflicts not emulated
|
||||
|
||||
---------------------
|
||||
Unsupported Hardware:
|
||||
---------------------
|
||||
SA-1
|
||||
Coprocessor used in many popular games, including:
|
||||
- Dragon Ball Z Hyper Dimension
|
||||
- Kirby Super Star
|
||||
- Kirby's Dreamland 3
|
||||
- Marvelous
|
||||
- SD Gundam G-NEXT
|
||||
- Super Mario RPG
|
||||
|
||||
Super FX
|
||||
Coprocessor used in many popular games, including:
|
||||
- Doom
|
||||
- Star Fox
|
||||
- Star Fox 2 (unreleased beta)
|
||||
- Super Mario World 2: Yoshi's Island
|
||||
|
||||
SPC7110
|
||||
Coprocessor used only by the following games:
|
||||
- Far East of Eden Zero
|
||||
- Far East of Eden Zero: Shounen Jump no Shou
|
||||
- Momotarou Densetsu Happy
|
||||
- Super Power League 4
|
||||
|
||||
ST-011
|
||||
SETA DSP used by Quick-move Shogi Match with Nidan Rank-holder Morita
|
||||
|
||||
ST-018
|
||||
SETA RISC CPU used by Quick-move Shogi Match with Nidan Rank-holder Morita 2
|
||||
|
||||
Super Gameboy
|
||||
Cartridge passthrough used for playing Gameboy games
|
||||
|
||||
------------------------
|
||||
Unsupported Controllers:
|
||||
------------------------
|
||||
Mouse
|
||||
Super Scope
|
||||
Justifier
|
||||
Multitap (4-port and 5-port)
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
include lib/nall/Makefile.string
|
||||
prefix = /usr/local
|
||||
|
||||
################
|
||||
### compiler ###
|
||||
################
|
||||
|
||||
ifneq ($(findstring gcc,$(compiler)),) # GCC family
|
||||
flags = -O3 -fomit-frame-pointer -Ilib
|
||||
c = $(compiler) $(flags)
|
||||
cpp = $(subst cc,++,$(compiler)) $(flags)
|
||||
obj = o
|
||||
rule = -c $< -o $@
|
||||
link = -s
|
||||
mkbin = -o$1
|
||||
mkdef = -D$1
|
||||
mklib = -l$1
|
||||
else ifeq ($(compiler),cl) # Visual C++
|
||||
flags = /nologo /wd4355 /wd4996 /O2 /EHsc /Ilib
|
||||
c = cl $(flags)
|
||||
cpp = cl $(flags)
|
||||
obj = obj
|
||||
rule = /c $< /Fo$@
|
||||
link = /link
|
||||
mkbin = /Fe$1
|
||||
mkdef = /D$1
|
||||
mklib = $1.lib
|
||||
else
|
||||
unknown_compiler: help;
|
||||
endif
|
||||
|
||||
##########
|
||||
### os ###
|
||||
##########
|
||||
|
||||
ifeq ($(platform),x) # X11
|
||||
ruby = video.glx video.xv video.sdl audio.openal audio.oss audio.alsa audio.ao input.sdl input.x
|
||||
link += `pkg-config --libs gtk+-2.0`
|
||||
link += $(call mklib,Xtst)
|
||||
delete = rm -f $1
|
||||
else ifeq ($(platform),win) # Windows
|
||||
ruby = video.direct3d video.wgl video.directdraw video.gdi audio.directsound input.directinput
|
||||
link += $(if $(findstring mingw,$(compiler)),-mwindows)
|
||||
link += $(call mklib,uuid)
|
||||
link += $(call mklib,kernel32)
|
||||
link += $(call mklib,user32)
|
||||
link += $(call mklib,gdi32)
|
||||
link += $(call mklib,shell32)
|
||||
link += $(call mklib,winmm)
|
||||
link += $(call mklib,comdlg32)
|
||||
link += $(call mklib,comctl32)
|
||||
delete = $(if $(findstring i586-mingw-gcc,$(compiler)),rm -f $1,del $(subst /,\,$1))
|
||||
else
|
||||
unknown_platform: help;
|
||||
endif
|
||||
|
||||
############
|
||||
### ruby ###
|
||||
############
|
||||
|
||||
rubyflags =
|
||||
rubyflags += $(if $(findstring .sdl,$(ruby)),`sdl-config --cflags`)
|
||||
|
||||
link += $(if $(findstring video.direct3d,$(ruby)),$(call mklib,d3d9))
|
||||
link += $(if $(findstring video.directdraw,$(ruby)),$(call mklib,ddraw))
|
||||
link += $(if $(findstring video.glx,$(ruby)),$(call mklib,GL))
|
||||
link += $(if $(findstring video.wgl,$(ruby)),$(call mklib,opengl32))
|
||||
link += $(if $(findstring video.xv,$(ruby)),$(call mklib,Xv))
|
||||
link += $(if $(findstring audio.alsa,$(ruby)),$(call mklib,asound))
|
||||
link += $(if $(findstring audio.ao,$(ruby)),$(call mklib,ao))
|
||||
link += $(if $(findstring audio.directsound,$(ruby)),$(call mklib,dsound))
|
||||
link += $(if $(findstring audio.openal,$(ruby)),$(if $(call streq,$(platform),x),$(call mklib,openal),$(call mklib,openal32)))
|
||||
link += $(if $(findstring input.directinput,$(ruby)),$(call mklib,dinput8) $(call mklib,dxguid))
|
||||
link += $(if $(findstring input.sdl,$(ruby)),`sdl-config --libs`)
|
||||
|
||||
####################################
|
||||
### main target and dependencies ###
|
||||
####################################
|
||||
|
||||
objects = main libco hiro ruby libfilter string reader cart cheat \
|
||||
memory smemory cpu scpu smp ssmp sdsp ppu bppu snes \
|
||||
bsx srtc sdd1 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010
|
||||
|
||||
ifeq ($(enable_gzip),true)
|
||||
objects += adler32 compress crc32 deflate gzio inffast inflate inftrees ioapi trees unzip zip zutil
|
||||
flags += $(call mkdef,GZIP_SUPPORT)
|
||||
endif
|
||||
|
||||
ifeq ($(enable_jma),true)
|
||||
objects += jma jcrc32 lzmadec 7zlzma iiostrm inbyte lzma winout
|
||||
flags += $(call mkdef,JMA_SUPPORT)
|
||||
endif
|
||||
|
||||
objects := $(patsubst %,obj/%.$(obj),$(objects))
|
||||
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),$(call mkdef,$c))
|
||||
|
||||
# Windows resource file
|
||||
ifeq ($(platform),win)
|
||||
ifeq ($(compiler),cl)
|
||||
objects += obj/bsnes.res
|
||||
else ifneq ($(findstring gcc,$(compiler)),)
|
||||
objects += obj/bsnesrc.$(obj)
|
||||
endif
|
||||
endif
|
||||
|
||||
################
|
||||
### implicit ###
|
||||
################
|
||||
|
||||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(c) $1 $(rule), \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(cpp) $1 $(rule) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
%.$(obj): $<; $(call compile)
|
||||
|
||||
all: build;
|
||||
|
||||
############
|
||||
### main ###
|
||||
############
|
||||
|
||||
obj/main.$(obj): ui/main.cpp ui/* ui/base/* ui/loader/* ui/settings/*
|
||||
obj/bsnes.res: ui/bsnes.rc; rc /r /foobj/bsnes.res ui/bsnes.rc
|
||||
obj/bsnesrc.$(obj): ui/bsnes.rc; windres ui/bsnes.rc obj/bsnesrc.$(obj)
|
||||
|
||||
#################
|
||||
### libraries ###
|
||||
#################
|
||||
|
||||
obj/ruby.$(obj): lib/ruby/ruby.cpp lib/ruby/*
|
||||
$(call compile,$(rubydef) $(rubyflags))
|
||||
obj/hiro.$(obj): lib/hiro/hiro.cpp lib/hiro/* lib/hiro/gtk/* lib/hiro/win/*
|
||||
$(call compile,$(if $(call streq,$(platform),x),`pkg-config --cflags gtk+-2.0`))
|
||||
obj/libco.$(obj): lib/libco/libco.c lib/libco/*
|
||||
$(call compile,-static)
|
||||
obj/libfilter.$(obj): lib/libfilter/libfilter.cpp lib/libfilter/*
|
||||
obj/string.$(obj): lib/nall/string.cpp lib/nall/*
|
||||
|
||||
#################
|
||||
### utilities ###
|
||||
#################
|
||||
|
||||
obj/reader.$(obj): reader/reader.cpp reader/*
|
||||
obj/cart.$(obj) : cart/cart.cpp cart/*
|
||||
obj/cheat.$(obj) : cheat/cheat.cpp cheat/*
|
||||
|
||||
##############
|
||||
### memory ###
|
||||
##############
|
||||
|
||||
obj/memory.$(obj) : memory/memory.cpp memory/*
|
||||
obj/smemory.$(obj): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/mapper/*
|
||||
|
||||
###########
|
||||
### cpu ###
|
||||
###########
|
||||
|
||||
obj/cpu.$(obj) : cpu/cpu.cpp cpu/*
|
||||
obj/scpu.$(obj): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/*
|
||||
|
||||
###########
|
||||
### smp ###
|
||||
###########
|
||||
|
||||
obj/smp.$(obj) : smp/smp.cpp smp/*
|
||||
obj/ssmp.$(obj): smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/core/* smp/ssmp/memory/* smp/ssmp/timing/*
|
||||
|
||||
###########
|
||||
### dsp ###
|
||||
###########
|
||||
|
||||
obj/adsp.$(obj): dsp/adsp/adsp.cpp dsp/adsp/*
|
||||
obj/bdsp.$(obj): dsp/bdsp/bdsp.cpp dsp/bdsp/*
|
||||
obj/sdsp.$(obj): dsp/sdsp/sdsp.cpp dsp/sdsp/*
|
||||
|
||||
###########
|
||||
### ppu ###
|
||||
###########
|
||||
|
||||
obj/ppu.$(obj) : ppu/ppu.cpp ppu/*
|
||||
obj/bppu.$(obj): ppu/bppu/bppu.cpp ppu/bppu/*
|
||||
|
||||
############
|
||||
### snes ###
|
||||
############
|
||||
|
||||
obj/snes.$(obj): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* snes/input/*
|
||||
|
||||
#####################
|
||||
### special chips ###
|
||||
#####################
|
||||
|
||||
obj/bsx.$(obj) : chip/bsx/bsx.cpp chip/bsx/*
|
||||
obj/srtc.$(obj) : chip/srtc/srtc.cpp chip/srtc/*
|
||||
obj/sdd1.$(obj) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
obj/cx4.$(obj) : chip/cx4/cx4.cpp chip/cx4/*
|
||||
obj/dsp1.$(obj) : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||
obj/dsp2.$(obj) : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
obj/dsp3.$(obj) : chip/dsp3/dsp3.cpp chip/dsp3/*
|
||||
obj/dsp4.$(obj) : chip/dsp4/dsp4.cpp chip/dsp4/*
|
||||
obj/obc1.$(obj) : chip/obc1/obc1.cpp chip/obc1/*
|
||||
obj/st010.$(obj): chip/st010/st010.cpp chip/st010/*
|
||||
|
||||
############
|
||||
### zlib ###
|
||||
############
|
||||
|
||||
obj/adler32.$(obj) : reader/zlib/adler32.c reader/zlib/*
|
||||
obj/compress.$(obj): reader/zlib/compress.c reader/zlib/*
|
||||
obj/crc32.$(obj) : reader/zlib/crc32.c reader/zlib/*
|
||||
obj/deflate.$(obj) : reader/zlib/deflate.c reader/zlib/*
|
||||
obj/gzio.$(obj) : reader/zlib/gzio.c reader/zlib/*
|
||||
obj/inffast.$(obj) : reader/zlib/inffast.c reader/zlib/*
|
||||
obj/inflate.$(obj) : reader/zlib/inflate.c reader/zlib/*
|
||||
obj/inftrees.$(obj): reader/zlib/inftrees.c reader/zlib/*
|
||||
obj/ioapi.$(obj) : reader/zlib/ioapi.c reader/zlib/*
|
||||
obj/trees.$(obj) : reader/zlib/trees.c reader/zlib/*
|
||||
obj/unzip.$(obj) : reader/zlib/unzip.c reader/zlib/*
|
||||
obj/zip.$(obj) : reader/zlib/zip.c reader/zlib/*
|
||||
obj/zutil.$(obj) : reader/zlib/zutil.c reader/zlib/*
|
||||
|
||||
###########
|
||||
### jma ###
|
||||
###########
|
||||
|
||||
obj/jma.$(obj) : reader/jma/jma.cpp reader/jma/*
|
||||
obj/jcrc32.$(obj) : reader/jma/jcrc32.cpp reader/jma/*
|
||||
obj/lzmadec.$(obj): reader/jma/lzmadec.cpp reader/jma/*
|
||||
obj/7zlzma.$(obj) : reader/jma/7zlzma.cpp reader/jma/*
|
||||
obj/iiostrm.$(obj): reader/jma/iiostrm.cpp reader/jma/*
|
||||
obj/inbyte.$(obj) : reader/jma/inbyte.cpp reader/jma/*
|
||||
obj/lzma.$(obj) : reader/jma/lzma.cpp reader/jma/*
|
||||
obj/winout.$(obj) : reader/jma/winout.cpp reader/jma/*
|
||||
|
||||
###############
|
||||
### targets ###
|
||||
###############
|
||||
|
||||
build: $(objects)
|
||||
$(strip $(cpp) $(call mkbin,../bsnes) $(objects) $(link))
|
||||
|
||||
install:
|
||||
install -D -m 755 ../bsnes $(DESTDIR)$(prefix)/bin/bsnes
|
||||
install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/icons/bsnes.png
|
||||
|
||||
clean:
|
||||
-@$(call delete,obj/*.$(obj))
|
||||
-@$(call delete,*.res)
|
||||
-@$(call delete,*.pgd)
|
||||
-@$(call delete,*.pgc)
|
||||
-@$(call delete,*.ilk)
|
||||
-@$(call delete,*.pdb)
|
||||
-@$(call delete,*.manifest)
|
||||
|
||||
help:
|
||||
@echo "Usage: $(MAKE) platform=(os) compiler=(cc) [options]"
|
||||
@echo ""
|
||||
@echo "Supported platforms:"
|
||||
@echo " x - Linux / BSD (x86, x86-64)"
|
||||
@echo " win - Windows (x86, x86-64)"
|
||||
@echo ""
|
||||
@echo "Supported compilers:"
|
||||
@echo " gcc - GCC compiler"
|
||||
@echo " mingw32-gcc - MinGW compiler"
|
||||
@echo " i586-mingw32-gcc - MinGW cross compiler"
|
||||
@echo " cl - Visual C++"
|
||||
@echo ""
|
||||
@echo "Available options:"
|
||||
@echo " enable_gzip=[true|false] - Enable ZIP / GZ support (default=false)"
|
||||
@echo " enable_jma=[true|false] - Enable JMA support (default=false)"
|
||||
@echo ""
|
||||
@echo "Example: $(MAKE) platform=x compiler=gcc enable_gzip=true"
|
||||
@echo ""
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#define BSNES_VERSION "0.032a"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define BUSCORE sBus
|
||||
#define CPUCORE sCPU
|
||||
#define SMPCORE sSMP
|
||||
#define DSPCORE sDSP
|
||||
#define PPUCORE bPPU
|
||||
|
||||
//S-DSP can be encapsulated into a state machine using #define magic
|
||||
//this avoids ~2.048m co_switch() calls per second (~5% speedup)
|
||||
#define USE_STATE_MACHINE
|
||||
|
||||
//FAST_FRAMESKIP disables calculation of RTO during frameskip
|
||||
//frameskip offers near-zero speedup if RTO is calculated
|
||||
//accuracy is not affected by this define when frameskipping is off
|
||||
#define FAST_FRAMESKIP
|
||||
|
||||
//game genie + pro action replay code support (~2% speed hit)
|
||||
#define CHEAT_SYSTEM
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/config.hpp>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/modulo.hpp>
|
||||
#include <nall/new.hpp>
|
||||
#include <nall/sort.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#include <libco/libco.h>
|
||||
#include <bbase.h>
|
||||
|
||||
//platform-specific global functions
|
||||
void alert(const char*, ...);
|
||||
void dprintf(const char*, ...);
|
||||
void dprintf(uint, const char*, ...);
|
||||
|
||||
namespace source {
|
||||
enum {
|
||||
none = 0,
|
||||
debug,
|
||||
cpu,
|
||||
ppu,
|
||||
smp,
|
||||
dsp,
|
||||
bus,
|
||||
};
|
||||
};
|
||||
|
||||
#include "interface.h"
|
||||
@@ -0,0 +1,137 @@
|
||||
#include "../base.h"
|
||||
#define CART_CPP
|
||||
|
||||
#include <nall/crc32.hpp>
|
||||
#include <nall/ups.hpp>
|
||||
|
||||
#include "cart_normal.cpp"
|
||||
#include "cart_bsx.cpp"
|
||||
#include "cart_bsc.cpp"
|
||||
#include "cart_st.cpp"
|
||||
|
||||
#include "cart_file.cpp"
|
||||
#include "cart_header.cpp"
|
||||
|
||||
namespace memory {
|
||||
MappedRAM cartrom, cartram;
|
||||
MappedRAM bscram;
|
||||
MappedRAM stArom, stAram;
|
||||
MappedRAM stBrom, stBram;
|
||||
};
|
||||
|
||||
Cartridge cartridge;
|
||||
|
||||
Cartridge::MemoryMapper Cartridge::mapper() { return info.mapper; }
|
||||
Cartridge::Region Cartridge::region() { return info.region; }
|
||||
|
||||
bool Cartridge::loaded() { return cart.loaded; }
|
||||
|
||||
void Cartridge::load_begin(CartridgeType cart_type) {
|
||||
cart.rom = cart.ram = 0;
|
||||
bs.ram = 0;
|
||||
stA.rom = stA.ram = 0;
|
||||
stB.rom = stB.ram = 0;
|
||||
|
||||
cart.rom_size = cart.ram_size = 0;
|
||||
bs.ram_size = 0;
|
||||
stA.rom_size = stA.ram_size = 0;
|
||||
stB.rom_size = stB.ram_size = 0;
|
||||
|
||||
info.type = cart_type;
|
||||
|
||||
info.bsxbase = false;
|
||||
info.bsxcart = false;
|
||||
info.bsxflash = false;
|
||||
info.st = false;
|
||||
|
||||
info.superfx = false;
|
||||
info.sa1 = false;
|
||||
info.spc7110 = false;
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.cx4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.dsp3 = false;
|
||||
info.dsp4 = false;
|
||||
info.obc1 = false;
|
||||
info.st010 = false;
|
||||
info.st011 = false;
|
||||
info.st018 = false;
|
||||
|
||||
info.dsp1_mapper = DSP1Unmapped;
|
||||
|
||||
info.header_index = 0xffc0;
|
||||
info.mapper = LoROM;
|
||||
info.name[0] = 0;
|
||||
info.region = NTSC;
|
||||
|
||||
info.rom_size = 0;
|
||||
info.ram_size = 0;
|
||||
}
|
||||
|
||||
void Cartridge::load_end() {
|
||||
memory::cartrom.map(cart.rom, cart.rom_size);
|
||||
memory::cartram.map(cart.ram, cart.ram_size);
|
||||
memory::bscram.map(bs.ram, bs.ram_size);
|
||||
memory::stArom.map(stA.rom, stA.rom_size);
|
||||
memory::stAram.map(stA.ram, stA.ram_size);
|
||||
memory::stBrom.map(stB.rom, stB.rom_size);
|
||||
memory::stBram.map(stB.ram, stB.ram_size);
|
||||
|
||||
memory::cartrom.write_protect(true);
|
||||
memory::cartram.write_protect(false);
|
||||
memory::bscram.write_protect(true);
|
||||
memory::stArom.write_protect(true);
|
||||
memory::stAram.write_protect(false);
|
||||
memory::stBrom.write_protect(true);
|
||||
memory::stBram.write_protect(false);
|
||||
|
||||
if(fexists(get_cheat_filename(cart.fn, "cht"))) {
|
||||
cheat.clear();
|
||||
cheat.load(cheatfn);
|
||||
}
|
||||
|
||||
cart.loaded = true;
|
||||
bus.load_cart();
|
||||
}
|
||||
|
||||
bool Cartridge::unload() {
|
||||
if(cart.loaded == false) return false;
|
||||
|
||||
bus.unload_cart();
|
||||
|
||||
switch(info.type) {
|
||||
case CartridgeNormal: unload_cart_normal(); break;
|
||||
case CartridgeBSX: unload_cart_bsx(); break;
|
||||
case CartridgeBSC: unload_cart_bsc(); break;
|
||||
case CartridgeSufamiTurbo: unload_cart_st(); break;
|
||||
}
|
||||
|
||||
if(cart.rom) { delete[] cart.rom; cart.rom = 0; }
|
||||
if(cart.ram) { delete[] cart.ram; cart.ram = 0; }
|
||||
if(bs.ram) { delete[] bs.ram; bs.ram = 0; }
|
||||
if(stA.rom) { delete[] stA.rom; stA.rom = 0; }
|
||||
if(stA.ram) { delete[] stA.ram; stA.ram = 0; }
|
||||
if(stB.rom) { delete[] stB.rom; stB.rom = 0; }
|
||||
if(stB.ram) { delete[] stB.ram; stB.ram = 0; }
|
||||
|
||||
char fn[PATH_MAX];
|
||||
strcpy(fn, cart.fn);
|
||||
modify_extension(fn, "cht");
|
||||
if(cheat.count() > 0 || fexists(get_cheat_filename(cart.fn, "cht"))) {
|
||||
cheat.save(cheatfn);
|
||||
cheat.clear();
|
||||
}
|
||||
|
||||
cart.loaded = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Cartridge::Cartridge() {
|
||||
cart.loaded = false;
|
||||
}
|
||||
|
||||
Cartridge::~Cartridge() {
|
||||
if(cart.loaded == true) unload();
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
class Cartridge {
|
||||
public:
|
||||
enum CartridgeType {
|
||||
CartridgeNormal,
|
||||
CartridgeBSX,
|
||||
CartridgeBSC,
|
||||
CartridgeSufamiTurbo,
|
||||
};
|
||||
|
||||
enum HeaderField {
|
||||
CART_NAME = 0x00,
|
||||
MAPPER = 0x15,
|
||||
ROM_TYPE = 0x16,
|
||||
ROM_SIZE = 0x17,
|
||||
RAM_SIZE = 0x18,
|
||||
REGION = 0x19,
|
||||
COMPANY = 0x1a,
|
||||
VERSION = 0x1b,
|
||||
ICKSUM = 0x1c,
|
||||
CKSUM = 0x1e,
|
||||
RESL = 0x3c,
|
||||
RESH = 0x3d,
|
||||
};
|
||||
|
||||
enum Region {
|
||||
NTSC,
|
||||
PAL,
|
||||
};
|
||||
|
||||
enum MemoryMapper {
|
||||
LoROM,
|
||||
HiROM,
|
||||
ExLoROM,
|
||||
ExHiROM,
|
||||
BSXROM,
|
||||
BSCLoROM,
|
||||
BSCHiROM,
|
||||
STROM,
|
||||
};
|
||||
|
||||
enum DSP1MemoryMapper {
|
||||
DSP1Unmapped,
|
||||
DSP1LoROM1MB,
|
||||
DSP1LoROM2MB,
|
||||
DSP1HiROM,
|
||||
};
|
||||
|
||||
struct {
|
||||
bool loaded;
|
||||
char fn[PATH_MAX];
|
||||
uint8 *rom, *ram;
|
||||
uint rom_size, ram_size;
|
||||
} cart;
|
||||
|
||||
struct {
|
||||
char fn[PATH_MAX];
|
||||
uint8 *ram;
|
||||
uint ram_size;
|
||||
} bs;
|
||||
|
||||
struct {
|
||||
char fn[PATH_MAX];
|
||||
uint8 *rom, *ram;
|
||||
uint rom_size, ram_size;
|
||||
} stA, stB;
|
||||
|
||||
struct {
|
||||
CartridgeType type;
|
||||
|
||||
uint32 crc32;
|
||||
char filename[PATH_MAX * 4];
|
||||
char name[128];
|
||||
|
||||
Region region;
|
||||
MemoryMapper mapper;
|
||||
uint rom_size;
|
||||
uint ram_size;
|
||||
|
||||
bool bsxbase;
|
||||
bool bsxcart;
|
||||
bool bsxflash;
|
||||
bool st;
|
||||
bool superfx;
|
||||
bool sa1;
|
||||
bool srtc;
|
||||
bool sdd1;
|
||||
bool spc7110;
|
||||
bool cx4;
|
||||
bool dsp1;
|
||||
bool dsp2;
|
||||
bool dsp3;
|
||||
bool dsp4;
|
||||
bool obc1;
|
||||
bool st010;
|
||||
bool st011;
|
||||
bool st018;
|
||||
|
||||
DSP1MemoryMapper dsp1_mapper;
|
||||
|
||||
uint header_index;
|
||||
} info;
|
||||
|
||||
MemoryMapper mapper();
|
||||
Region region();
|
||||
|
||||
void load_cart_normal(const char*);
|
||||
void load_cart_bsx(const char*, const char*);
|
||||
void load_cart_bsc(const char*, const char*);
|
||||
void load_cart_st(const char*, const char*, const char*);
|
||||
|
||||
void unload_cart_normal();
|
||||
void unload_cart_bsx();
|
||||
void unload_cart_bsc();
|
||||
void unload_cart_st();
|
||||
|
||||
bool loaded();
|
||||
void load_begin(CartridgeType);
|
||||
void load_end();
|
||||
bool unload();
|
||||
|
||||
void find_header();
|
||||
void read_header();
|
||||
void read_extended_header();
|
||||
|
||||
enum CompressionMode {
|
||||
CompressionNone, //always load without compression
|
||||
CompressionInspect, //use file header inspection
|
||||
CompressionAuto, //use file extension or file header inspection (configured by user)
|
||||
};
|
||||
bool load_file(const char *fn, uint8 *&data, uint &size, CompressionMode compression = CompressionNone);
|
||||
bool save_file(const char *fn, uint8 *data, uint size);
|
||||
bool apply_patch(const uint8_t *pdata, unsigned psize, uint8_t *&data, unsigned &size);
|
||||
char* modify_extension(char *filename, const char *extension);
|
||||
char* get_base_filename(char *filename);
|
||||
char* get_path_filename(char *filename, const char *path, const char *source, const char *extension);
|
||||
char* get_patch_filename(const char *source, const char *extension);
|
||||
char* get_save_filename(const char *source, const char *extension);
|
||||
char* get_cheat_filename(const char *source, const char *extension);
|
||||
|
||||
Cartridge();
|
||||
~Cartridge();
|
||||
|
||||
private:
|
||||
char patchfn[PATH_MAX];
|
||||
char savefn[PATH_MAX];
|
||||
char cheatfn[PATH_MAX];
|
||||
};
|
||||
|
||||
namespace memory {
|
||||
extern MappedRAM cartrom, cartram;
|
||||
extern MappedRAM bscram;
|
||||
extern MappedRAM stArom, stAram;
|
||||
extern MappedRAM stBrom, stBram;
|
||||
};
|
||||
|
||||
extern Cartridge cartridge;
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::load_cart_bsc(const char *base, const char *slot) {
|
||||
if(!base || !*base) return;
|
||||
|
||||
strcpy(cart.fn, base);
|
||||
strcpy(bs.fn, slot ? slot : "");
|
||||
load_begin(CartridgeBSC);
|
||||
|
||||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
load_file(cart.fn, data, size, CompressionAuto);
|
||||
cart.rom = data, cart.rom_size = size;
|
||||
|
||||
if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, cart.rom, cart.rom_size);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
if(*bs.fn) {
|
||||
if(load_file(bs.fn, data, size, CompressionAuto) == true) {
|
||||
info.bsxflash = true;
|
||||
bs.ram = data, bs.ram_size = size;
|
||||
if(load_file(get_patch_filename(bs.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, bs.ram, bs.ram_size);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
find_header();
|
||||
read_header();
|
||||
|
||||
info.mapper = cartridge.info.header_index == 0x7fc0 ? BSCLoROM : BSCHiROM;
|
||||
info.region = NTSC;
|
||||
|
||||
if(info.ram_size > 0) {
|
||||
cart.ram = new uint8_t[cart.ram_size = info.ram_size];
|
||||
memset(cart.ram, 0xff, cart.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(cart.ram, data, min(size, cart.ram_size));
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
load_end();
|
||||
|
||||
//set base filename
|
||||
strcpy(info.filename, cart.fn);
|
||||
get_base_filename(info.filename);
|
||||
if(*bs.fn) {
|
||||
char filenameBS[PATH_MAX];
|
||||
strcpy(filenameBS, bs.fn);
|
||||
get_base_filename(filenameBS);
|
||||
strcat(info.filename, " + ");
|
||||
strcat(info.filename, filenameBS);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::unload_cart_bsc() {
|
||||
if(cart.ram) save_file(get_save_filename(cart.fn, "srm"), cart.ram, cart.ram_size);
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::load_cart_bsx(const char *base, const char *slot) {
|
||||
if(!base || !*base) return;
|
||||
|
||||
strcpy(cart.fn, base);
|
||||
strcpy(bs.fn, slot ? slot : "");
|
||||
|
||||
load_begin(CartridgeBSX);
|
||||
info.bsxbase = true;
|
||||
info.bsxcart = true;
|
||||
info.mapper = BSXROM;
|
||||
info.region = NTSC;
|
||||
|
||||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
load_file(cart.fn, data, size, CompressionAuto);
|
||||
cart.rom = data, cart.rom_size = size;
|
||||
cart.ram = 0, cart.ram_size = 0;
|
||||
|
||||
if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, cart.rom, cart.rom_size);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
memset(bsxcart.sram.handle (), 0x00, bsxcart.sram.size ());
|
||||
memset(bsxcart.psram.handle(), 0x00, bsxcart.psram.size());
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(bsxcart.sram.handle (), data, min(bsxcart.sram.size (), size));
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "psr"), data, size, CompressionNone) == true) {
|
||||
memcpy(bsxcart.psram.handle(), data, min(bsxcart.psram.size(), size));
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
if(*bs.fn) {
|
||||
if(load_file(bs.fn, data, size, CompressionAuto) == true) {
|
||||
info.bsxflash = true;
|
||||
bs.ram = data, bs.ram_size = size;
|
||||
if(load_file(get_patch_filename(bs.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, bs.ram, bs.ram_size);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
load_end();
|
||||
|
||||
strcpy(info.filename, !*bs.fn ? cart.fn : bs.fn);
|
||||
get_base_filename(info.filename);
|
||||
}
|
||||
|
||||
void Cartridge::unload_cart_bsx() {
|
||||
save_file(get_save_filename(cart.fn, "srm"), bsxcart.sram.handle (), bsxcart.sram.size ());
|
||||
save_file(get_save_filename(cart.fn, "psr"), bsxcart.psram.handle(), bsxcart.psram.size());
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,179 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
#include "../reader/filereader.h"
|
||||
|
||||
#if defined(GZIP_SUPPORT)
|
||||
#include "../reader/gzreader.h"
|
||||
#include "../reader/zipreader.h"
|
||||
#endif
|
||||
|
||||
#if defined(JMA_SUPPORT)
|
||||
#include "../reader/jmareader.h"
|
||||
#endif
|
||||
|
||||
char* Cartridge::modify_extension(char *filename, const char *extension) {
|
||||
int i;
|
||||
for(i = strlen(filename); i >= 0; i--) {
|
||||
if(filename[i] == '.') break;
|
||||
if(filename[i] == '/') break;
|
||||
if(filename[i] == '\\') break;
|
||||
}
|
||||
if(i > 0 && filename[i] == '.') filename[i] = 0;
|
||||
strcat(filename, ".");
|
||||
strcat(filename, extension);
|
||||
return filename;
|
||||
}
|
||||
|
||||
//remove directory information and file extension ("/foo/bar.ext" -> "bar")
|
||||
char* Cartridge::get_base_filename(char *filename) {
|
||||
//remove extension
|
||||
for(int i = strlen(filename) - 1; i >= 0; i--) {
|
||||
if(filename[i] == '.') {
|
||||
filename[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//remove directory information
|
||||
for(int i = strlen(filename) - 1; i >= 0; i--) {
|
||||
if(filename[i] == '/' || filename[i] == '\\') {
|
||||
i++;
|
||||
char *output = filename;
|
||||
while(true) {
|
||||
*output++ = filename[i];
|
||||
if(!filename[i]) break;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* Cartridge::get_path_filename(char *filename, const char *path, const char *source, const char *extension) {
|
||||
strcpy(filename, source);
|
||||
for(char *p = filename; *p; p++) { if(*p == '\\') *p = '/'; }
|
||||
modify_extension(filename, extension);
|
||||
|
||||
//override path with user-specified folder, if one was defined
|
||||
if(*path) {
|
||||
lstring part;
|
||||
split(part, "/", filename);
|
||||
string fn = path;
|
||||
if(strend(fn, "/") == false) strcat(fn, "/");
|
||||
strcat(fn, part[count(part) - 1]);
|
||||
strcpy(filename, fn);
|
||||
|
||||
//resolve relative path, if found
|
||||
if(strbegin(fn, "./") == true) {
|
||||
ltrim(fn, "./");
|
||||
strcpy(filename, config::path.base);
|
||||
strcat(filename, fn);
|
||||
}
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
char* Cartridge::get_patch_filename(const char *source, const char *extension) {
|
||||
return get_path_filename(patchfn, config::path.patch, source, extension);
|
||||
}
|
||||
|
||||
char* Cartridge::get_save_filename(const char *source, const char *extension) {
|
||||
return get_path_filename(savefn, config::path.save, source, extension);
|
||||
}
|
||||
|
||||
char* Cartridge::get_cheat_filename(const char *source, const char *extension) {
|
||||
return get_path_filename(cheatfn, config::path.cheat, source, extension);
|
||||
}
|
||||
|
||||
bool Cartridge::load_file(const char *fn, uint8 *&data, uint &size, CompressionMode compression) {
|
||||
dprintf("* Loading \"%s\" ...", fn);
|
||||
|
||||
if(fexists(fn) == false) return false;
|
||||
|
||||
Reader::Type filetype = Reader::Normal;
|
||||
if(compression == CompressionInspect) filetype = Reader::detect(fn, true);
|
||||
if(compression == CompressionAuto) filetype = Reader::detect(fn, config::file.autodetect_type);
|
||||
|
||||
switch(filetype) {
|
||||
default:
|
||||
dprintf("* Warning: filetype detected as unsupported compression type.");
|
||||
dprintf("* Will attempt to load as uncompressed file -- may fail.");
|
||||
case Reader::Normal: {
|
||||
FileReader ff(fn);
|
||||
if(!ff.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = ff.size();
|
||||
data = ff.read();
|
||||
} break;
|
||||
|
||||
#ifdef GZIP_SUPPORT
|
||||
case Reader::GZIP: {
|
||||
GZReader gf(fn);
|
||||
if(!gf.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = gf.size();
|
||||
data = gf.read();
|
||||
} break;
|
||||
|
||||
case Reader::ZIP: {
|
||||
ZipReader zf(fn);
|
||||
size = zf.size();
|
||||
data = zf.read();
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef JMA_SUPPORT
|
||||
case Reader::JMA: {
|
||||
try {
|
||||
JMAReader jf(fn);
|
||||
size = jf.size();
|
||||
data = jf.read();
|
||||
} catch(JMA::jma_errors jma_error) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cartridge::apply_patch(const uint8_t *pdata, const unsigned psize, uint8_t *&data, unsigned &size) {
|
||||
uint8_t *outdata = 0;
|
||||
unsigned outsize;
|
||||
ups patcher;
|
||||
ups::result result = patcher.apply(pdata, psize, data, size, outdata, outsize);
|
||||
|
||||
bool apply = false;
|
||||
if(result == ups::ok) apply = true;
|
||||
if(config::file.bypass_patch_crc32 == true) {
|
||||
if(result == ups::input_crc32_invalid) apply = true;
|
||||
if(result == ups::output_crc32_invalid) apply = true;
|
||||
}
|
||||
|
||||
if(apply == true) {
|
||||
delete[] data;
|
||||
data = new uint8_t[size = outsize];
|
||||
memcpy(data, outdata, outsize);
|
||||
} else {
|
||||
dprintf("* Warning: patch application failed!");
|
||||
}
|
||||
|
||||
if(outdata) delete[] outdata;
|
||||
}
|
||||
|
||||
bool Cartridge::save_file(const char *fn, uint8 *data, uint size) {
|
||||
FILE *fp = fopen(fn, "wb");
|
||||
if(!fp) return false;
|
||||
fwrite(data, 1, size, fp);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,194 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::read_header() {
|
||||
uint8 *rom = cart.rom;
|
||||
uint index = info.header_index;
|
||||
uint8 mapper = rom[index + MAPPER];
|
||||
uint8 rom_type = rom[index + ROM_TYPE];
|
||||
uint8 company = rom[index + COMPANY];
|
||||
uint8 region = rom[index + REGION] & 0x7f;
|
||||
|
||||
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
||||
bool has_bsxflash = false;
|
||||
if(rom[index - 14] == 'Z') {
|
||||
if(rom[index - 11] == 'J') {
|
||||
uint8 n13 = rom[index - 13];
|
||||
if((n13 >= 'A' && n13 <= 'Z') || (n13 >= '0' && n13 <= '9')) {
|
||||
if(company == 0x33 || (rom[index - 10] == 0x00 && rom[index - 4] == 0x00)) {
|
||||
has_bsxflash = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(has_bsxflash == true) {
|
||||
info.mapper = index == 0x7fc0 ? BSCLoROM : BSCHiROM;
|
||||
} else if(index == 0x7fc0 && cart.rom_size >= 0x401000) {
|
||||
info.mapper = ExLoROM;
|
||||
} else if(index == 0x7fc0 && mapper == 0x32) {
|
||||
info.mapper = ExLoROM;
|
||||
} else if(index == 0x7fc0) {
|
||||
info.mapper = LoROM;
|
||||
} else if(index == 0xffc0) {
|
||||
info.mapper = HiROM;
|
||||
} else { //index == 0x40ffc0
|
||||
info.mapper = ExHiROM;
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && (rom_type == 0x13 || rom_type == 0x14 || rom_type == 0x15 || rom_type == 0x1a)) {
|
||||
info.superfx = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x23 && (rom_type == 0x34 || rom_type == 0x35)) {
|
||||
info.sa1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x35 && rom_type == 0x55) {
|
||||
info.srtc = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x32 && (rom_type == 0x43 || rom_type == 0x45)) {
|
||||
info.sdd1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x3a && (rom_type == 0xf5 || rom_type == 0xf9)) {
|
||||
//rom_type: 0xf5 = no S-RTC, 0xf9 = S-RTC
|
||||
info.spc7110 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0xf3) {
|
||||
info.cx4 = true;
|
||||
}
|
||||
|
||||
if((mapper == 0x20 || mapper == 0x21) && rom_type == 0x03) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05 && company != 0xb2) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x31 && (rom_type == 0x03 || rom_type == 0x05)) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(info.dsp1 == true) {
|
||||
if((mapper & 0x2f) == 0x20 && cart.rom_size <= 0x100000) {
|
||||
info.dsp1_mapper = DSP1LoROM1MB;
|
||||
} else if((mapper & 0x2f) == 0x20) {
|
||||
info.dsp1_mapper = DSP1LoROM2MB;
|
||||
} else if((mapper & 0x2f) == 0x21) {
|
||||
info.dsp1_mapper = DSP1HiROM;
|
||||
}
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0x05) {
|
||||
info.dsp2 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05 && company == 0xb2) {
|
||||
info.dsp3 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x03) {
|
||||
info.dsp4 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x25) {
|
||||
info.obc1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0xf6) {
|
||||
//TODO: both ST010 and ST011 share the same mapper + rom_type.
|
||||
//need way to determine which is which.
|
||||
//for now, default to supported ST010.
|
||||
info.st010 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0xf5) {
|
||||
info.st018 = true;
|
||||
}
|
||||
|
||||
if(rom[info.header_index + RAM_SIZE] & 7) {
|
||||
info.ram_size = 1024 << (rom[info.header_index + RAM_SIZE] & 7);
|
||||
} else {
|
||||
info.ram_size = 0;
|
||||
}
|
||||
|
||||
//0, 1, 13 = NTSC; 2 - 12 = PAL
|
||||
info.region = (region <= 1 || region >= 13) ? NTSC : PAL;
|
||||
|
||||
memcpy(&info.name, &rom[info.header_index + CART_NAME], 21);
|
||||
info.name[21] = 0;
|
||||
trim(info.name);
|
||||
|
||||
//convert undisplayable characters (half-width katakana, etc) to '?' characters
|
||||
for(int i = 0; i < 21; i++) {
|
||||
if(info.name[i] & 0x80) info.name[i] = '?';
|
||||
}
|
||||
|
||||
//always display something
|
||||
if(!info.name[0]) strcpy(info.name, "(untitled)");
|
||||
}
|
||||
|
||||
void Cartridge::find_header() {
|
||||
int32 score_lo = 0, score_hi = 0, score_ex = 0;
|
||||
uint8_t *rom = cart.rom;
|
||||
|
||||
if(cart.rom_size < 0x010000) {
|
||||
//cart too small to be anything but lorom
|
||||
info.header_index = 0x007fc0;
|
||||
return;
|
||||
}
|
||||
|
||||
if((rom[0x7fc0 + MAPPER] & ~0x10) == 0x20) score_lo++;
|
||||
if((rom[0xffc0 + MAPPER] & ~0x10) == 0x21) score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + ROM_TYPE] < 0x08) score_lo++;
|
||||
if(rom[0xffc0 + ROM_TYPE] < 0x08) score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + ROM_SIZE] < 0x10) score_lo++;
|
||||
if(rom[0xffc0 + ROM_SIZE] < 0x10) score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + RAM_SIZE] < 0x08) score_lo++;
|
||||
if(rom[0xffc0 + RAM_SIZE] < 0x08) score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + REGION] < 14) score_lo++;
|
||||
if(rom[0xffc0 + REGION] < 14) score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + COMPANY] < 3) score_lo++;
|
||||
if(rom[0xffc0 + COMPANY] < 3) score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + RESH] & 0x80) score_lo += 2;
|
||||
if(rom[0xffc0 + RESH] & 0x80) score_hi += 2;
|
||||
|
||||
uint16 cksum, icksum;
|
||||
cksum = rom[0x7fc0 + CKSUM] | (rom[0x7fc0 + CKSUM + 1] << 8);
|
||||
icksum = rom[0x7fc0 + ICKSUM] | (rom[0x7fc0 + ICKSUM + 1] << 8);
|
||||
if((cksum + icksum) == 0xffff && (cksum != 0) && (icksum != 0)) {
|
||||
score_lo += 8;
|
||||
}
|
||||
|
||||
cksum = rom[0xffc0 + CKSUM] | (rom[0xffc0 + CKSUM + 1] << 8);
|
||||
icksum = rom[0xffc0 + ICKSUM] | (rom[0xffc0 + ICKSUM + 1] << 8);
|
||||
if((cksum + icksum) == 0xffff && (cksum != 0) && (icksum != 0)) {
|
||||
score_hi += 8;
|
||||
}
|
||||
|
||||
if(cart.rom_size < 0x401000) {
|
||||
score_ex = 0;
|
||||
} else {
|
||||
if(rom[0x7fc0 + MAPPER] == 0x32) score_lo++;
|
||||
else score_ex += 16;
|
||||
}
|
||||
|
||||
if(score_lo >= score_hi && score_lo >= score_ex) {
|
||||
info.header_index = 0x007fc0;
|
||||
} else if(score_hi >= score_ex) {
|
||||
info.header_index = 0x00ffc0;
|
||||
} else {
|
||||
info.header_index = 0x40ffc0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::load_cart_normal(const char *filename) {
|
||||
if(!filename || !*filename) return;
|
||||
|
||||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
if(load_file(filename, data, size, CompressionAuto) == false) return;
|
||||
strcpy(cart.fn, filename);
|
||||
|
||||
load_begin(CartridgeNormal);
|
||||
|
||||
//load ROM data, ignore 512-byte header if detected
|
||||
if((size & 0x7fff) != 512) {
|
||||
cart.rom = new uint8_t[cart.rom_size = size];
|
||||
memcpy(cart.rom, data, size);
|
||||
} else {
|
||||
cart.rom = new uint8_t[cart.rom_size = size - 512];
|
||||
memcpy(cart.rom, data + 512, size - 512);
|
||||
}
|
||||
delete[] data;
|
||||
|
||||
if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, cart.rom, cart.rom_size);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
info.crc32 = crc32_calculate(cart.rom, cart.rom_size);
|
||||
|
||||
find_header();
|
||||
read_header();
|
||||
|
||||
if(info.ram_size > 0) {
|
||||
cart.ram = new uint8_t[cart.ram_size = info.ram_size];
|
||||
memset(cart.ram, 0xff, cart.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(cart.ram, data, min(size, cart.ram_size));
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
load_end();
|
||||
|
||||
//set base filename
|
||||
strcpy(info.filename, cart.fn);
|
||||
get_base_filename(info.filename);
|
||||
}
|
||||
|
||||
void Cartridge::unload_cart_normal() {
|
||||
if(cart.ram) save_file(get_save_filename(cart.fn, "srm"), cart.ram, cart.ram_size);
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,96 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::load_cart_st(const char *base, const char *slotA, const char *slotB) {
|
||||
if(!base || !*base) return;
|
||||
|
||||
strcpy(cart.fn, base);
|
||||
strcpy(stA.fn, slotA ? slotA : "");
|
||||
strcpy(stB.fn, slotB ? slotB : "");
|
||||
|
||||
load_begin(CartridgeSufamiTurbo);
|
||||
info.st = true;
|
||||
info.mapper = STROM;
|
||||
info.region = NTSC;
|
||||
|
||||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
if(load_file(cart.fn, data, size, CompressionAuto) == true) {
|
||||
cart.rom = new(zeromemory) uint8_t[cart.rom_size = 0x040000];
|
||||
memcpy(cart.rom, data, min(size, cart.rom_size));
|
||||
delete[] data;
|
||||
if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, cart.rom, cart.rom_size);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
if(*stA.fn) {
|
||||
if(load_file(stA.fn, data, size, CompressionAuto) == true) {
|
||||
stA.rom = new(zeromemory) uint8_t[stA.rom_size = 0x100000];
|
||||
memcpy(stA.rom, data, min(size, stA.rom_size));
|
||||
delete[] data;
|
||||
if(load_file(get_patch_filename(stA.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, stA.rom, stA.rom_size);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
stA.ram = new uint8_t[stA.ram_size = 0x020000];
|
||||
memset(stA.ram, 0xff, stA.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(stA.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(stA.ram, data, min(size, 0x020000U));
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*stB.fn) {
|
||||
if(load_file(stB.fn, data, size, CompressionAuto) == true) {
|
||||
stB.rom = new(zeromemory) uint8_t[stB.rom_size = 0x100000];
|
||||
memcpy(stB.rom, data, min(size, stB.rom_size));
|
||||
delete[] data;
|
||||
if(load_file(get_patch_filename(stB.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, stB.rom, stB.rom_size);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
stB.ram = new uint8_t[stB.ram_size = 0x020000];
|
||||
memset(stB.ram, 0xff, stB.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(stB.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(stB.ram, data, min(size, 0x020000U));
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
load_end();
|
||||
|
||||
//set base filename
|
||||
if(!*stA.fn && !*stB.fn) {
|
||||
strcpy(info.filename, cart.fn);
|
||||
get_base_filename(info.filename);
|
||||
} else if(*stA.fn && !*stB.fn) {
|
||||
strcpy(info.filename, stA.fn);
|
||||
get_base_filename(info.filename);
|
||||
} else if(!*stA.fn && *stB.fn) {
|
||||
strcpy(info.filename, stB.fn);
|
||||
get_base_filename(info.filename);
|
||||
} else {
|
||||
char filenameA[PATH_MAX], filenameB[PATH_MAX];
|
||||
strcpy(filenameA, stA.fn);
|
||||
get_base_filename(filenameA);
|
||||
strcpy(filenameB, stB.fn);
|
||||
get_base_filename(filenameB);
|
||||
strcpy(info.filename, filenameA);
|
||||
strcat(info.filename, " + ");
|
||||
strcat(info.filename, filenameB);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::unload_cart_st() {
|
||||
if(stA.ram) save_file(get_save_filename(stA.fn, "srm"), stA.ram, stA.ram_size);
|
||||
if(stB.ram) save_file(get_save_filename(stB.fn, "srm"), stB.ram, stB.ram_size);
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,3 @@
|
||||
@make platform=win compiler=mingw32-gcc
|
||||
::@make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true
|
||||
@pause
|
||||
@@ -0,0 +1,2 @@
|
||||
make platform=x compiler=gcc
|
||||
#make platform=x compiler=gcc enable_gzip=true enable_jma=true
|
||||
@@ -0,0 +1,329 @@
|
||||
#include "../base.h"
|
||||
#include "../reader/filereader.h"
|
||||
|
||||
Cheat cheat;
|
||||
|
||||
/*****
|
||||
* string <> binary code translation routines
|
||||
* decode() "7e1234:56" -> 0x7e123456
|
||||
* encode() 0x7e123456 -> "7e1234:56"
|
||||
*****/
|
||||
|
||||
bool Cheat::decode(char *str, uint32 &addr, uint8 &data, uint8 &type) {
|
||||
string t, part;
|
||||
strcpy(t, str);
|
||||
strlower(t());
|
||||
if(strlen(t) == 8 || (strlen(t) == 9 && t()[6] == ':')) {
|
||||
type = ProActionReplay;
|
||||
replace(t, ":", "");
|
||||
uint32 r = strhex((const char*)t);
|
||||
addr = r >> 8;
|
||||
data = r & 0xff;
|
||||
return true;
|
||||
} else if(strlen(t) == 9 && t()[4] == '-') {
|
||||
type = GameGenie;
|
||||
replace(t, "-", "");
|
||||
strtr(t, "df4709156bc8a23e", "0123456789abcdef");
|
||||
uint32 r = strhex((const char*)t);
|
||||
//8421 8421 8421 8421 8421 8421
|
||||
//abcd efgh ijkl mnop qrst uvwx
|
||||
//ijkl qrst opab cduv wxef ghmn
|
||||
addr = (!!(r & 0x002000) << 23) | (!!(r & 0x001000) << 22) |
|
||||
(!!(r & 0x000800) << 21) | (!!(r & 0x000400) << 20) |
|
||||
(!!(r & 0x000020) << 19) | (!!(r & 0x000010) << 18) |
|
||||
(!!(r & 0x000008) << 17) | (!!(r & 0x000004) << 16) |
|
||||
(!!(r & 0x800000) << 15) | (!!(r & 0x400000) << 14) |
|
||||
(!!(r & 0x200000) << 13) | (!!(r & 0x100000) << 12) |
|
||||
(!!(r & 0x000002) << 11) | (!!(r & 0x000001) << 10) |
|
||||
(!!(r & 0x008000) << 9) | (!!(r & 0x004000) << 8) |
|
||||
(!!(r & 0x080000) << 7) | (!!(r & 0x040000) << 6) |
|
||||
(!!(r & 0x020000) << 5) | (!!(r & 0x010000) << 4) |
|
||||
(!!(r & 0x000200) << 3) | (!!(r & 0x000100) << 2) |
|
||||
(!!(r & 0x000080) << 1) | (!!(r & 0x000040) << 0);
|
||||
data = r >> 24;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Cheat::encode(char *str, uint32 addr, uint8 data, uint8 type) {
|
||||
if(type == ProActionReplay) {
|
||||
sprintf(str, "%0.6x:%0.2x", addr, data);
|
||||
return true;
|
||||
} else if(type == GameGenie) {
|
||||
uint32 r = addr;
|
||||
addr = (!!(r & 0x008000) << 23) | (!!(r & 0x004000) << 22) |
|
||||
(!!(r & 0x002000) << 21) | (!!(r & 0x001000) << 20) |
|
||||
(!!(r & 0x000080) << 19) | (!!(r & 0x000040) << 18) |
|
||||
(!!(r & 0x000020) << 17) | (!!(r & 0x000010) << 16) |
|
||||
(!!(r & 0x000200) << 15) | (!!(r & 0x000100) << 14) |
|
||||
(!!(r & 0x800000) << 13) | (!!(r & 0x400000) << 12) |
|
||||
(!!(r & 0x200000) << 11) | (!!(r & 0x100000) << 10) |
|
||||
(!!(r & 0x000008) << 9) | (!!(r & 0x000004) << 8) |
|
||||
(!!(r & 0x000002) << 7) | (!!(r & 0x000001) << 6) |
|
||||
(!!(r & 0x080000) << 5) | (!!(r & 0x040000) << 4) |
|
||||
(!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2) |
|
||||
(!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0);
|
||||
sprintf(str, "%0.2x%0.2x-%0.4x", data, addr >> 16, addr & 0xffff);
|
||||
strtr(str, "0123456789abcdef", "df4709156bc8a23e");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*****
|
||||
* address lookup table manipulation and mirroring
|
||||
* mirror_address() 0x000000 -> 0x7e0000
|
||||
* set() enable specified address, mirror accordingly
|
||||
* clear() disable specified address, mirror accordingly
|
||||
*****/
|
||||
|
||||
uint Cheat::mirror_address(uint addr) {
|
||||
if((addr & 0x40e000) != 0x0000) return addr;
|
||||
//8k WRAM mirror
|
||||
//$[00-3f|80-bf]:[0000-1fff] -> $7e:[0000-1fff]
|
||||
return (0x7e0000 + (addr & 0x1fff));
|
||||
}
|
||||
|
||||
void Cheat::set(uint32 addr) {
|
||||
addr = mirror_address(addr);
|
||||
|
||||
mask[addr >> 3] |= 1 << (addr & 7);
|
||||
if((addr & 0xffe000) == 0x7e0000) {
|
||||
//mirror $7e:[0000-1fff] to $[00-3f|80-bf]:[0000-1fff]
|
||||
uint mirror;
|
||||
for(int x = 0; x <= 0x3f; x++) {
|
||||
mirror = ((0x00 + x) << 16) + (addr & 0x1fff);
|
||||
mask[mirror >> 3] |= 1 << (mirror & 7);
|
||||
mirror = ((0x80 + x) << 16) + (addr & 0x1fff);
|
||||
mask[mirror >> 3] |= 1 << (mirror & 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cheat::clear(uint32 addr) {
|
||||
addr = mirror_address(addr);
|
||||
|
||||
//is there more than one cheat code using the same address
|
||||
//(and likely a different override value) that is enabled?
|
||||
//if so, do not clear code lookup table entry for this address.
|
||||
uint8 r;
|
||||
if(read(addr, r) == true)return;
|
||||
|
||||
mask[addr >> 3] &= ~(1 << (addr & 7));
|
||||
if((addr & 0xffe000) == 0x7e0000) {
|
||||
//mirror $7e:[0000-1fff] to $[00-3f|80-bf]:[0000-1fff]
|
||||
uint mirror;
|
||||
for(int x = 0; x <= 0x3f; x++) {
|
||||
mirror = ((0x00 + x) << 16) + (addr & 0x1fff);
|
||||
mask[mirror >> 3] &= ~(1 << (mirror & 7));
|
||||
mirror = ((0x80 + x) << 16) + (addr & 0x1fff);
|
||||
mask[mirror >> 3] &= ~(1 << (mirror & 7));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****
|
||||
* read() is used by MemBus::read() if Cheat::enabled(addr)
|
||||
* returns true to look up cheat code.
|
||||
* returns true if cheat code was found, false if it was not.
|
||||
* when true, cheat code substitution value is stored in data.
|
||||
*****/
|
||||
|
||||
bool Cheat::read(uint32 addr, uint8 &data) {
|
||||
addr = mirror_address(addr);
|
||||
for(int i = 0; i < cheat_count; i++) {
|
||||
if(enabled(i) == false) continue;
|
||||
if(addr == mirror_address(index[i].addr)) {
|
||||
data = index[i].data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//code not found, or code is disabled
|
||||
return false;
|
||||
}
|
||||
|
||||
/*****
|
||||
* update_cheat_status() will scan to see if any codes are
|
||||
* enabled. if any are, make sure the cheat system is on.
|
||||
* otherwise, turn cheat system off to speed up emulation.
|
||||
*****/
|
||||
|
||||
void Cheat::update_cheat_status() {
|
||||
for(unsigned i = 0; i < cheat_count; i++) {
|
||||
if(index[i].enabled) {
|
||||
cheat_enabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cheat_enabled = false;
|
||||
}
|
||||
|
||||
/*****
|
||||
* cheat list manipulation routines
|
||||
*****/
|
||||
|
||||
bool Cheat::add(bool enable, char *code, char *desc) {
|
||||
if(cheat_count >= CheatLimit) return false;
|
||||
|
||||
uint32 addr, len;
|
||||
uint8 data, type;
|
||||
if(decode(code, addr, data, type) == false) return false;
|
||||
|
||||
index[cheat_count].enabled = enable;
|
||||
index[cheat_count].addr = addr;
|
||||
index[cheat_count].data = data;
|
||||
len = strlen(code);
|
||||
len = len > 16 ? 16 : len;
|
||||
memcpy(index[cheat_count].code, code, len);
|
||||
index[cheat_count].code[len] = 0;
|
||||
len = strlen(desc);
|
||||
len = len > 128 ? 128 : len;
|
||||
memcpy(index[cheat_count].desc, desc, len);
|
||||
index[cheat_count].desc[len] = 0;
|
||||
cheat_count++;
|
||||
(enable) ? set(addr) : clear(addr);
|
||||
|
||||
update_cheat_status();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::edit(uint32 n, bool enable, char *code, char *desc) {
|
||||
if(n >= cheat_count) return false;
|
||||
|
||||
uint32 addr, len;
|
||||
uint8 data, type;
|
||||
if(decode(code, addr, data, type) == false) return false;
|
||||
|
||||
//disable current code and clear from code lookup table
|
||||
index[n].enabled = false;
|
||||
clear(index[n].addr);
|
||||
|
||||
//update code and enable in code lookup table
|
||||
index[n].enabled = enable;
|
||||
index[n].addr = addr;
|
||||
index[n].data = data;
|
||||
len = strlen(code);
|
||||
len = len > 16 ? 16 : len;
|
||||
memcpy(index[n].code, code, len);
|
||||
index[n].code[len] = 0;
|
||||
len = strlen(desc);
|
||||
len = len > 128 ? 128 : len;
|
||||
memcpy(index[n].desc, desc, len);
|
||||
index[n].desc[len] = 0;
|
||||
set(addr);
|
||||
|
||||
update_cheat_status();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::remove(uint32 n) {
|
||||
if(n >= cheat_count) return false;
|
||||
|
||||
for(unsigned i = n; i < cheat_count; i++) {
|
||||
index[i].enabled = index[i + 1].enabled;
|
||||
index[i].addr = index[i + 1].addr;
|
||||
index[i].data = index[i + 1].data;
|
||||
strcpy(index[i].desc, index[i + 1].desc);
|
||||
}
|
||||
|
||||
cheat_count--;
|
||||
|
||||
update_cheat_status();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::get(uint32 n, bool &enable, uint32 &addr, uint8 &data, char *code, char *desc) {
|
||||
if(n >= cheat_count) return false;
|
||||
enable = index[n].enabled;
|
||||
addr = index[n].addr;
|
||||
data = index[n].data;
|
||||
strcpy(code, index[n].code);
|
||||
strcpy(desc, index[n].desc);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****
|
||||
* code status modifier routines
|
||||
*****/
|
||||
|
||||
bool Cheat::enabled(uint32 n) {
|
||||
if(n >= cheat_count) return false;
|
||||
return index[n].enabled;
|
||||
}
|
||||
|
||||
void Cheat::enable(uint32 n) {
|
||||
if(n >= cheat_count) return;
|
||||
index[n].enabled = true;
|
||||
set(index[n].addr);
|
||||
update_cheat_status();
|
||||
}
|
||||
|
||||
void Cheat::disable(uint32 n) {
|
||||
if(n >= cheat_count) return;
|
||||
index[n].enabled = false;
|
||||
clear(index[n].addr);
|
||||
update_cheat_status();
|
||||
}
|
||||
|
||||
/*****
|
||||
* cheat file manipulation routines
|
||||
*****/
|
||||
|
||||
/* file format: */
|
||||
/* nnnn-nnnn = status, "description" \r\n */
|
||||
/* ... */
|
||||
|
||||
bool Cheat::load(const char *fn) {
|
||||
string data;
|
||||
if(!fread(data, fn)) return false;
|
||||
replace(data, "\r\n", "\n");
|
||||
qreplace(data, "=", ",");
|
||||
qreplace(data, " ", "");
|
||||
|
||||
lstring line;
|
||||
split(line, "\n", data);
|
||||
for(unsigned i = 0; i < ::count(line); i++) {
|
||||
lstring part;
|
||||
split(part, ",", line[i]);
|
||||
if(::count(part) != 3) continue;
|
||||
trim(part[2], "\"");
|
||||
add(part[1] == "enabled", part[0](), part[2]());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::save(const char *fn) {
|
||||
FILE *fp = fopen(fn, "wb");
|
||||
if(!fp) return false;
|
||||
for(unsigned i = 0; i < cheat_count; i++) {
|
||||
fprintf(fp, "%9s = %8s, \"%s\"\r\n",
|
||||
index[i].code,
|
||||
index[i].enabled ? "enabled" : "disabled",
|
||||
index[i].desc);
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****
|
||||
* initialization routines
|
||||
*****/
|
||||
|
||||
void Cheat::clear() {
|
||||
cheat_enabled = false;
|
||||
cheat_count = 0;
|
||||
memset(mask, 0, 0x200000);
|
||||
for(unsigned i = 0; i <= CheatLimit; i++) {
|
||||
index[i].enabled = false;
|
||||
index[i].addr = 0x000000;
|
||||
index[i].data = 0x00;
|
||||
strcpy(index[i].code, "");
|
||||
strcpy(index[i].desc, "");
|
||||
}
|
||||
}
|
||||
|
||||
Cheat::Cheat() {
|
||||
clear();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
class Cheat {
|
||||
public:
|
||||
enum { CheatLimit = 1024 };
|
||||
|
||||
enum Type {
|
||||
ProActionReplay,
|
||||
GameGenie,
|
||||
};
|
||||
|
||||
struct CheatIndex {
|
||||
bool enabled;
|
||||
uint32 addr;
|
||||
uint8 data;
|
||||
char code[ 16 + 1];
|
||||
char desc[128 + 1];
|
||||
} index[CheatLimit + 1];
|
||||
|
||||
bool cheat_enabled;
|
||||
uint32 cheat_count;
|
||||
uint8 mask[0x200000];
|
||||
|
||||
inline bool enabled() { return cheat_enabled; }
|
||||
inline uint count() { return cheat_count; }
|
||||
inline bool exists(uint32 addr) { return bool(mask[addr >> 3] & 1 << (addr & 7)); }
|
||||
|
||||
bool decode(char *str, uint32 &addr, uint8 &data, uint8 &type);
|
||||
bool encode(char *str, uint32 addr, uint8 data, uint8 type);
|
||||
|
||||
bool read(uint32 addr, uint8 &data);
|
||||
|
||||
void update_cheat_status();
|
||||
bool add(bool enable, char *code, char *desc);
|
||||
bool edit(uint32 n, bool enable, char *code, char *desc);
|
||||
bool get(uint32 n, bool &enable, uint32 &addr, uint8 &data, char *code, char *desc);
|
||||
bool remove(uint32 n);
|
||||
bool enabled(uint32 n);
|
||||
void enable(uint32 n);
|
||||
void disable(uint32 n);
|
||||
bool load(const char *fn);
|
||||
bool save(const char *fn);
|
||||
void clear();
|
||||
|
||||
Cheat();
|
||||
|
||||
private:
|
||||
uint mirror_address(uint addr);
|
||||
void set(uint32 addr);
|
||||
void clear(uint32 addr);
|
||||
};
|
||||
|
||||
extern Cheat cheat;
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "../../base.h"
|
||||
#define BSX_CPP
|
||||
|
||||
#include "bsx_base.cpp"
|
||||
#include "bsx_cart.cpp"
|
||||
#include "bsx_flash.cpp"
|
||||
@@ -0,0 +1,77 @@
|
||||
class BSXBase : public MMIO {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 mmio_read(uint addr);
|
||||
void mmio_write(uint addr, uint8 data);
|
||||
|
||||
private:
|
||||
struct {
|
||||
uint8 r2188, r2189, r218a, r218b;
|
||||
uint8 r218c, r218d, r218e, r218f;
|
||||
uint8 r2190, r2191, r2192, r2193;
|
||||
uint8 r2194, r2195, r2196, r2197;
|
||||
uint8 r2198, r2199, r219a, r219b;
|
||||
uint8 r219c, r219d, r219e, r219f;
|
||||
|
||||
uint8 r2192_counter;
|
||||
uint8 r2192_hour, r2192_minute, r2192_second;
|
||||
} regs;
|
||||
};
|
||||
|
||||
class BSXCart : public MMIO {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 mmio_read(uint addr);
|
||||
void mmio_write(uint addr, uint8 data);
|
||||
|
||||
MappedRAM sram;
|
||||
MappedRAM psram;
|
||||
|
||||
BSXCart();
|
||||
~BSXCart();
|
||||
|
||||
private:
|
||||
uint8 *sram_data; //256kbit SRAM
|
||||
uint8 *psram_data; // 4mbit PSRAM
|
||||
|
||||
struct {
|
||||
uint8 r[16];
|
||||
} regs;
|
||||
|
||||
void update_memory_map();
|
||||
};
|
||||
|
||||
class BSXFlash : public Memory {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint size();
|
||||
uint8 read(uint addr);
|
||||
void write(uint addr, uint8 data);
|
||||
|
||||
private:
|
||||
struct {
|
||||
uint command;
|
||||
uint8 write_old;
|
||||
uint8 write_new;
|
||||
|
||||
bool flash_enable;
|
||||
bool read_enable;
|
||||
bool write_enable;
|
||||
} regs;
|
||||
};
|
||||
|
||||
extern BSXBase bsxbase;
|
||||
extern BSXCart bsxcart;
|
||||
extern BSXFlash bsxflash;
|
||||
@@ -0,0 +1,137 @@
|
||||
#ifdef BSX_CPP
|
||||
|
||||
void BSXBase::init() {
|
||||
}
|
||||
|
||||
void BSXBase::enable() {
|
||||
for(uint16 i = 0x2188; i <= 0x219f; i++) memory::mmio.map(i, *this);
|
||||
}
|
||||
|
||||
void BSXBase::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void BSXBase::reset() {
|
||||
memset(®s, 0x00, sizeof regs);
|
||||
}
|
||||
|
||||
uint8 BSXBase::mmio_read(uint addr) {
|
||||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x2188: return regs.r2188;
|
||||
case 0x2189: return regs.r2189;
|
||||
case 0x218a: return regs.r218a;
|
||||
case 0x218c: return regs.r218c;
|
||||
case 0x218e: return regs.r218e;
|
||||
case 0x218f: return regs.r218f;
|
||||
case 0x2190: return regs.r2190;
|
||||
|
||||
case 0x2192: {
|
||||
uint counter = regs.r2192_counter++;
|
||||
if(regs.r2192_counter >= 18) regs.r2192_counter = 0;
|
||||
|
||||
if(counter == 0) {
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
tm *t = localtime(&rawtime);
|
||||
|
||||
regs.r2192_hour = t->tm_hour;
|
||||
regs.r2192_minute = t->tm_min;
|
||||
regs.r2192_second = t->tm_sec;
|
||||
}
|
||||
|
||||
switch(counter) {
|
||||
case 0: return 0x00; //???
|
||||
case 1: return 0x00; //???
|
||||
case 2: return 0x00; //???
|
||||
case 3: return 0x00; //???
|
||||
case 4: return 0x00; //???
|
||||
case 5: return 0x01;
|
||||
case 6: return 0x01;
|
||||
case 7: return 0x00;
|
||||
case 8: return 0x00;
|
||||
case 9: return 0x00;
|
||||
case 10: return regs.r2192_second;
|
||||
case 11: return regs.r2192_minute;
|
||||
case 12: return regs.r2192_hour;
|
||||
case 13: return 0x00; //???
|
||||
case 14: return 0x00; //???
|
||||
case 15: return 0x00; //???
|
||||
case 16: return 0x00; //???
|
||||
case 17: return 0x00; //???
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x2193: return regs.r2193 & ~0x0c;
|
||||
case 0x2194: return regs.r2194;
|
||||
case 0x2196: return regs.r2196;
|
||||
case 0x2197: return regs.r2197;
|
||||
case 0x2199: return regs.r2199;
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void BSXBase::mmio_write(uint addr, uint8 data) {
|
||||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x2188: {
|
||||
regs.r2188 = data;
|
||||
} break;
|
||||
|
||||
case 0x2189: {
|
||||
regs.r2189 = data;
|
||||
} break;
|
||||
|
||||
case 0x218a: {
|
||||
regs.r218a = data;
|
||||
} break;
|
||||
|
||||
case 0x218b: {
|
||||
regs.r218b = data;
|
||||
} break;
|
||||
|
||||
case 0x218c: {
|
||||
regs.r218c = data;
|
||||
} break;
|
||||
|
||||
case 0x218e: {
|
||||
regs.r218e = data;
|
||||
} break;
|
||||
|
||||
case 0x218f: {
|
||||
regs.r218e >>= 1;
|
||||
regs.r218e = regs.r218f - regs.r218e;
|
||||
regs.r218f >>= 1;
|
||||
} break;
|
||||
|
||||
case 0x2191: {
|
||||
regs.r2191 = data;
|
||||
regs.r2192_counter = 0;
|
||||
} break;
|
||||
|
||||
case 0x2192: {
|
||||
regs.r2190 = 0x80;
|
||||
} break;
|
||||
|
||||
case 0x2193: {
|
||||
regs.r2193 = data;
|
||||
} break;
|
||||
|
||||
case 0x2194: {
|
||||
regs.r2194 = data;
|
||||
} break;
|
||||
|
||||
case 0x2197: {
|
||||
regs.r2197 = data;
|
||||
} break;
|
||||
|
||||
case 0x2199: {
|
||||
regs.r2199 = data;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef BSX_CPP
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifdef BSX_CPP
|
||||
|
||||
void BSXCart::init() {
|
||||
}
|
||||
|
||||
void BSXCart::enable() {
|
||||
for(uint16 i = 0x5000; i <= 0x5fff; i++) memory::mmio.map(i, *this);
|
||||
}
|
||||
|
||||
void BSXCart::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void BSXCart::reset() {
|
||||
for(uint i = 0; i < 16; i++) regs.r[i] = 0x00;
|
||||
regs.r[0x07] = 0x80;
|
||||
regs.r[0x08] = 0x80;
|
||||
|
||||
update_memory_map();
|
||||
}
|
||||
|
||||
void BSXCart::update_memory_map() {
|
||||
Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)psram;
|
||||
|
||||
if((regs.r[0x02] & 0x80) == 0x00) { //LoROM mapping
|
||||
bus.map(Bus::MapLinear, 0x00, 0x7d, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0x80, 0xff, 0x8000, 0xffff, cart);
|
||||
} else { //HiROM mapping
|
||||
bus.map(Bus::MapShadow, 0x00, 0x3f, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0x40, 0x7d, 0x0000, 0xffff, cart);
|
||||
bus.map(Bus::MapShadow, 0x80, 0xbf, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0xc0, 0xff, 0x0000, 0xffff, cart);
|
||||
}
|
||||
|
||||
if(regs.r[0x03] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x60, 0x6f, 0x0000, 0xffff, psram);
|
||||
//bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, psram);
|
||||
}
|
||||
|
||||
if((regs.r[0x05] & 0x80) == 0x00) {
|
||||
bus.map(Bus::MapLinear, 0x40, 0x4f, 0x0000, 0xffff, psram);
|
||||
}
|
||||
|
||||
if((regs.r[0x06] & 0x80) == 0x00) {
|
||||
bus.map(Bus::MapLinear, 0x50, 0x5f, 0x0000, 0xffff, psram);
|
||||
}
|
||||
|
||||
if(regs.r[0x07] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom);
|
||||
}
|
||||
|
||||
if(regs.r[0x08] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom);
|
||||
}
|
||||
|
||||
bus.map(Bus::MapShadow, 0x20, 0x3f, 0x6000, 0x7fff, psram);
|
||||
bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, psram);
|
||||
}
|
||||
|
||||
uint8 BSXCart::mmio_read(uint addr) {
|
||||
if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
return regs.r[n];
|
||||
}
|
||||
|
||||
if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM
|
||||
return sram.read(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff));
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void BSXCart::mmio_write(uint addr, uint8 data) {
|
||||
if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
regs.r[n] = data;
|
||||
if(n == 0x0e && data & 0x80) update_memory_map();
|
||||
return;
|
||||
}
|
||||
|
||||
if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM
|
||||
return sram.write(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff), data);
|
||||
}
|
||||
}
|
||||
|
||||
BSXCart::BSXCart() {
|
||||
sram_data = new uint8_t[ 32 * 1024];
|
||||
psram_data = new uint8_t[512 * 1024];
|
||||
|
||||
sram.map (sram_data, 32 * 1024);
|
||||
psram.map(psram_data, 512 * 1024);
|
||||
}
|
||||
|
||||
BSXCart::~BSXCart() {
|
||||
delete[] sram_data;
|
||||
delete[] psram_data;
|
||||
}
|
||||
|
||||
#endif //ifdef BSX_CPP
|
||||
Loaded 100 of 550 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user