📄 cpu.c
字号:
/* gameplaySP * * Copyright (C) 2006 Exophase <exophase@gmail.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */// Important todo:// - stm reglist writeback when base is in the list needs adjustment// - block memory needs psr swapping and user mode reg swapping#include <stdio.h>#include "common.h"u32 memory_region_access_read_u8[16];u32 memory_region_access_read_s8[16];u32 memory_region_access_read_u16[16];u32 memory_region_access_read_s16[16];u32 memory_region_access_read_u32[16];u32 memory_region_access_write_u8[16];u32 memory_region_access_write_u16[16];u32 memory_region_access_write_u32[16];u32 memory_reads_u8;u32 memory_reads_s8;u32 memory_reads_u16;u32 memory_reads_s16;u32 memory_reads_u32;u32 memory_writes_u8;u32 memory_writes_u16;u32 memory_writes_u32;const u8 bit_count[256] ={ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};#define arm_decode_data_proc_reg() \ u32 rn = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 rm = opcode & 0x0F \#define arm_decode_data_proc_imm() \ u32 rn = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 imm; \ ror(imm, opcode & 0xFF, ((opcode >> 8) & 0x0F) * 2) \#define arm_decode_psr_reg() \ u32 psr_field = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 rm = opcode & 0x0F \#define arm_decode_psr_imm() \ u32 psr_field = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 imm; \ ror(imm, opcode & 0xFF, ((opcode >> 8) & 0x0F) * 2) \#define arm_decode_branchx() \ u32 rn = opcode & 0x0F \#define arm_decode_multiply() \ u32 rd = (opcode >> 16) & 0x0F; \ u32 rn = (opcode >> 12) & 0x0F; \ u32 rs = (opcode >> 8) & 0x0F; \ u32 rm = opcode & 0x0F \#define arm_decode_multiply_long() \ u32 rdhi = (opcode >> 16) & 0x0F; \ u32 rdlo = (opcode >> 12) & 0x0F; \ u32 rn = (opcode >> 8) & 0x0F; \ u32 rm = opcode & 0x0F \#define arm_decode_swap() \ u32 rn = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 rm = opcode & 0x0F \#define arm_decode_half_trans_r() \ u32 rn = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 rm = opcode & 0x0F \#define arm_decode_half_trans_of() \ u32 rn = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 offset = ((opcode >> 4) & 0xF0) | (opcode & 0x0F) \#define arm_decode_data_trans_imm() \ u32 rn = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 offset = opcode & 0x0FFF \#define arm_decode_data_trans_reg() \ u32 rn = (opcode >> 16) & 0x0F; \ u32 rd = (opcode >> 12) & 0x0F; \ u32 rm = opcode & 0x0F \#define arm_decode_block_trans() \ u32 rn = (opcode >> 16) & 0x0F; \ u32 reg_list = opcode & 0xFFFF \#define arm_decode_branch() \ s32 offset = ((s32)(opcode & 0xFFFFFF) << 8) >> 6 \#define calculate_z_flag(dest) \ z_flag = (dest == 0) \#define calculate_n_flag(dest) \ n_flag = ((signed)dest < 0) \#define calculate_c_flag_sub(dest, src_a, src_b) \ c_flag = ((unsigned)src_b <= (unsigned)src_a) \#define calculate_v_flag_sub(dest, src_a, src_b) \ v_flag = ((signed)src_b > (signed)src_a) != ((signed)dest < 0) \#define calculate_c_flag_add(dest, src_a, src_b) \ c_flag = ((unsigned)dest < (unsigned)src_a) \#define calculate_v_flag_add(dest, src_a, src_b) \ v_flag = ((signed)dest < (signed)src_a) != ((signed)src_b < 0) \#define get_shift_register(dest) \ u32 shift = reg[(opcode >> 8) & 0x0F]; \ dest = reg[rm]; \ if(rm == 15) \ dest += 4 \#define calculate_reg_sh() \ u32 reg_sh; \ switch((opcode >> 4) & 0x07) \ { \ /* LSL imm */ \ case 0x0: \ { \ reg_sh = reg[rm] << ((opcode >> 7) & 0x1F); \ break; \ } \ \ /* LSL reg */ \ case 0x1: \ { \ get_shift_register(reg_sh); \ if(shift <= 31) \ reg_sh = reg_sh << shift; \ else \ reg_sh = 0; \ break; \ } \ \ /* LSR imm */ \ case 0x2: \ { \ u32 imm = (opcode >> 7) & 0x1F; \ if(imm == 0) \ reg_sh = 0; \ else \ reg_sh = reg[rm] >> imm; \ break; \ } \ \ /* LSR reg */ \ case 0x3: \ { \ get_shift_register(reg_sh); \ if(shift <= 31) \ reg_sh = reg_sh >> shift; \ else \ reg_sh = 0; \ break; \ } \ \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -