⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.cpp

📁 SNES game emulator. C and asm files.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	"XOR <%b", 2, 3,
	"SHR <%b", 2, 5,
	"XOR [<%b]", 2, 6,
	// 0x48
	"PSH A", 1, 3, // PHA
	"XOR %#", 2, 2,
	"SHR A", 1, 2,
	"PSH PBR", 1, 3, // PHK
	"JMP %w", 3, 3,
	"XOR %w", 3, 4,
	"SHR %w", 3, 6,
	"XOR %L", 4, 5,
	// 0x50
	"BVC @%b", 2, 2,
	"XOR (<%b),Y", 2, 5,
	"XOR (<%b)", 2, 5,
	"XOR (<%b,s),Y", 2, 7,
	"MVN XYA %w", 3, 7,
	"XOR <%b,X", 2, 4,
	"SHR <%b,X", 2, 6,
	"XOR [<%b],Y", 2, 6,
	// 0x58
	"CLI", 1, 2,
	"XOR %w,Y", 3, 4,
	"PSH Y", 1, 3, // PHY
	"TAD", 1, 2,
	"JML %L", 4, 4,
	"XOR %w,X", 3, 4,
	"SHR %w,X", 3, 7,
	"XOR %L,X", 4, 5,
	// 0x60
	"RTS", 1, 6,
	"ADC (<%b,X)", 2, 6,
	"PSH @%w", 3, 6, // PER
	"ADC <%b,s", 2, 4,
	"CLR <%b", 2, 3,
	"ADC <%b", 2, 3,
	"ROR <%b", 2, 5,
	"ADC [<%b]", 2, 6,
	// 0x68
	"PUL A", 1, 4, // PLA
	"ADC %#", 2, 2,
	"ROR A", 1, 2,
	"RTL", 1, 6,
	"JMP (%w)", 3, 5,
	"ADC %w", 3, 4,
	"ROR %w", 3, 6,
	"ADC %L", 4, 5,
	// 0x70
	"BVS @%b", 2, 2,
	"ADC (<%b),Y", 2, 5,
	"ADC (<%b)", 2, 5,
	"ADC (<%b,s),Y", 2, 7,
	"CLR <%b,X", 2, 4,
	"ADC <%b,X", 2, 4,
	"ROR <%b,X", 2, 6,
	"ADC [<%b],Y", 2, 6,
	// 0x78
	"SEI", 1, 2,
	"ADC %w,Y", 3, 4,
	"PUL Y", 1, 4, // PLY
	"TDA", 1, 2,
	"JMP (%w,X)", 3, 6,
	"ADC %w,X", 3,4,
	"ROR %w,X", 3,7,
	"ADC %L,X",4,5,
	// 0x80
	"BRA @%b", 2, 2,
	"STA (<%b,X)", 2, 6,
	"BRL @%w", 3, 3,
	"STA <%b,S", 2, 4,
	"STY <%b", 2, 3,
	"STA <%b", 2, 3,
	"STX <%b", 2, 3,
	"STA [<%b]", 2, 6,
	// 0x88
	"DEY", 1, 2,
	"BIT %#", 2, 2,
	"TXA", 1, 2,
	"PSH DBR", 1, 3, // PHB
	"STY %w", 3, 4,
	"STA %w", 3, 4,
	"STX %w", 3, 4,
	"STA %L", 4, 5,
	// 0x90
	"BCC @%b", 2, 2,
	"STA (<%b),Y", 2, 6,
	"STA (<%b)", 2, 5,
	"STA (<%b,s),Y", 2, 7,
	"STY <%b,X", 2, 4,
	"STA <%b,X", 2, 4,
	"STX <%b,Y", 2, 4,
	"STA [<%b],Y", 2, 6,
	// 0x98
	"TYA", 1, 2,
	"STA %w,Y", 3, 5,
	"TXS", 1, 2,
	"TXY", 1, 2,
	"CLR %w", 3, 4,
	"STA %w,X", 3, 5,
	"CLR %w,X", 3, 5,
	"STA %L,X", 4, 5,
	// 0xA0
	"LDY %#i", 2, 2,
	"LDA (<%b,X)", 2, 6,
	"LDX %#i", 2, 2,
	"LDA <%b,S", 2, 4,
	"LDY <%b", 2, 3,
	"LDA <%b", 2, 3,
	"LDX <%b", 2, 3,
	"LDA [<%b]", 2, 6,
	// 0xA8
	"TAY", 1, 2,
	"LDA %#", 2, 2,
	"TAX", 1, 2,
	"PUL DBR", 1, 4, // PLB
	"LDY %w", 3, 4,
	"LDA %w", 3, 4,
	"LDX %w", 3, 4,
	"LDA %L", 4, 5,
	// 0xB0
	"BCS @%b", 2, 2,
	"LDA (<%b),Y", 2, 5,
	"LDA (<%b)", 2, 5,
	"LDA (<%b,S),Y", 2, 7,
	"LDY <%b,X", 2, 4,
	"LDA <%b,X", 2, 4,
	"LDX <%b,Y", 2, 4,
	"LDA [<%b],Y", 2, 6,
	// 0xB8
	"CLV", 1, 2,
	"LDA %w,Y", 3, 4,
	"TSX", 1, 2,
	"TYX", 1, 2,
	"LDY %w,X", 3, 4,
	"LDA %w,X", 3, 4,
	"LDX %w,Y", 3, 4,
	"LDA %L,X",4, 5,
	// 0xC0
	"CPY %#i", 2, 2,
	"CMP (<%b,X)", 2, 6,
	"CLP %#b", 2, 3,
	"CMP <%b,S", 2, 4,
	"CPY <%b", 2, 3,
	"CMP <%b", 2, 3,
	"DEC <%b", 2, 5,
	"CMP [<%b]", 2,6,
	// 0xC8
	"INY", 1, 2,
	"CMP %#", 2, 2,
	"DEX", 1, 2,
	"WAI", 1, 3,
	"CPY %w", 3, 4,
	"CMP %w", 3, 4,
	"DEC %w", 3, 6,
	"CMP %L", 4, 5,
	// 0xD0
	"BNE @%b", 2, 2,
	"CMP (<%b),Y", 2, 5,
	"CMP (<%b)", 2, 5,
	"CMP (<%b,S),Y", 2, 7,
	"PSH %b", 2, 6, // PEI
	"CMP <%b,X", 2, 4,
	"DEC <%b,X", 2, 6,
	"CMP [<%b],Y", 2, 6,
	// 0xD8
	"CLD", 1, 2,
	"CMP %w,Y", 3, 4,
	"PSH X", 1, 3, // PHX
	"HLT", 1, 3, // STP
	"JML (%w)", 3, 6,
	"CMP %w,X", 3, 4,
	"DEC %w,X", 3, 7,
	"CMP %L,X", 4, 5,
	// 0xE0
	"CPX %#i", 2, 2,
	"SBC (<%b,X)", 2, 6,
	"SEP %#b", 2, 3,
	"SBC <%b,s", 2, 4,
	"CPX <%b", 2, 3,
	"SBC <%b", 2, 3,
	"INC <%b", 2, 5,
	"SBC [<%b]", 2, 6,
	// 0xE8
	"INX", 1, 2,
	"SBC %#", 2, 2,
	"NOP", 1, 2,
	"SWA", 1, 3,
	"CPX %w", 3, 4,
	"SBC %w", 3, 4,
	"INC %w", 3, 6,
	"SBC %L", 4, 5,
	// 0xF0
	"BEQ @%b", 2, 2,
	"SBC (<%b),Y", 2, 5,
	"SBC (<%b)", 2, 5,
	"SBC (<%b,S),Y", 2, 7,
	"PSH %#w", 3, 5, // PEA
	"SBC <%b,X", 2, 4,
	"INC <%b,X", 2, 6,
	"SBC [<%b],Y", 2, 6,
	// 0xF8
	"SED", 1, 2,
	"SBC %w,Y", 3, 4,
	"PUL X", 1, 4, // PLX
	"XCE", 1, 2,
	"JSR (%w,X)", 3, 6,
	"SBC %w,X", 3, 4,
	"INC %w,X", 3, 7,
	"SBC %L,X", 4, 5
};

// ADDRESSING MODES - several categories, one mode from each category can be combined
// None of the instructions can use all combinations, and certain combinations are
// never used with any instruction.
	// Used to calculate memory address:
	//   Absolute: Argument is two bytes and specifies a memory location
	//     + Long: Argument is three bytes instead             opcode $addr
	//   Direct: Argument is one byte; memory address formed by adding D.
	//     Bank is always 0, unless indirect addressing is also used, in
	//     which case the bank is the program bank.            opcode <$addr
	//   Stack Relative: Argument is one byte, which is added to the stack pointer
	//     to find the final address.                          opcode $addr,S
	// Indexed addressing:
	//   Indexed: Memory location argument is added to X or Y to get the final
	//     memory location.                                    opcode $addr,X or Y
	//   Note that certain indexed addressing modes only work with the X register
	//     or only with the Y register.
	//
	// Note! The above addressing mode specifiers are used only to specify the
	// size of the argument and how it is used.  The specifiers DO NOT SPECIFY
	// anything about the actual memory location being referenced.
	// For example, suppose the Absolute Indexed mode is used.  This means that
	// the argument to the opcode is 16 bits and will be added to an index
	// register.  It does not, however, mean that the value at the calculated
	// memory location will be a 16-bit value.  The size of the value at the memory
	// location is determined by either:
	//   a. whether the processor is in 16-bit mode (and whether E=0), or
	//   b. if indirect addressing is used, whether the Long Indirect mode is used.
	//
	// Indirect addressing:
	//   Indirect: Uses indirection (pointers).  In other words, after the memory
	//     location is found and the contents are loaded, the contents are used as
	//     a SECOND memory location and the value at the second memory location is
	//     used in the operation.                              opcode ($addr)
	//     + Direct Long: Normally, the pointer found at the specified location
	//       will be two bytes.  If Direct Indirect Long is used, the pointer
	//       at the memory address found will be a three-byte long address.
	//                                                         opcode [$addr]
	// Indexed Indirect (preindexed; (arg,x)) vs. Indirect Indexed (postindexed;
	// (arg),x): remember, these two are different!
// There is also two more modes, which are never used with any other specifiers:
	// Implied: Opcode has no arguments (The "accumulator" addressing mode is like
	//   an implied mode and it means it acts on the accumulator only.)
	// Immediate: The argument specifies an actual constant value to be used,
	//   rather than a memory address. [opcode #$XX or #$XXXX]
	//   some immediate addressing modes always have a 8-bit argument (CLP, SEP);
	//   others have an 8/16 bit argument depending on the status of the M bit;
	//   others have an 8/16 bit argument depending on the status of the X bit.
	//   (When the programmer writes a immediate addressing instruction he must make
	//   sure the assembler knows what size to make it!)

#define AA_ROM (byte *)0x1
#define AA_HIROM (byte *)0x2
//#define AA_LOROM_x40 (byte *)0x3
#define AA_NOTHING (byte *)0x4
	// Placeholder in the addressarea array, needed since the rom variable is initialized to NULL

/*struct addressarea { // old mem map based on Duncanthrax's doc
	// this is a representation of the SNES memory map. It's used by the getstartaddresses()
	// function to build the address mapping table, *startaddr[].
	byte b1, b2;
	word a1, a2;
	byte *start;
	boolean continuous;
} loromarea [] = {
	{ 0x00, 0x3F, 0x0000, 0x1FFF, ram,             },
	{ 0x00, 0x3F, 0x2000, 0x5FFF, registers,       },
	{ 0x00, 0x3F, 0x6000, 0x7FFF, expram,          },
	{ 0x00, 0x3F, 0x8000, 0xFFFF, AA_ROM,    true  },
	{ 0x40, 0x7C, 0x0000, 0x7FFF, AA_ROM,    true  },
	{ 0x40, 0x7C, 0x8000, 0xFFFF, AA_ROM,    true  },
	{ 0x7D, 0x7D, 0x0000, 0xFFFF, sram,            },
	{ 0x7E, 0x7F, 0x0000, 0xFFFF, ram,       true  },

	{ 0x80, 0xBF, 0x0000, 0x1FFF, ram,             },
	{ 0x80, 0xBF, 0x2000, 0x5FFF, registers,       },
	{ 0x80, 0xBF, 0x6000, 0x7FFF, expram,          },
	{ 0x80, 0xBF, 0x8000, 0xFFFF, AA_ROM,    true  },
	{ 0xC0, 0xFC, 0x0000, 0x7FFF, AA_ROM,    true  },
	{ 0xC0, 0xFC, 0x8000, 0xFFFF, AA_ROM,    true  },
	{ 0xFD, 0xFD, 0x0000, 0xFFFF, sram,            },
	{ 0xFE, 0xFF, 0x0000, 0xFFFF, ram,       true  },
	{ 0 }
}, hiromarea [] = {
	{ 0x00, 0x3F, 0x0000, 0x1FFF, ram,             },
	{ 0x00, 0x3F, 0x2000, 0x5FFF, registers,       },
	{ 0x00, 0x3F, 0x6000, 0x7FFF, sram,            },
	{ 0x00, 0x3F, 0x8000, 0xFFFF, AA_ROM,    true  },
	{ 0x40, 0x7D, 0x0000, 0xFFFF, AA_ROM,    true  },
	{ 0x7E, 0x7F, 0x0000, 0xFFFF, ram,       true  },

	{ 0x80, 0xBF, 0x0000, 0x1FFF, ram,             },
	{ 0x80, 0xBF, 0x2000, 0x5FFF, registers,       },
	{ 0x80, 0xBF, 0x6000, 0x7FFF, sram,            },
	{ 0x80, 0xBF, 0x8000, 0xFFFF, AA_ROM,    true  },
	{ 0xC0, 0xFF, 0x0000, 0xFFFF, AA_ROM,    true  },
	{ 0 }
};*/

struct addressarea {
	// this is a representation of the SNES memory map. It's used by the getstartaddresses()
	// function to build the address mapping table, *startaddr[].
	byte b1, b2;
	word a1, a2;
	byte *start;
	boolean continuous;
	word spacing;
} loromarea [] = {
	{ 0x00, 0x3F, 0x0000, 0x1FFF, ram,             },
	{ 0x00, 0x3F, 0x2000, 0x5FFF, registers,       },
	{ 0x00, 0x3F, 0x6000, 0x7FFF, expram,          },
	{ 0x00, 0x6F, 0x8000, 0xFFFF, AA_ROM,    true  },
	{ 0x40, 0x6F, 0x0000, 0x7FFF, AA_NOTHING       },
	{ 0x70, 0x77, 0x0000, 0xFFFF, sram             },
	{ 0x78, 0x7D, 0x0000, 0xFFFF, AA_NOTHING       },
	{ 0x7E, 0x7F, 0x0000, 0xFFFF, ram,       true  },

	{ 0x80, 0xBF, 0x0000, 0x1FFF, ram,             },
	{ 0x80, 0xBF, 0x2000, 0x5FFF, registers,       },
	{ 0x80, 0xBF, 0x6000, 0x7FFF, expram,          },
	{ 0x80, 0xEF, 0x8000, 0xFFFF, AA_ROM,    true  },
	{ 0xC0, 0xEF, 0x0000, 0x7FFF, AA_NOTHING       },
	{ 0xF0, 0xF7, 0x0000, 0xFFFF, sram             },
	{ 0xF8, 0xFD, 0x0000, 0xFFFF, AA_NOTHING       },
	{ 0xFE, 0xFF, 0x0000, 0xFFFF, ram,       true  },
	{ 0 }
}, hiromarea [] = {
	{ 0x00, 0x3F, 0x0000, 0x1FFF, ram,             },
	{ 0x00, 0x3F, 0x2000, 0x5FFF, registers,       },
	{ 0x00, 0x2F, 0x6000, 0x7FFF, expram,          },
	{ 0x30, 0x3F, 0x6000, 0x7FFF, sram,      true  },
	{ 0x00, 0x3F, 0x8000, 0xFFFF, AA_HIROM,  true, 0x8000 },
	{ 0x40, 0x6F, 0x0000, 0xFFFF, AA_ROM,    true  },
	{ 0x70, 0x77, 0x0000, 0xFFFF, sram             },
	{ 0x78, 0x7D, 0x0000, 0xFFFF, AA_NOTHING       },
	{ 0x7E, 0x7F, 0x0000, 0xFFFF, ram,       true  },

	{ 0x80, 0xBF, 0x0000, 0x1FFF, ram,             },
	{ 0x80, 0xBF, 0x2000, 0x5FFF, registers,       },
	{ 0x80, 0xAF, 0x6000, 0x7FFF, expram,          },
	{ 0xB0, 0xBF, 0x6000, 0x7FFF, sram,      true  },
	{ 0x80, 0xBF, 0x8000, 0xFFFF, AA_HIROM,  true, 0x8000 },
	{ 0xC0, 0xFF, 0x0000, 0xFFFF, AA_ROM,    true  },
	{ 0 }
};

void getstartaddresses (boolean hirom)
{
	int x, i;
	int b, a; // bank, address
	struct addressarea *aa;

	if (hirom) aa = hiromarea;
	else aa = loromarea;
	for (x = 0; aa[x].start != NULL; x++) {
		if (aa[x].start == AA_ROM)
			aa[x].start = rom;
		if (aa[x].start == AA_HIROM)
			aa[x].start = rom + 0x8000;
		//if (aa[x].start == AA_ROM_x40)
		//	aa[x].start = rom + 0x40*0x8000;
		if (aa[x].start == AA_NOTHING)
			aa[x].start = expram;
	}
	for (i = 0; i <= 0x7FF; i++) {
			// Get bank and address
		b = (i >> 3);
		a = (i & 7) << 13;
			// Find which of the address areas that bb.aaaa is part of
		for (x = 0; aa[x].start != NULL; x++) {
			if (b >= aa[x].b1 && b <= aa[x].b2 && a >= aa[x].a1 && a <= aa[x].a2)
				break;
		}
		startaddr [i] = (aa[x].start + (a - aa[x].a1));
		if (aa[x].continuous)
			startaddr [i] += (b - aa[x].b1) * (aa[x].a2 - aa[x].a1 + 1 + aa[x].spacing);
		assert (aa[x].start != NULL);
			// Map that address to the array specified by start.
		//debug0 ("Mapping memory: %X.%X->%P[%X]", b, a, aa[x].start, startaddr [i]-aa[x].start);
	}
}

void resetsystem (boolean warmreset)
{
	int x;

	if (!romloaded) return;
	getstartaddresses (ishirom());
	if (warmreset) {
		//reg.S = (reg.S & 0xFF) | 0x100;
		reg.S = 0x1FF;
		//*(byte*)SNESMEM(reg.S) = (byte)(reg.PC >> 16); (*(word*)&reg.S)--;
		//*(word*)SNESMEM(reg.S-1) = (word)reg.PC; (*(word*)&reg.S) -= 2;
		//*(byte*)SNESMEM(reg.S) = (byte)(reg.P); (*(word*)&reg.S)--;
	} else {
		reg.S = 0x1FF;
		dealloc_autobacktrack();
		if (autobacktrack)
			alloc_autobacktrack(backtracknum);
	}
	reg.D_dummy = 0x0000;
	reg.P_dummy = 0x34; //|= 0x34; // 0011 0100
	//reg.P &= ~BCD;
	reg.A_dummy = 0;
	reg.X_dummy = 0; //&= 0xFF;
	reg.Y_dummy = 0; //&= 0xFF;
	reg.E_dummy = true;
	reg.PC = curheader.resetvector; //| (curheader.fastrom ? 0x800000 : 0);
	debug0 ("reg.PC = %LX", reg.PC);
	reg.DBR_dummy1 = reg.DBR_dummy2 = reg.DBR = reg.DBR_dummy3 = 0;
	romrunning = false;
	total_frames = 0;
	debug_instr = 0;

	memset (ram, 0, sizeof (ram));
	memset (registers, 0, sizeof (registers));
	memset (expram, 0, sizeof (expram));
	memset (vram, 0, sizeof (vram));
	memset (oam, 0, sizeof (oam));
	memset (cgram, 0, sizeof (cgram));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -