diff --git a/desmume/src/MMU.c b/desmume/src/MMU.c new file mode 100644 index 000000000..ee8702b0c --- /dev/null +++ b/desmume/src/MMU.c @@ -0,0 +1,2182 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//#define RENDER3D + +#include +#include +#include + +#include "debug.h" +#include "NDSSystem.h" +#include "windows/cflash.h" + +#include "nds/interrupts.h" +#include "nds/video.h" +#include "nds/system.h" +#include "nds/serial.h" +#include "nds/card.h" + +#define ROM_MASK 3 + +//#define LOG_CARD +//#define LOG_GPU +//#define LOG_DMA +//#define LOG_DMA2 +//#define LOG_DIV + +extern BOOL execute; +extern BOOL click; +extern NDSSystem nds; + +char szRomPath[512]; + +MMU_struct MMU; + +u8 * MMU_ARM9_MEM_MAP[256]={ + //0X + ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, + //1X + //ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, ARM9Mem.ARM9_ITCM, + ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, ARM9Mem.ARM9_WRAM, + //2X + ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, + //3x + MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, + //4X + ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, ARM9Mem.ARM9_REG, + //5X + ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, ARM9Mem.ARM9_VMEM, + //60 61 + ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, + //62 63 + ARM9Mem.ARM9_BBG, ARM9Mem.ARM9_BBG, + //64 65 + ARM9Mem.ARM9_AOBJ, ARM9Mem.ARM9_AOBJ, + //66 67 + ARM9Mem.ARM9_BOBJ, ARM9Mem.ARM9_BOBJ, + //68 69 .. + ARM9Mem.ARM9_LCD, ARM9Mem.ARM9_LCD, ARM9Mem.ARM9_LCD, ARM9Mem.ARM9_LCD, ARM9Mem.ARM9_LCD, ARM9Mem.ARM9_LCD, ARM9Mem.ARM9_LCD, ARM9Mem.ARM9_LCD, + //7X + ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, ARM9Mem.ARM9_OAM, + //8X + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + //9X + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + //AX + MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, + //BX + //CX + //DX + //EX + //FX + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, ARM9Mem.ARM9_BIOS, +}; + +u32 MMU_ARM9_MEM_MASK[256]={ + //0X + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + //1X + 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, + //0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + //2x + 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, + //3X + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + //4X + 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, + //5X + 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, + //60 61 + 0x7FFFF, 0x7FFFF, + //62 63 + 0x1FFFF, 0x1FFFF, + //64 65 + 0x3FFFF, 0x3FFFF, + //66 67 + 0x1FFFF, 0x1FFFF, + //68 69 .... + 0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF, + //7X + 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x7FF, + //8X + ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, + //9x + ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, + //AX + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + //BX + //CX + //DX + //EX + //FX + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x0003, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, +}; + +u8 * MMU_ARM7_MEM_MAP[256]={ + //0X + MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, MMU.ARM7_BIOS, + //1X + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + //2X + ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, ARM9Mem.MAIN_MEM, + //30 - 37 + MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, MMU.SWIRAM, + //38 - 3F + MMU.ARM7_ERAM, MMU.ARM7_ERAM, MMU.ARM7_ERAM, MMU.ARM7_ERAM, MMU.ARM7_ERAM, MMU.ARM7_ERAM, MMU.ARM7_ERAM, MMU.ARM7_ERAM, + //40 - 47 + MMU.ARM7_REG, MMU.ARM7_REG, MMU.ARM7_REG, MMU.ARM7_REG, MMU.ARM7_REG, MMU.ARM7_REG, MMU.ARM7_REG, MMU.ARM7_REG, + //48 - 4F + MMU.ARM7_WIRAM, MMU.ARM7_WIRAM, MMU.ARM7_WIRAM, MMU.ARM7_WIRAM, MMU.ARM7_WIRAM, MMU.ARM7_WIRAM, MMU.ARM7_WIRAM, MMU.ARM7_WIRAM, + //5X + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + //6X + ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, ARM9Mem.ARM9_ABG, + //7X + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + //8X + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + //9X + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + //AX + MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, MMU.CART_RAM, + //BX + //CX + //DX + //EX + //FX + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, + MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, MMU.UNUSED_RAM, +}; + +u32 MMU_ARM7_MEM_MASK[256]={ + //0X + 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, 0x3FFF, + //1X + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + //2x + 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, 0x3FFFFF, + //30 - 37 + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + //38 - 3F + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + //40 - 47 + 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, + //48 - 4F + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + //5X + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + //6X + 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, 0x3FFFF, + //7X + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + //8X + ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, + //9x + ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, ROM_MASK, + //AX + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + //BX + //CX + //DX + //EX + //FX + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, +}; + +u32 MMU_ARM9_WAIT16[16]={ + 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1, +}; + +u32 MMU_ARM9_WAIT32[16]={ + 1, 1, 1, 1, 1, 2, 2, 1, 8, 8, 5, 1, 1, 1, 1, 1, +}; + +u32 MMU_ARM7_WAIT16[16]={ + 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1, +}; + +u32 MMU_ARM7_WAIT32[16]={ + 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 5, 1, 1, 1, 1, 1, +}; + +void MMUInit(void) { + int i; + + LOG("MMU init\n"); + + memset(&MMU, 0, sizeof(MMU_struct)); + + MMU.CART_ROM = MMU.UNUSED_RAM; + + for(i = 0x80; i<0xA0; ++i) + { + MMU_ARM9_MEM_MAP[i] = MMU.CART_ROM; + MMU_ARM7_MEM_MAP[i] = MMU.CART_ROM; + } + + MMU.MMU_MEM[0] = MMU_ARM9_MEM_MAP; + MMU.MMU_MEM[1] = MMU_ARM7_MEM_MAP; + MMU.MMU_MASK[0]= MMU_ARM9_MEM_MASK; + MMU.MMU_MASK[1] = MMU_ARM7_MEM_MASK; + + MMU.ITCMRegion = 0x00800000; + + MMU.MMU_WAIT16[0] = MMU_ARM9_WAIT16; + MMU.MMU_WAIT16[1] = MMU_ARM7_WAIT16; + MMU.MMU_WAIT32[0] = MMU_ARM9_WAIT32; + MMU.MMU_WAIT32[1] = MMU_ARM7_WAIT32; + + for(i = 0;i < 16;i++) + FIFOInit(MMU.fifos + i); + + fw_init(&MMU.spi7.fw); /* init fw device */ + fw_alloc(&MMU.spi7.fw, NDS_FW_SIZE_V1); + +} + +void MMUDeInit(void) { + LOG("MMU deinit\n"); +} + +//Card rom & ram + +u16 SPI_CNT = 0; +u16 SPI_CMD = 0; + +u32 rom_mask = 0; + +u32 DMASrc[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}}; +u32 DMADst[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}}; + + +void MMU_setRom(u8 * rom, u32 mask) +{ + unsigned int i; + MMU.CART_ROM = rom; + + for(i = 0x80; i<0xA0; ++i) + { + MMU_ARM9_MEM_MAP[i] = rom; + MMU_ARM7_MEM_MAP[i] = rom; + MMU_ARM9_MEM_MASK[i] = mask; + MMU_ARM7_MEM_MASK[i] = mask; + } + rom_mask = mask; +} + +void MMU_unsetRom() +{ + unsigned int i; + MMU.CART_ROM=MMU.UNUSED_RAM; + + for(i = 0x80; i<0xA0; ++i) + { + MMU_ARM9_MEM_MAP[i] = MMU.UNUSED_RAM; + MMU_ARM7_MEM_MAP[i] = MMU.UNUSED_RAM; + MMU_ARM9_MEM_MASK[i] = ROM_MASK; + MMU_ARM7_MEM_MASK[i] = ROM_MASK; + } + rom_mask = ROM_MASK; +} +char txt[80]; + +u8 FASTCALL MMU_read8(u32 proc, u32 adr) +{ + if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==MMU.DTCMRegion)) + { + return ARM9Mem.ARM9_DTCM[adr&0x3FFF]; + } + + // CFlash reading, Mic + if ((adr>=0x9000000)&&(adr<0x9900000)) + return (unsigned char)cflash_read(adr); + + adr &= 0x0FFFFFFF; + switch(adr) + { + case 0x027FFCDC : + return 0x20; + case 0x027FFCDD : + return 0x20; + case 0x027FFCE2 : + //execute = FALSE; + return 0xE0; + case 0x027FFCE3 : + return 0x80; + /*case 0x04000300 : + return 1; + case 0x04000208 : + execute = FALSE;*/ + default : + return MMU.MMU_MEM[proc][(adr>>20)&0xFF][adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF]]; + } +} + + + +u16 FASTCALL MMU_read16(u32 proc, u32 adr) +{ + if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion)) + { + /* Returns data from DTCM (ARM9 only) */ + return ((u16 *)ARM9Mem.ARM9_DTCM)[(adr&0x3FFF)>>1]; + } + + // CFlash reading, Mic + if ((adr>=0x08800000)&&(adr<0x09900000)) + return (unsigned short)cflash_read(adr); + + adr &= 0x0FFFFFFF; + + if((adr>>24)==4) + { + /* Adress is an IO register */ + switch(adr) + { + case 0x04100000 : /* TODO (clear): ??? */ + execute = FALSE; + return 1; + + case REG_IME : + return (u16)MMU.reg_IME[proc]; + + case REG_IE : + return (u16)MMU.reg_IE[proc]; + case REG_IE + 2 : + return (u16)(MMU.reg_IE[proc]>>16); + + case REG_IF : + return (u16)MMU.reg_IF[proc]; + case REG_IF + 2 : + return (u16)(MMU.reg_IF[proc]>>16); + + case 0x04000100 : + case 0x04000104 : + case 0x04000108 : + case 0x0400010C : + return MMU.timer[proc][(adr&0xF)>>2]; + + case 0x04000630 : + LOG("vect res\r\n"); /* TODO (clear): ??? */ + //execute = FALSE; + return 0; + //case 0x27FFFAA : + //case 0x27FFFAC : + /*case 0x2330F84 : + if(click) execute = FALSE;*/ + //case 0x27FF018 : execute = FALSE; + case 0x04000300 : + return 1; + default : + break; + } + } + else + { + /* TODO (clear): i don't known what are these 'registers', perhaps reset vectors ... */ + switch(adr) + { + case 0x027FFCD8 : + return (0x20<<4); + case 0x027FFCDA : + return (0x20<<4); + case 0x027FFCDE : + return (0xE0<<4); + case 0x027FFCE0 : + //execute = FALSE; + return (0x80<<4); + default : + break; + } + } + + /* Returns data from memory */ + return ((u16 *)(MMU.MMU_MEM[proc][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>1]; +} + +u32 FASTCALL MMU_read32(u32 proc, u32 adr) +{ + if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion)) + { + /* Returns data from DTCM (ARM9 only) */ + return ((u32 *)ARM9Mem.ARM9_DTCM)[(adr&0x3FFF)>>2]; + } + + // CFlash reading, Mic + if ((adr>=0x9000000)&&(adr<0x9900000)) + return (unsigned long)cflash_read(adr); + + adr &= 0x0FFFFFFF; + + if((adr >> 24) == 4) + { + /* Adress is an IO register */ + switch(adr) + { + #ifdef RENDER3D + case 0x04000600 : + return ((OGLRender::nbpush[0]&1)<<13) | ((OGLRender::nbpush[2]&0x1F)<<8); + #endif + + case REG_IME : + return MMU.reg_IME[proc]; + case REG_IE : + return MMU.reg_IE[proc]; + case REG_IF : + return MMU.reg_IF[proc]; + + case 0x04100000 : + { + u16 IPCFIFO_CNT = ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x184>>1]; + if(IPCFIFO_CNT&0x8000) + { + //execute = FALSE; + u32 fifonum = IPCFIFO+proc; + u32 val = FIFOValue(MMU.fifos + fifonum); + u32 remote = (proc+1) & 1; + u16 IPCFIFO_CNT_remote = ((u16 *)(MMU.MMU_MEM[remote][0x40]))[0x184>>1]; + IPCFIFO_CNT |= (MMU.fifos[fifonum].empty<<8) | (MMU.fifos[fifonum].full<<9) | (MMU.fifos[fifonum].error<<14); + IPCFIFO_CNT_remote |= (MMU.fifos[fifonum].empty) | (MMU.fifos[fifonum].full<<1); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x184>>1] = IPCFIFO_CNT; + ((u16 *)(MMU.MMU_MEM[remote][0x40]))[0x184>>1] = IPCFIFO_CNT_remote; + if(MMU.fifos[fifonum].empty) + MMU.reg_IF[proc] |= ((IPCFIFO_CNT & (1<<2))<<15);// & (MMU.reg_IME[proc]<<17);// & (MMU.reg_IE[proc] & (1<<17));// + return val; + } + } + return 0; + case 0x04000100 : + case 0x04000104 : + case 0x04000108 : + case 0x0400010C : + { + u32 val = (((u16 *)(MMU.MMU_MEM[proc][0x40]))[((adr+2)&0xFFF)>>1]); + return MMU.timer[proc][(adr&0xF)>>2] | (val<<16); + } + case 0x04000640 : /* TODO (clear): again, ??? */ + LOG("read proj\r\n"); + return 0; + case 0x04000680 : + LOG("read roat\r\n"); + return 0; + case 0x04000620 : + LOG("point res\r\n"); + return 0; + + case CARD_DATA_RD: + { + if(!MMU.dscard[proc].adress) return 0; + + //u32 val = ((u32 *)MMU.CART_ROM)[MMU.dscard[proc].adress >> 2]; + u32 val = ROM_32(MMU.CART_ROM, MMU.dscard[proc].adress); /* get data from rom */ + + MMU.dscard[proc].adress += 4; /* increment adress */ + + MMU.dscard[proc].transfer_count--; /* update transfer counter */ + if(MMU.dscard[proc].transfer_count) /* if transfer is not ended */ + { + return val; /* return data */ + } + else /* transfer is done */ + { + MEM_32(MMU.MMU_MEM[proc], CARD_CR2) &= ~(CARD_DATA_READY | CARD_ACTIVATE); /* we're done, edit control register */ + /* = 0x7f7fffff */ + + /* if needed, throw irq for the end of transfer */ + if(MEM_16(MMU.MMU_MEM[proc], CARD_CR1) & CARD_CR1_IRQ) + { + if(proc == ARMCPU_ARM7) NDS_makeARM7Int(IRQ_CARD); + else NDS_makeARM9Int(IRQ_CARD); + } + + return val; + } + } + + default : + break; + } + } + + /* Returns data from memory */ + return ((u32 *)(MMU.MMU_MEM[proc][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>2]; +} + +void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val) +{ + if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion)) + { + /* Writes data in DTCM (ARM9 only) */ + ARM9Mem.ARM9_DTCM[adr&0x3FFF] = val; + return ; + } + + // CFlash writing, Mic + if ((adr>=0x9000000)&&(adr<0x9900000)) { + cflash_write(adr,val); + return; + } + + adr &= 0x0FFFFFFF; + + switch(adr) + { + /* TODO: EEEK ! Controls for VRAMs A, B, C, D are missing ! */ + /* TODO: Not all mappings of VRAMs are handled... (especially BG and OBJ modes) */ + case VRAM_E_CR : + if(proc == ARMCPU_ARM9) + { + if((val & 7) == VRAM_E_BG_EXT_PALETTE) + { + ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x80000; + ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x82000; + ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x84000; + ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x86000; + } + else if((val & 7) == VRAM_E_TEX_PALETTE) + { + ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x80000; + ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x82000; + ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x84000; + ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x86000; + } + } + break; + + case VRAM_F_CR : + if(proc == ARMCPU_ARM9) + { + switch(val & 0x1F) + { + case VRAM_F_BG_EXT_PALETTE : + ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x90000; + ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x92000; + break; + + case VRAM_F_BG_EXT_PALETTE | VRAM_OFFSET(1) : + ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x90000; + ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x92000; + break; + + case VRAM_F_TEX_PALETTE : + ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x90000; + break; + + case VRAM_F_TEX_PALETTE | VRAM_OFFSET(1) : + ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x90000; + break; + + case VRAM_F_TEX_PALETTE | VRAM_OFFSET(2) : + ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x90000; + break; + + case VRAM_F_TEX_PALETTE | VRAM_OFFSET(3) : + ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x90000; + break; + + case VRAM_F_OBJ_EXT_PALETTE : + case VRAM_F_OBJ_EXT_PALETTE | VRAM_OFFSET(1) : + case VRAM_F_OBJ_EXT_PALETTE | VRAM_OFFSET(2) : + case VRAM_F_OBJ_EXT_PALETTE | VRAM_OFFSET(3) : + ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x90000; + ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x92000; + break; + } + } + break; + case VRAM_G_CR : + if(proc == ARMCPU_ARM9) + { + switch(val & 0x1F) + { + case VRAM_G_BG_EXT_PALETTE : + ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x94000; + ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x96000; + break; + + case VRAM_G_BG_EXT_PALETTE | VRAM_OFFSET(1) : + ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x94000; + ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x96000; + break; + + case VRAM_G_TEX_PALETTE : + ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x94000; + break; + + case VRAM_G_TEX_PALETTE | VRAM_OFFSET(1) : + ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x94000; + break; + + case VRAM_G_TEX_PALETTE | VRAM_OFFSET(2) : + ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x94000; + break; + + case VRAM_G_TEX_PALETTE | VRAM_OFFSET(3) : + ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x94000; + break; + + case VRAM_G_OBJ_EXT_PALETTE : + case VRAM_G_OBJ_EXT_PALETTE | VRAM_OFFSET(1) : + case VRAM_G_OBJ_EXT_PALETTE | VRAM_OFFSET(2) : + case VRAM_G_OBJ_EXT_PALETTE | VRAM_OFFSET(3) : + ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x94000; + ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x96000; + break; + } + } + break; + + case VRAM_H_CR : + if(proc == ARMCPU_ARM9) + { + if((val & 7) == VRAM_H_SUB_BG_EXT_PALETTE) + { + ARM9Mem.ExtPal[1][0] = ARM9Mem.ARM9_LCD + 0x98000; + ARM9Mem.ExtPal[1][1] = ARM9Mem.ARM9_LCD + 0x9A000; + ARM9Mem.ExtPal[1][2] = ARM9Mem.ARM9_LCD + 0x9C000; + ARM9Mem.ExtPal[1][3] = ARM9Mem.ARM9_LCD + 0x9E000; + } + } + break; + + case VRAM_I_CR : + if(proc == ARMCPU_ARM9) + { + if((val & 7) == VRAM_I_SUB_SPRITE_EXT_PALETTE) + { + ARM9Mem.ObjExtPal[1][0] = ARM9Mem.ARM9_LCD + 0xA0000; + ARM9Mem.ObjExtPal[1][1] = ARM9Mem.ARM9_LCD + 0xA2000; + } + } + break; + +#ifdef LOG_CARD + case 0x040001A0 : /* TODO (clear): ??? */ + case 0x040001A1 : + case 0x040001A2 : + case 0x040001A8 : + case 0x040001A9 : + case 0x040001AA : + case 0x040001AB : + case 0x040001AC : + case 0x040001AD : + case 0x040001AE : + case 0x040001AF : + LOG("%08X : %02X\r\n", adr, val); +#endif + + default : + break; + } + + MMU.MMU_MEM[proc][(adr>>20)&0xFF][adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF]]=val; +} + +u16 partie = 1; + +void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val) +{ + if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion)) + { + /* Writes in DTCM (ARM9 only) */ + ((u16 *)ARM9Mem.ARM9_DTCM)[(adr&0x3FFF)>>1] = val; + return; + } + + // CFlash writing, Mic + if ((adr>=0x08800000)&&(adr<0x09900000)) + { + cflash_write(adr,val); + return; + } + + adr &= 0x0FFFFFFF; + + if((adr >> 24) == 4) + { + /* Adress is an IO register */ + switch(adr) + { + #ifdef RENDER3D + case 0x04000610 : + if(proc == ARMCPU_ARM9) + { + LOG("CUT DEPTH %08X\r\n", val); + } + return; + case 0x04000340 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glAlphaFunc(val); + } + return; + case 0x04000060 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glControl(val); + } + return; + case 0x04000354 : + if(proc == ARMCPU_ARM9) + OGLRender::glClearDepth(val); + return; + #endif + + case POWER_CR : + if(proc == ARMCPU_ARM9) + { + if(val & (1<<15)) + { + LOG("Main core on top\n"); + MainScreen.offset = 0; + SubScreen.offset = 192; + //nds.swapScreen(); + } + else + { + LOG("Main core on bottom (%04X)\n", val); + MainScreen.offset = 192; + SubScreen.offset = 0; + } + } + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x304>>1] = val; + return; + case REG_SPICNT : + if(proc == ARMCPU_ARM7) + { + SPI_CNT = val; + + //MMU.spi7.fw.com == 0; /* reset fw device communication */ + + fw_reset_com(&MMU.spi7.fw); /* reset fw device communication */ + + } + + MEM_16(MMU.MMU_MEM[proc], REG_SPICNT) = val; + return; + + case REG_SPIDATA : + if(proc==ARMCPU_ARM7) + { + if(val!=0) + { + SPI_CMD = val; + } + + u16 spicnt = MEM_16(MMU.MMU_MEM[proc], REG_SPICNT); + + switch(spicnt & 0x300) + { + case SPI_DEVICE_POWER : + break; + + case SPI_DEVICE_NVRAM : /* firmware memory device */ + if(SPI_BAUD_MASK(spicnt) != SPI_BAUD_4MHz) /* check SPI baudrate (must be 4mhz) */ + { + MEM_16(MMU.MMU_MEM[proc], REG_SPIDATA) = 0; + break; + } + MEM_16(MMU.MMU_MEM[proc], REG_SPIDATA) = fw_transfer(&MMU.spi7.fw, val); /* transfer data to fw chip and receive back */ + return; + + case SPI_DEVICE_TOUCH: + switch(SPI_CMD & 0x70) + { + case 0x00 : + val = 0; + break; + case 0x10 : + //execute = FALSE; + if(SPI_CNT&(1<<11)) + { + if(partie) + { + val = ((nds.touchY<<3)&0x7FF); + partie = 0; + //execute = FALSE; + break; + } + val = (nds.touchY>>5); + partie = 1; + break; + } + val = ((nds.touchY<<3)&0x7FF); + partie = 1; + break; + case 0x20 : + val = 0; + break; + case 0x30 : + val = 0; + break; + case 0x40 : + val = 0; + break; + case 0x50 : + if(spicnt & SPI_CONTINUOUS) + { + if(partie) + { + val = ((nds.touchX<<3)&0x7FF); + partie = 0; + break; + } + val = (nds.touchX>>5); + partie = 1; + break; + } + val = ((nds.touchX<<3)&0x7FF); + partie = 1; + break; + case 0x60 : + val = 0; + break; + case 0x70 : + val = 0; + break; + } + break; + + case 0x300 : + /* NOTICE: Device 3 of SPI is reserved (unused and unusable) */ + break; + } + } + + MEM_16(MMU.MMU_MEM[proc], REG_SPIDATA) = val; + return; + + /* NOTICE: Perhaps we have to use gbatek-like reg names instead of libnds-like ones ...*/ + + case BG0_X0 : + GPU_scrollX(MainScreen.gpu, 0, val); + return; + case BG1_X0 : + GPU_scrollX(MainScreen.gpu, 1, val); + return; + case BG2_X0 : + GPU_scrollX(MainScreen.gpu, 2, val); + return; + case BG3_X0 : + GPU_scrollX(MainScreen.gpu, 3, val); + return; + case SUB_BG0_X0 : + GPU_scrollX(SubScreen.gpu, 0, val); + return; + case SUB_BG1_X0 : + GPU_scrollX(SubScreen.gpu, 1, val); + return; + case SUB_BG2_X0 : + GPU_scrollX(SubScreen.gpu, 2, val); + return; + case SUB_BG3_X0 : + GPU_scrollX(SubScreen.gpu, 3, val); + return; + case BG0_Y0 : + GPU_scrollY(MainScreen.gpu, 0, val); + return; + case BG1_Y0 : + GPU_scrollY(MainScreen.gpu, 1, val); + return; + case BG2_Y0 : + GPU_scrollY(MainScreen.gpu, 2, val); + return; + case BG3_Y0 : + GPU_scrollY(MainScreen.gpu, 3, val); + return; + case SUB_BG0_Y0 : + GPU_scrollY(SubScreen.gpu, 0, val); + return; + case SUB_BG1_Y0 : + GPU_scrollY(SubScreen.gpu, 1, val); + return; + case SUB_BG2_Y0 : + GPU_scrollY(SubScreen.gpu, 2, val); + return; + case SUB_BG3_Y0 : + GPU_scrollY(SubScreen.gpu, 3, val); + return; + case BG2_XDX : + GPU_setPA(MainScreen.gpu, 2, val); + return; + case BG2_XDY : + GPU_setPB(MainScreen.gpu, 2, val); + return; + case BG2_YDX : + GPU_setPC(MainScreen.gpu, 2, val); + return; + case BG2_YDY : + GPU_setPD(MainScreen.gpu, 2, val); + return; + case SUB_BG2_XDX : + GPU_setPA(SubScreen.gpu, 2, val); + return; + case SUB_BG2_XDY : + GPU_setPB(SubScreen.gpu, 2, val); + return; + case SUB_BG2_YDX : + GPU_setPC(SubScreen.gpu, 2, val); + return; + case SUB_BG2_YDY : + GPU_setPD(SubScreen.gpu, 2, val); + return; + case BG3_XDX : + GPU_setPA(MainScreen.gpu, 3, val); + return; + case BG3_XDY : + GPU_setPB(MainScreen.gpu, 3, val); + return; + case BG3_YDX : + GPU_setPC(MainScreen.gpu, 3, val); + return; + case BG3_YDY : + GPU_setPD(MainScreen.gpu, 3, val); + return; + case SUB_BG3_XDX : + GPU_setPA(SubScreen.gpu, 3, val); + return; + case SUB_BG3_XDY : + GPU_setPB(SubScreen.gpu, 3, val); + return; + case SUB_BG3_YDX : + GPU_setPC(SubScreen.gpu, 3, val); + return; + case SUB_BG3_YDY : + GPU_setPD(SubScreen.gpu, 3, val); + return; + case BG2_CX : + GPU_setXL(MainScreen.gpu, 2, val); + return; + case BG2_CX + 2 : + GPU_setXH(MainScreen.gpu, 2, val); + return; + case SUB_BG2_CX : + GPU_setXL(SubScreen.gpu, 2, val); + return; + case SUB_BG2_CX + 2 : + GPU_setXH(SubScreen.gpu, 2, val); + return; + case BG3_CX : + GPU_setXL(MainScreen.gpu, 3, val); + return; + case BG3_CX + 2 : + GPU_setXH(MainScreen.gpu, 3, val); + return; + case SUB_BG3_CX : + GPU_setXL(SubScreen.gpu, 3, val); + return; + case SUB_BG3_CX + 2 : + GPU_setXH(SubScreen.gpu, 3, val); + return; + case BG2_CY : + GPU_setYL(MainScreen.gpu, 2, val); + return; + case BG2_CY + 2 : + GPU_setYH(MainScreen.gpu, 2, val); + return; + case SUB_BG2_CY : + GPU_setYL(SubScreen.gpu, 2, val); + return; + case SUB_BG2_CY + 2 : + GPU_setYH(SubScreen.gpu, 2, val); + return; + case BG3_CY : + GPU_setYL(MainScreen.gpu, 3, val); + return; + case BG3_CY + 2 : + GPU_setYH(MainScreen.gpu, 3, val); + return; + case SUB_BG3_CY : + GPU_setYL(SubScreen.gpu, 3, val); + return; + case SUB_BG3_CY + 2 : + GPU_setYH(SubScreen.gpu, 3, val); + return; + case BG0_CR : + GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val); + GPU_setBGProp(MainScreen.gpu, 0, val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x8>>1] = val; + return; + case BG1_CR : + GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val); + GPU_setBGProp(MainScreen.gpu, 1, val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0xA>>1] = val; + return; + case BG2_CR : + GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val); + GPU_setBGProp(MainScreen.gpu, 2, val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0xC>>1] = val; + return; + case BG3_CR : + GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val); + GPU_setBGProp(MainScreen.gpu, 3, val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0xE>>1] = val; + return; + case SUB_BG0_CR : + GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val); + GPU_setBGProp(SubScreen.gpu, 0, val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x1008>>1] = val; + return; + case SUB_BG1_CR : + GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val); + GPU_setBGProp(SubScreen.gpu, 1, val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x100A>>1] = val; + return; + case SUB_BG2_CR : + GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val); + GPU_setBGProp(SubScreen.gpu, 2, val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x100C>>1] = val; + return; + case SUB_BG3_CR : + GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val); + GPU_setBGProp(SubScreen.gpu, 3, val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x100E>>1] = val; + return; + + case REG_IME : + MMU.reg_IME[proc] = val&1; + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x208>>1] = val; + return; + + case REG_IE : + MMU.reg_IE[proc] = (MMU.reg_IE[proc]&0xFFFF0000) | val; + return; + case REG_IE + 2 : + execute = FALSE; + MMU.reg_IE[proc] = (MMU.reg_IE[proc]&0xFFFF) | (((u32)val)<<16); + return; + + case REG_IF : + execute = FALSE; + MMU.reg_IF[proc] &= (~((u32)val)); + return; + case REG_IF + 2 : + execute = FALSE; + MMU.reg_IF[proc] &= (~(((u32)val)<<16)); + return; + + case 0x04000180 : + { + u32 remote = (proc+1)&1; + u16 IPCSYNC_remote = ((u16 *)(MMU.MMU_MEM[remote][0x40]))[0x180>>1]; + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x180>>1] = (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF); + ((u16 *)(MMU.MMU_MEM[remote][0x40]))[0x180>>1] = (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF); + MMU.reg_IF[remote] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU.reg_IME[remote] << 16);// & (MMU.reg_IE[remote] & (1<<16));// + //execute = FALSE; + } + return; + case 0x04000184 : + { + if(val & 0x4008) + { + FIFOInit(MMU.fifos + (IPCFIFO+((proc+1)&1))); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x184>>1] = (val & 0xBFF4) | 1; + ((u16 *)(MMU.MMU_MEM[(proc+1)&1][0x40]))[0x184>>1] |= (1<<8); + MMU.reg_IF[proc] |= ((val & 4)<<15);// & (MMU.reg_IME[proc]<<17);// & (MMU.reg_IE[proc]&0x20000);// + return; + } + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x184>>1] |= (val & 0xBFF4); + } + return; + case 0x04000100 : + case 0x04000104 : + case 0x04000108 : + case 0x0400010C : + MMU.timerReload[proc][(adr>>2)&3] = val; + return; + case 0x04000102 : + case 0x04000106 : + case 0x0400010A : + case 0x0400010E : + if(val&0x80) + { + if(!(val&4)) MMU.timer[proc][((adr-2)>>2)&0x3] = MMU.timerReload[proc][((adr-2)>>2)&0x3]; + else MMU.timer[proc][((adr-2)>>2)&0x3] = 0; + } + MMU.timerON[proc][((adr-2)>>2)&0x3] = val & 0x80; + switch(val&7) + { + case 0 : + MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 0+1;//proc; + break; + case 1 : + MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 6+1;//proc; + break; + case 2 : + MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 8+1;//proc; + break; + case 3 : + MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 10+1;//proc; + break; + default : + MMU.timerMODE[proc][((adr-2)>>2)&0x3] = 0xFFFF; + break; + } + if(!(val & 0x80)) + MMU.timerRUN[proc][((adr-2)>>2)&0x3] = FALSE; + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[(adr&0xFFF)>>1] = val; + return; + case 0x04000002 : + { + //execute = FALSE; + u32 v = (((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x0>>2]&0xFFFF)|((u32)val<<16); + GPU_setVideoProp(MainScreen.gpu, v); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x0>>2] = v; + } + return; + case 0x04000000 : + { + u32 v = (((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x0]&0xFFFF0000)|val; + GPU_setVideoProp(MainScreen.gpu, v); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x0] = v; + } + return; + case 0x04001002 : + { + //execute = FALSE; + u32 v = (((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x1000>>2]&0xFFFF)|((u32)val<<16); + GPU_setVideoProp(SubScreen.gpu, v); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x1000>>2] = v; + } + return; + case 0x04001000 : + { + u32 v = (((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x1000>>2]&0xFFFF0000)|val; + GPU_setVideoProp(SubScreen.gpu, v); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x1000>>2] = v; + } + return; + //case 0x020D8460 : + /*case 0x0235A904 : + LOG("ECRIRE %d %04X\r\n", proc, val); + execute = FALSE;*/ + case 0x040000BA : + { + //if(val&0x8000) execute = FALSE; + //LOG("16 bit dma0 %04X\r\n", val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0xBA>>1] = val; + DMASrc[proc][0] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xB0>>2]; + DMADst[proc][0] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xB4>>2]; + u32 v = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xB8>>2]; + MMU.DMAStartTime[proc][0] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7); + MMU.DMACrt[proc][0] = v; + if(MMU.DMAStartTime[proc][0] == 0) + MMU_doDMA(proc, 0); + #ifdef LOG_DMA2 + //else + { + LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 0, DMASrc[proc][0], DMADst[proc][0], (val&(1<<25))?"ON":"OFF"); + } + #endif + } + return; + case 0x040000C6 : + { + //if(val&0x8000) execute = FALSE; + //LOG("16 bit dma1 %04X\r\n", val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0xC6>>1] = val; + DMASrc[proc][1] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xBC>>2]; + DMADst[proc][1] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xC0>>2]; + u32 v = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xC4>>2]; + MMU.DMAStartTime[proc][1] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7); + MMU.DMACrt[proc][1] = v; + if(MMU.DMAStartTime[proc][1] == 0) + MMU_doDMA(proc, 1); + #ifdef LOG_DMA2 + //else + { + LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 1, DMASrc[proc][1], DMADst[proc][1], (val&(1<<25))?"ON":"OFF"); + } + #endif + } + return; + case 0x040000D2 : + { + //if(val&0x8000) execute = FALSE; + //LOG("16 bit dma2 %04X\r\n", val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0xD2>>1] = val; + DMASrc[proc][2] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xC8>>2]; + DMADst[proc][2] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xCC>>2]; + u32 v = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xD0>>2]; + MMU.DMAStartTime[proc][2] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7); + MMU.DMACrt[proc][2] = v; + if(MMU.DMAStartTime[proc][2] == 0) + MMU_doDMA(proc, 2); + #ifdef LOG_DMA2 + //else + { + LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 2, DMASrc[proc][2], DMADst[proc][2], (val&(1<<25))?"ON":"OFF"); + } + #endif + } + return; + case 0x040000DE : + { + //if(val&0x8000) execute = FALSE; + //LOG("16 bit dma3 %04X\r\n", val); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0xDE>>1] = val; + DMASrc[proc][3] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xD4>>2]; + DMADst[proc][3] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xD8>>2]; + u32 v = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xDC>>2]; + MMU.DMAStartTime[proc][3] = (proc ? (v>>28) & 0x3 : (v>>27) & 0x7); + MMU.DMACrt[proc][3] = v; + + if(MMU.DMAStartTime[proc][3] == 0) + MMU_doDMA(proc, 3); + #ifdef LOG_DMA2 + //else + { + LOG("proc %d, dma %d src %08X dst %08X %s\r\n", proc, 3, DMASrc[proc][3], DMADst[proc][3], (val&(1<<25))?"ON":"OFF"); + } + #endif + } + return; + //case 0x040001A0 : execute = FALSE; + default : + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>1]=val; + return; + } + } + ((u16 *)(MMU.MMU_MEM[proc][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>1]=val; +} + +u32 testval = 0; + +void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val) +{ + if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==MMU.DTCMRegion)) + { + ((u32 *)ARM9Mem.ARM9_DTCM)[(adr&0x3FFF)>>2] = val; + return ; + } + + // CFlash writing, Mic + if ((adr>=0x9000000)&&(adr<0x9900000)) { + cflash_write(adr,val); + return; + } + + adr &= 0x0FFFFFFF; + + if((adr>>24)==4) + { + switch(adr) + { +#ifdef RENDER3D + case 0x040004AC : + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4AC>>2] = val; + if(proc==ARMCPU_ARM9) + OGLRender::glTexImage2D(testval, TRUE); + //execute = FALSE; + return; + case 0x040004A8 : + if(proc==ARMCPU_ARM9) + { + OGLRender::glTexImage2D(val, FALSE); + //execute = FALSE; + testval = val; + } + return; + case 0x04000488 : + if(proc==ARMCPU_ARM9) + { + OGLRender::glTexCoord(val); + //execute = FALSE; + } + return; + case 0x0400046C : + if(proc==ARMCPU_ARM9) + { + OGLRender::glScale(val); + } + return; + case 0x04000490 : + if(proc==ARMCPU_ARM9) + { + //GPULOG("VERTEX 10 %d\r\n",val); + } + return; + case 0x04000494 : + if(proc==ARMCPU_ARM9) + { + //GPULOG(printf(txt, "VERTEXY %d\r\n",val); + } + return; + case 0x04000498 : + if(proc==ARMCPU_ARM9) + { + //GPULOG("VERTEXZ %d\r\n",val); + } + return; + case 0x0400049C : + if(proc==ARMCPU_ARM9) + { + //GPULOG("VERTEYZ %d\r\n",val); + } + return; + case 0x04000400 : + if(proc==ARMCPU_ARM9) + { + OGLRender::glCallList(val); + } + return; + case 0x04000450 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glRestore(); + } + return; + case 0x04000580 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glViewPort(val); + } + return; + case 0x04000350 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glClearColor(val); + } + return; + case 0x04000440 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glMatrixMode(val); + } + return; + case 0x04000458 : + if(proc == ARMCPU_ARM9) + { + OGLRender::ML4x4ajouter(val); + } + return; + case 0x0400044C : + if(proc == ARMCPU_ARM9) + { + OGLRender::glStoreMatrix(val); + } + return; + case 0x0400045C : + if(proc == ARMCPU_ARM9) + { + OGLRender::ML4x3ajouter(val); + } + return; + case 0x04000444 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glPushMatrix(); + } + return; + case 0x04000448 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glPopMatrix(val); + } + return; + case 0x04000470 : + if(proc == ARMCPU_ARM9) + { + OGLRender::addTrans(val); + } + return; + case 0x04000460 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glMultMatrix4x4(val); + } + return; + case 0x04000464 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glMultMatrix4x3(val); + } + return; + case 0x04000468 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glMultMatrix3x3(val); + } + return; + case 0x04000500 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glBegin(val); + } + return; + case 0x04000504 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glEnd(); + } + return; + case 0x04000480 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glColor3b(val); + } + return; + case 0x0400048C : + if(proc == ARMCPU_ARM9) + { + OGLRender::glVertex3(val); + } + return; + case 0x04000540 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glFlush(); + } + return; + case 0x04000454 : + if(proc == ARMCPU_ARM9) + { + OGLRender::glLoadIdentity(); + } + return; +#endif + case 0x04000020 : + GPU_setPAPB(MainScreen.gpu, 2, val); + return; + case 0x04000024 : + GPU_setPCPD(MainScreen.gpu, 2, val); + return; + case 0x04001020 : + GPU_setPAPB(SubScreen.gpu, 2, val); + return; + case 0x04001024 : + GPU_setPCPD(SubScreen.gpu, 2, val); + return; + case 0x04000030 : + GPU_setPAPB(MainScreen.gpu, 3, val); + return; + case 0x04000034 : + GPU_setPCPD(MainScreen.gpu, 3, val); + return; + case 0x04001030 : + GPU_setPAPB(SubScreen.gpu, 3, val); + return; + case 0x04001034 : + GPU_setPCPD(SubScreen.gpu, 3, val); + return; + case 0x04000028 : + GPU_setX(MainScreen.gpu, 2, val); + return; + case 0x0400002C : + GPU_setY(MainScreen.gpu, 2, val); + return; + case 0x04001028 : + GPU_setX(SubScreen.gpu, 2, val); + return; + case 0x0400102C : + GPU_setY(SubScreen.gpu, 2, val); + return; + case 0x04000038 : + GPU_setX(MainScreen.gpu, 3, val); + return; + case 0x0400003C : + GPU_setY(MainScreen.gpu, 3, val); + return; + case 0x04001038 : + GPU_setX(SubScreen.gpu, 3, val); + return; + case 0x0400103C : + GPU_setY(SubScreen.gpu, 3, val); + return; + case 0x04000010 : + GPU_scrollXY(MainScreen.gpu, 0, val); + return; + case 0x04000014 : + GPU_scrollXY(MainScreen.gpu, 1, val); + return; + case 0x04000018 : + GPU_scrollXY(MainScreen.gpu, 2, val); + return; + case 0x0400001C : + GPU_scrollXY(MainScreen.gpu, 3, val); + return; + case 0x04001010 : + GPU_scrollXY(SubScreen.gpu, 0, val); + return; + case 0x04001014 : + GPU_scrollXY(SubScreen.gpu, 1, val); + return; + case 0x04001018 : + GPU_scrollXY(SubScreen.gpu, 2, val); + return; + case 0x0400101C : + GPU_scrollXY(SubScreen.gpu, 3, val); + return; + case 0x04000000 : + GPU_setVideoProp(MainScreen.gpu, val); + + GPULOG("MAIN INIT 32B %08X\r\n", val); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x0] = val; + return; + + case 0x04001000 : + GPU_setVideoProp(SubScreen.gpu, val); + GPULOG("SUB INIT 32B %08X\r\n", val); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x1000>>2] = val; + return; + + case REG_IME : + MMU.reg_IME[proc] = val & 1; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x208>>2] = val; + return; + + case REG_IE : + MMU.reg_IE[proc] = val; + return; + + case REG_IF : + MMU.reg_IF[proc] &= (~val); + return; + + case 0x04000100 : + case 0x04000104 : + case 0x04000108 : + case 0x0400010C : + MMU.timerReload[proc][(adr>>2)&0x3] = (u16)val; + if(val&0x800000) + { + if(!(val&40000)) MMU.timer[proc][(adr>>2)&0x3] = MMU.timerReload[proc][(adr>>2)&0x3]; + else MMU.timer[proc][(adr>>2)&0x3] = 0; + } + MMU.timerON[proc][(adr>>2)&0x3] = val & 0x800000; + switch((val>>16)&7) + { + case 0 : + MMU.timerMODE[proc][(adr>>2)&0x3] = 0+1;//proc; + break; + case 1 : + MMU.timerMODE[proc][(adr>>2)&0x3] = 6+1;//proc; + break; + case 2 : + MMU.timerMODE[proc][(adr>>2)&0x3] = 8+1;//proc; + break; + case 3 : + MMU.timerMODE[proc][(adr>>2)&0x3] = 10+1;//proc; + break; + default : + MMU.timerMODE[proc][(adr>>2)&0x3] = 0xFFFF; + break; + } + if(!(val & 0x800000)) + { + MMU.timerRUN[proc][(adr>>2)&0x3] = FALSE; + } + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[(adr&0xFFF)>>2] = val; + return; + case 0x04000298 : + { + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x298>>2] = val; + u16 cnt = ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x280>>1]; + s64 num = 0; + s64 den = 1; + s64 res; + s64 mod; + switch(cnt&3) + { + case 0: + { + num = (s64)(((s32 *)(MMU.MMU_MEM[proc][0x40]))[0x290>>2]); + den = (s64)(((s32 *)(MMU.MMU_MEM[proc][0x40]))[0x298>>2]); + } + break; + case 1: + { + num = ((s64*)(MMU.MMU_MEM[proc][0x40]))[0x290>>3]; + den = (s64)(((s32 *)(MMU.MMU_MEM[proc][0x40]))[0x298>>2]); + } + break; + case 2: + { + return; + //num = ((s64*)(MMU.MMU_MEM[proc][0x40]))[0x290>>3]; + //den = ((s64*)(MMU.MMU_MEM[proc][0x40]))[0x298>>3]; + } + break; + default: + break; + } + if(den==0) + { + res = 0; + mod = 0; + cnt |= 0x4000; + cnt &= 0x7FFF; + } + else + { + res = num / den; + mod = num % den; + cnt &= 0x3FFF; + } + DIVLOG("BOUT1 %08X%08X / %08X%08X = %08X%08X\r\n", (u32)(num>>32), (u32)num, + (u32)(den>>32), (u32)den, + (u32)(res>>32), (u32)res); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2A0>>2] = (u32)res; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2A4>>2] = (u32)(res>>32); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2A8>>2] = (u32)mod; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2AC>>2] = (u32)(mod>>32); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x280>>2] = cnt; + } + return; + case 0x0400029C : + { + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x29C>>2] = val; + u16 cnt = ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x280>>1]; + s64 num = 0; + s64 den = 1; + s64 res; + s64 mod; + switch(cnt&3) + { + case 0: + { + return;// + //num = (s64)(((s32 *)(MMU.MMU_MEM[proc][0x40]))[0x290>>2]); + //den = (s64)(((s32 *)(MMU.MMU_MEM[proc][0x40]))[0x298>>2]); + } + break; + case 1: + { + return;// + //num = ((s64*)(MMU.MMU_MEM[proc][0x40]))[0x290>>3]; + //den = (s64)(((s32 *)(MMU.MMU_MEM[proc][0x40]))[0x298>>2]); + } + break; + case 2: + { + num = ((s64*)(MMU.MMU_MEM[proc][0x40]))[0x290>>3]; + den = ((s64*)(MMU.MMU_MEM[proc][0x40]))[0x298>>3]; + } + break; + default: + break; + } + if(den==0) + { + res = 0; + mod = 0; + cnt |= 0x4000; + cnt &= 0x7FFF; + } + else + { + res = num / den; + mod = num % den; + cnt &= 0x3FFF; + } + DIVLOG("BOUT2 %08X%08X / %08X%08X = %08X%08X\r\n", (u32)(num>>32), (u32)num, + (u32)(den>>32), (u32)den, + (u32)(res>>32), (u32)res); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2A0>>2] = (u32)res; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2A4>>2] = (u32)(res>>32); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2A8>>2] = (u32)mod; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2AC>>2] = (u32)(mod>>32); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x280>>2] = cnt; + } + return; + case 0x040002B8 : + { + //execute = FALSE; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B8>>2] = val; + u16 cnt = ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x2B0>>1]; + u64 v = 1; + switch(cnt&1) + { + case 0: + v = (u64)(((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B8>>2]); + break; + case 1: + return; + //v = ((u64*)(MMU.MMU_MEM[proc][0x40]))[0x2B8>>3]; + //break; + } + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B4>>2] = (u32)sqrt(v); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B0>>2] = cnt & 0x7FFF; + SQRTLOG("BOUT1 sqrt(%08X%08X) = %08X\r\n", (u32)(v>>32), (u32)v, + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B4>>2]); + } + return; + case 0x040002BC : + { + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2BC>>2] = val; + u16 cnt = ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x2B0>>1]; + u64 v = 1; + switch(cnt&1) + { + case 0: + return; + //v = (u64)(((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B8>>2]); + //break; + case 1: + v = ((u64*)(MMU.MMU_MEM[proc][0x40]))[0x2B8>>3]; + break; + } + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B4>>2] = (u32)sqrt(v); + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B0>>2] = cnt & 0x7FFF; + SQRTLOG("BOUT2 sqrt(%08X%08X) = %08X\r\n", (u32)(v>>32), (u32)v, + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x2B4>>2]); + } + return; + case 0x04000180 : + { + //execute=FALSE; + u32 remote = (proc+1)&1; + u32 IPCSYNC_remote = ((u32 *)(MMU.MMU_MEM[remote][0x40]))[0x180>>2]; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x180>>2] = (val&0xFFF0)|((IPCSYNC_remote>>8)&0xF); + ((u32 *)(MMU.MMU_MEM[remote][0x40]))[0x180>>2] = (IPCSYNC_remote&0xFFF0)|((val>>8)&0xF); + MMU.reg_IF[remote] |= ((IPCSYNC_remote & (1<<14))<<2) & ((val & (1<<13))<<3);// & (MMU.reg_IME[remote] << 16);// & (MMU.reg_IE[remote] & (1<<16));// + } + return; + case 0x04000184 : + if(val & 0x4008) + { + FIFOInit(MMU.fifos + (IPCFIFO+((proc+1)&1))); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x184>>1] = (val & 0xBFF4) | 1; + ((u16 *)(MMU.MMU_MEM[(proc+1)&1][0x40]))[0x184>>1] |= (1<<8); + MMU.reg_IF[proc] |= ((val & 4)<<15);// & (MMU.reg_IME[proc] << 17);// & (MMU.reg_IE[proc] & 0x20000);// + return; + } + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x184>>1] = (val & 0xBFF4); + //execute = FALSE; + return; + case 0x04000188 : + { + u16 IPCFIFO_CNT = ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x184>>1]; + if(IPCFIFO_CNT&0x8000) + { + //if(val==43) execute = FALSE; + u32 remote = (proc+1)&1; + u32 fifonum = IPCFIFO+remote; + FIFOAdd(MMU.fifos + fifonum, val); + IPCFIFO_CNT = (IPCFIFO_CNT & 0xFFFC) | (MMU.fifos[fifonum].full<<1); + u16 IPCFIFO_CNT_remote = ((u16 *)(MMU.MMU_MEM[remote][0x40]))[0x184>>1]; + IPCFIFO_CNT_remote = (IPCFIFO_CNT_remote & 0xFCFF) | (MMU.fifos[fifonum].full<<10); + ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x184>>1] = IPCFIFO_CNT; + ((u16 *)(MMU.MMU_MEM[remote][0x40]))[0x184>>1] = IPCFIFO_CNT_remote; + //((u32 *)(MMU.MMU_MEM[rote][0x40]))[0x214>>2] = (IPCFIFO_CNT_remote & (1<<10))<<8; + MMU.reg_IF[remote] |= ((IPCFIFO_CNT_remote & (1<<10))<<8);// & (MMU.reg_IME[remote] << 18);// & (MMU.reg_IE[remote] & 0x40000);// + //execute = FALSE; + } + } + return; + case 0x040000B8 : + //LOG("32 bit dma0 %04X\r\n", val); + DMASrc[proc][0] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xB0>>2]; + DMADst[proc][0] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xB4>>2]; + MMU.DMAStartTime[proc][0] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7); + MMU.DMACrt[proc][0] = val; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xB8>>2]=val; + if(MMU.DMAStartTime[proc][0] == 0) + MMU_doDMA(proc, 0); + #ifdef LOG_DMA2 + else + { + LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 0, DMASrc[proc][0], DMADst[proc][0], 0, ((MMU.DMACrt[proc][0]>>27)&7)); + } + #endif + //execute = FALSE; + return; + case 0x040000C4 : + //LOG("32 bit dma1 %04X\r\n", val); + DMASrc[proc][1] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xBC>>2]; + DMADst[proc][1] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xC0>>2]; + MMU.DMAStartTime[proc][1] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7); + MMU.DMACrt[proc][1] = val; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xC4>>2]=val; + if(MMU.DMAStartTime[proc][1] == 0) + MMU_doDMA(proc, 1); + #ifdef LOG_DMA2 + else + { + LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 1, DMASrc[proc][1], DMADst[proc][1], 0, ((MMU.DMACrt[proc][1]>>27)&7)); + } + #endif + return; + case 0x040000D0 : + //LOG("32 bit dma2 %04X\r\n", val); + DMASrc[proc][2] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xC8>>2]; + DMADst[proc][2] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xCC>>2]; + MMU.DMAStartTime[proc][2] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7); + MMU.DMACrt[proc][2] = val; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xD0>>2]=val; + if(MMU.DMAStartTime[proc][2] == 0) + MMU_doDMA(proc, 2); + #ifdef LOG_DMA2 + else + { + LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 2, DMASrc[proc][2], DMADst[proc][2], 0, ((MMU.DMACrt[proc][2]>>27)&7)); + } + #endif + return; + case 0x040000DC : + //LOG("32 bit dma3 %04X\r\n", val); + DMASrc[proc][3] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xD4>>2]; + DMADst[proc][3] = ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xD8>>2]; + MMU.DMAStartTime[proc][3] = (proc ? (val>>28) & 0x3 : (val>>27) & 0x7); + MMU.DMACrt[proc][3] = val; + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0xDC>>2]=val; + if(MMU.DMAStartTime[proc][3] == 0) + MMU_doDMA(proc, 3); + #ifdef LOG_DMA2 + else + { + LOG("proc %d, dma %d src %08X dst %08X start taille %d %d\r\n", proc, 3, DMASrc[proc][3], DMADst[proc][3], 0, ((MMU.DMACrt[proc][3]>>27)&7)); + } + #endif + return; + case CARD_CR2 : + { + if(MEM_8(MMU.MMU_MEM[proc], CARD_COMMAND) == 0xB7) + { + MMU.dscard[proc].adress = (MEM_8(MMU.MMU_MEM[proc], CARD_COMMAND+1) << 24) | (MEM_8(MMU.MMU_MEM[proc], CARD_COMMAND+2) << 16) | (MEM_8(MMU.MMU_MEM[proc], CARD_COMMAND+3) << 8) | (MEM_8(MMU.MMU_MEM[proc], CARD_COMMAND+4)); + MMU.dscard[proc].transfer_count = 0x80;// * ((val>>24)&7)); + } + else + { + LOG("CARD command: %02X\n", MEM_8(MMU.MMU_MEM[proc], CARD_COMMAND)); + } + + CARDLOG("%08X : %08X %08X\r\n", adr, val, adresse[proc]); + val |= CARD_DATA_READY; + + if(MMU.dscard[proc].adress == 0) + { + val &= ~CARD_ACTIVATE; + MEM_32(MMU.MMU_MEM[proc], CARD_CR2) = val; + return; + } + MEM_32(MMU.MMU_MEM[proc], CARD_CR2) = val; + + int i; + + /* launch DMA if start flag was set to "DS Cart" */ + if(proc == ARMCPU_ARM7) i = 2; + else i = 5; + + if(proc == ARMCPU_ARM9 && MMU.DMAStartTime[proc][0] == i) /* dma0/1 on arm7 can't start on ds cart event */ + { + MMU_doDMA(proc, 0); + return; + } + else if(proc == ARMCPU_ARM9 && MMU.DMAStartTime[proc][1] == i) + { + MMU_doDMA(proc, 1); + return; + } + else if(MMU.DMAStartTime[proc][2] == i) + { + MMU_doDMA(proc, 2); + return; + } + else if(MMU.DMAStartTime[proc][3] == i) + { + MMU_doDMA(proc, 3); + return; + } + return; + + } + return; + case 0x04000008 : + GPU_setBGProp(MainScreen.gpu, 0, (val&0xFFFF)); + GPU_setBGProp(MainScreen.gpu, 1, (val>>16)); + //if((val>>16)==0x400) execute = FALSE; + ((u32 *)ARM9Mem.ARM9_REG)[8>>2] = val; + return; + case 0x0400000C : + GPU_setBGProp(MainScreen.gpu, 2, (val&0xFFFF)); + GPU_setBGProp(MainScreen.gpu, 3, (val>>16)); + ((u32 *)ARM9Mem.ARM9_REG)[0xC>>2] = val; + return; + case 0x04001008 : + GPU_setBGProp(SubScreen.gpu, 0, (val&0xFFFF)); + GPU_setBGProp(SubScreen.gpu, 1, (val>>16)); + ((u32 *)ARM9Mem.ARM9_REG)[0x1008>>2] = val; + return; + case 0x0400100C : + GPU_setBGProp(SubScreen.gpu, 2, (val&0xFFFF)); + GPU_setBGProp(SubScreen.gpu, 3, (val>>16)); + ((u32 *)ARM9Mem.ARM9_REG)[0x100C>>2] = val; + return; + //case 0x21FDFF0 : if(val==0) execute = FALSE; + //case 0x21FDFB0 : if(val==0) execute = FALSE; + default : + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>2]=val; + return; + } + } + ((u32 *)(MMU.MMU_MEM[proc][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>2]=val; + +} + + +void FASTCALL MMU_doDMA(u32 proc, u32 num) +{ + u32 src = DMASrc[proc][num]; + u32 dst = DMADst[proc][num]; + if(src==dst) + { + ((u32 *)(MMU.MMU_MEM[proc][0x40]))[(0xB8 + (0xC*num))>>2] &= 0x7FFFFFFF; + return; + } + + if((!(MMU.DMACrt[proc][num]&(1<<31)))&&(!(MMU.DMACrt[proc][num]&(1<<25)))) + { + MMU.DMAStartTime[proc][num] = 0; + MMU.DMACycle[proc][num] = 0; + //MMU.DMAing[proc][num] = FALSE; + return; + } + + u32 taille = (MMU.DMACrt[proc][num]&0xFFFF); + + if(MMU.DMAStartTime[proc][num] == 5) taille *= 0x80; + + MMU.DMACycle[proc][num] = taille + nds.cycles; + + MMU.DMAing[proc][num] = TRUE; + + DMALOG("proc %d, dma %d src %08X dst %08X start %d taille %d repeat %s %08X\r\n", proc, num, src, dst, MMU.DMAStartTime[proc][num], taille, (MMU.DMACrt[proc][num]&(1<<25))?"on":"off",MMU.DMACrt[proc][num]); + + if(!(MMU.DMACrt[proc][num]&(1<<25))) MMU.DMAStartTime[proc][num] = 0; + + switch((MMU.DMACrt[proc][num]>>26)&1) + { + case 1 : + switch(((MMU.DMACrt[proc][num]>>21)&0xF)) + { + u32 i; + case 0 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst += 4; + src += 4; + } + break; + case 1 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst -= 4; + src += 4; + } + break; + case 2 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + src += 4; + } + break; + case 3 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst += 4; + src += 4; + } + break; + case 4 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst += 4; + src -= 4; + } + break; + case 5 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst -= 4; + src -= 4; + } + break; + case 6 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + src -= 4; + } + break; + case 7 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst += 4; + src -= 4; + } + break; + case 8 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst += 4; + } + break; + case 9 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst -= 4; + } + break; + case 10 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + } + break; + case 11 : + for(i = 0; i < taille; ++i) + { + MMU_writeWord(proc, dst, MMU_readWord(proc, src)); + dst += 4; + } + break; + default : + break; + } + break; + case 0 : + switch(((MMU.DMACrt[proc][num]>>21)&0xF)) + { + u32 i; + case 0 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst += 2; + src += 2; + } + break; + case 1 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst -= 2; + src += 2; + } + break; + case 2 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + src += 2; + } + break; + case 3 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst += 2; + src += 2; + } + break; + case 4 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst += 2; + src -= 2; + } + break; + case 5 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst -= 2; + src -= 2; + } + break; + case 6 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + src -= 2; + } + break; + case 7 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst += 2; + src -= 2; + } + break; + case 8 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst += 2; + } + break; + case 9 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst -= 2; + } + break; + case 10 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + } + break; + case 11 : + for(i = 0; i < taille; ++i) + { + MMU_write16(proc, dst, MMU_readHWord(proc, src)); + dst += 2; + } + break; + default : + break; + } + break; + } + + //MMU.DMACrt[proc][num] &= 0x7FFFFFFF; + //((u32 *)(MMU.MMU_MEM[proc][0x40]))[(0xB8 + (0xC*num))>>2] = MMU.DMACrt[proc][num]; +} diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h new file mode 100644 index 000000000..3537fb0f2 --- /dev/null +++ b/desmume/src/MMU.h @@ -0,0 +1,123 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MMU_H +#define MMU_H + +#include "FIFO.h" +#include "dscard.h" + +#include "arm9/ARM9.h" +#include "arm7/spi.h" + +extern char szRomPath[512]; + +/* theses macros are designed for reading/writing in memory (m is a pointer to memory, like MMU.MMU_MEM[proc], and a is an adress, like 0x04000000 */ +#define MEM_8(m, a) (((u8*)(m[((a)>>20)&0xff]))[((a)&0xfff)]) +#define MEM_16(m, a) (((u16*)(m[((a)>>20)&0xff]))[((a)&0xfff)>>1]) +#define MEM_32(m, a) (((u32*)(m[((a)>>20)&0xff]))[((a)&0xfff)>>2]) + +/* theses ones for reading in rom data */ +#define ROM_8(m, a) (((u8*)(m))[(a)]) +#define ROM_16(m, a) (((u16*)(m))[(a)>>1]) +#define ROM_32(m, a) (((u32*)(m))[(a)>>2]) + + +#define IPCFIFO 0 + +typedef struct { + //ARM7 mem + u8 ARM7_BIOS[0x4000]; + u8 ARM7_ERAM[0x10000]; + u8 ARM7_REG[0x10000]; + u8 ARM7_WIRAM[0x10000]; + + //Shared ram + u8 SWIRAM[0x8000]; + + //Card rom & ram + u8 * CART_ROM; + u8 CART_RAM[0x10000]; + + //Unused ram + u8 UNUSED_RAM[4]; + + u8 * * MMU_MEM[2]; + u32 * MMU_MASK[2]; + + u8 ARM9_RW_MODE; + + FIFO fifos[16]; + + u32 * MMU_WAIT16[2]; + u32 * MMU_WAIT32[2]; + + u32 DTCMRegion; + u32 ITCMRegion; + + u16 timer[2][4]; + s32 timerMODE[2][4]; + u32 timerON[2][4]; + u32 timerRUN[2][4]; + u16 timerReload[2][4]; + + u32 reg_IME[2]; + u32 reg_IE[2]; + u32 reg_IF[2]; + + u32 DMAStartTime[2][4]; + s32 DMACycle[2][4]; + u32 DMACrt[2][4]; + BOOL DMAing[2][4]; + + nds7_spi_t spi7; /* NOTICE: arm7 only, perhaps should be moved in an arm7-specific struct */ + + nds_dscard dscard[2]; + +} MMU_struct; + +extern MMU_struct MMU; + +void MMUInit(void); +void MMUDeInit(void); + +void MMU_setRom(u8 * rom, u32 mask); +void MMU_unsetRom(); + +#define MMU_readByte MMU_read8 +#define MMU_readHWord MMU_read16 +#define MMU_readWord MMU_read32 + +u8 FASTCALL MMU_read8(u32 proc, u32 adr); +u16 FASTCALL MMU_read16(u32 proc, u32 adr); +u32 FASTCALL MMU_read32(u32 proc, u32 adr); + +#define MMU_writeByte MMU_write8 +#define MMU_writeHWord MMU_write16 +#define MMU_writeWord MMU_write32 + +void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val); +void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val); +void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val); + +void FASTCALL MMU_doDMA(u32 proc, u32 num); + +#endif diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index ff8b6a5f7..e70ce3ab3 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -1,17 +1,18 @@ SUBDIRS = . $(UI_DIR) noinst_LIBRARIES = libdesmume.a libdesmume_a_SOURCES = \ - armcpu.cpp armcpu.hpp \ - arm_instructions.cpp arm_instructions.hpp \ - bios.cpp bios.hpp cp15.cpp cp15.hpp \ + armcpu.c armcpu.h \ + arm_instructions.c arm_instructions.h \ + bios.c bios.h cp15.c cp15.h \ Disassembler.c Disassembler.h \ FIFO.c FIFO.h \ debug.c debug.h \ - MMU.cpp MMU.hpp NDSSystem.cpp NDSSystem.hpp \ - thumb_instructions.cpp thumb_instructions.hpp \ + MMU.c MMU.h NDSSystem.c NDSSystem.h \ + thumb_instructions.c thumb_instructions.h \ arm7/fw.c arm7/fw.h \ arm7/spi.c arm7/spi.h \ arm9/GPU.c arm9/GPU.h \ arm9/ARM9.c arm9/ARM9.h \ - windows/cflash.cpp windows/cflash.h fs.h + windows/cflash.c windows/cflash.h fs.h \ + saves.c saves.h libdesmume_a_LIBADD = fs-$(desmume_arch).$(OBJEXT) diff --git a/desmume/src/NDSSystem.c b/desmume/src/NDSSystem.c new file mode 100644 index 000000000..b0bec797a --- /dev/null +++ b/desmume/src/NDSSystem.c @@ -0,0 +1,221 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "NDSSystem.h" +#include + +NDSSystem nds; + +void NDSInit(void) { + nds.ARM9Cycle = 0; + nds.ARM7Cycle = 0; + nds.cycles = 0; + MMUInit(); + nds.nextHBlank = 3168; + nds.VCount = 0; + nds.lignerendu = FALSE; + + ScreenInit(); + + armcpu_new(&NDS_ARM7,1); + armcpu_new(&NDS_ARM9,0); +} + +void NDSDeInit(void) { + if(MMU.CART_ROM != MMU.UNUSED_RAM) + { + // free(MMU.CART_ROM); IT'S UP TO THE GUI TO LOAD/UNLOAD AND MALLOC/FREE ROM >( + MMU_unsetRom(); + } + nds.nextHBlank = 3168; + ScreenDeInit(); + MMUDeInit(); +} + +BOOL NDS_loadROM(u8 * rom, u32 mask) +{ + u32 i; + + if(MMU.CART_ROM != MMU.UNUSED_RAM) + { + // free(MMU.CART_ROM); IT'S UP TO THE GUI TO LOAD/UNLOAD AND MALLOC/FREE ROM >( + MMU_unsetRom(); + } + MMU_setRom(rom, mask); + + NDS_header * header = (NDS_header *)MMU.CART_ROM; + + u32 src = header->ARM9src>>2; + u32 dst = header->ARM9cpy; + + for(i = 0; i < (header->ARM9binSize>>2); ++i) + { + MMU_writeWord(0, dst, ((u32 *)rom)[src]); + dst+=4; + ++src; + } + + src = header->ARM7src>>2; + dst = header->ARM7cpy; + + for(i = 0; i < (header->ARM7binSize>>2); ++i) + { + MMU_writeWord(1, dst, ((u32 *)rom)[src]); + dst+=4; + ++src; + } + armcpu_init(&NDS_ARM7, header->ARM7exe); + armcpu_init(&NDS_ARM9, header->ARM9exe); + + nds.ARM9Cycle = 0; + nds.ARM7Cycle = 0; + nds.cycles = 0; + nds.nextHBlank = 3168; + nds.VCount = 0; + nds.lignerendu = FALSE; + + MMU_writeHWord(0, 0x04000130, 0x3FF); + MMU_writeHWord(1, 0x04000130, 0x3FF); + MMU_writeByte(1, 0x04000136, 0x43); + + MMU_writeByte(0, 0x027FFCDC, 0x20); + MMU_writeByte(0, 0x027FFCDD, 0x20); + MMU_writeByte(0, 0x027FFCE2, 0xE0); + MMU_writeByte(0, 0x027FFCE3, 0x80); + + MMU_writeHWord(0, 0x027FFCD8, 0x20<<4); + MMU_writeHWord(0, 0x027FFCDA, 0x20<<4); + MMU_writeHWord(0, 0x027FFCDE, 0xE0<<4); + MMU_writeHWord(0, 0x027FFCE0, 0x80<<4); + + MMU_writeWord(0, 0x027FFE40, 0xE188); + MMU_writeWord(0, 0x027FFE44, 0x9); + MMU_writeWord(0, 0x027FFE48, 0xE194); + MMU_writeWord(0, 0x027FFE4C, 0x0); +// logcount = 0; + + MMU_writeByte(0, 0x023FFC80, 1); + MMU_writeByte(0, 0x023FFC82, 10); + MMU_writeByte(0, 0x023FFC83, 7); + MMU_writeByte(0, 0x023FFC84, 15); + + MMU_writeHWord(0, 0x023FFC86, 'y'); + MMU_writeHWord(0, 0x023FFC88, 'o'); + MMU_writeHWord(0, 0x023FFC8A, 'p'); + MMU_writeHWord(0, 0x023FFC8C, 'y'); + MMU_writeHWord(0, 0x023FFC8E, 'o'); + MMU_writeHWord(0, 0x023FFC90, 'p'); + MMU_writeHWord(0, 0x023FFC9A, 6); + + MMU_writeHWord(0, 0x023FFC9C, 'H'); + MMU_writeHWord(0, 0x023FFC9E, 'i'); + MMU_writeHWord(0, 0x023FFCA0, ','); + MMU_writeHWord(0, 0x023FFCA2, 'i'); + MMU_writeHWord(0, 0x023FFCA4, 't'); + MMU_writeHWord(0, 0x023FFCA6, '\''); + MMU_writeHWord(0, 0x023FFCA8, 's'); + MMU_writeHWord(0, 0x023FFCAA, ' '); + MMU_writeHWord(0, 0x023FFCAC, 'm'); + MMU_writeHWord(0, 0x023FFCAE, 'e'); + MMU_writeHWord(0, 0x023FFCB0, '!'); + MMU_writeHWord(0, 0x023FFCD0, 11); + + MMU_writeHWord(0, 0x023FFCE4, 2); + + MMU_writeWord(0, 0x027FFE40, header->FNameTblOff); + MMU_writeWord(0, 0x027FFE44, header->FNameTblSize); + MMU_writeWord(0, 0x027FFE48, header->FATOff); + MMU_writeWord(0, 0x027FFE4C, header->FATSize); + + MMU_writeWord(0, 0x027FFE50, header->ARM9OverlayOff); + MMU_writeWord(0, 0x027FFE54, header->ARM9OverlaySize); + MMU_writeWord(0, 0x027FFE58, header->ARM7OverlayOff); + MMU_writeWord(0, 0x027FFE5C, header->ARM7OverlaySize); + + MMU_writeWord(0, 0x027FFE60, header->unknown2a); + MMU_writeWord(0, 0x027FFE64, header->unknown2b); //merci EACKiX + + MMU_writeWord(0, 0x027FFE70, header->ARM9unk); + MMU_writeWord(0, 0x027FFE74, header->ARM7unk); + + MMU_writeWord(0, 0x027FFF9C, 0x027FFF90); // ?????? besoin d'avoir la vrai valeur sur ds + + nds.touchX = nds.touchY = 0; + MainScreen.offset = 192; + SubScreen.offset = 0; + + //MMU_writeWord(0, 0x02007FFC, 0xE92D4030); + + return TRUE; +} + +NDS_header * NDS_getROMHeader(void) +{ + return (NDS_header *)MMU.CART_ROM; +} + +void NDS_setTouchPos(u16 x, u16 y) +{ + nds.touchX = (x <<4); + nds.touchY = (y <<4); + + MMU.ARM7_REG[0x136] &= 0xBF; +} + +void NDS_releasTouch(void) +{ + nds.touchX = 0; + nds.touchY = 0; + + MMU.ARM7_REG[0x136] |= 0x40; +} + +void debug() +{ + //if(NDS_ARM9.R[15]==0x020520DC) execute = FALSE; + //DSLinux + //if(NDS_ARM9.CPSR.bits.mode == 0) execute = FALSE; + //if((NDS_ARM9.R[15]&0xFFFFF000)==0) execute = FALSE; + //if((NDS_ARM9.R[15]==0x0201B4F4)/*&&(NDS_ARM9.R[1]==0x0)*/) execute = FALSE; + //AOE + //if((NDS_ARM9.R[15]==0x01FFE194)&&(NDS_ARM9.R[0]==0)) execute = FALSE; + //if((NDS_ARM9.R[15]==0x01FFE134)&&(NDS_ARM9.R[0]==0)) execute = FALSE; + + //BBMAN + //if(NDS_ARM9.R[15]==0x02098B4C) execute = FALSE; + //if(NDS_ARM9.R[15]==0x02004924) execute = FALSE; + //if(NDS_ARM9.R[15]==0x02004890) execute = FALSE; + + //if(NDS_ARM9.R[15]==0x0202B800) execute = FALSE; + //if(NDS_ARM9.R[15]==0x0202B3DC) execute = FALSE; + //if((NDS_ARM9.R[1]==0x9AC29AC1)&&(!fait)) {execute = FALSE;fait = TRUE;} + //if(NDS_ARM9.R[1]==0x0400004A) {execute = FALSE;fait = TRUE;} + /*if(NDS_ARM9.R[4]==0x2E33373C) execute = FALSE; + if(NDS_ARM9.R[15]==0x02036668) //execute = FALSE; + { + nds.logcount++; + sprintf(logbuf, "%d %08X", nds.logcount, NDS_ARM9.R[13]); + log::ajouter(logbuf); + if(nds.logcount==89) execute=FALSE; + }*/ + //if(NDS_ARM9.instruction==0) execute = FALSE; + //if((NDS_ARM9.R[15]>>28)) execute = FALSE; +} diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h new file mode 100644 index 000000000..acae9c5b8 --- /dev/null +++ b/desmume/src/NDSSystem.h @@ -0,0 +1,801 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef NDSSYSTEM_H +#define NDSSYSTEM_H + +#include "armcpu.h" +#include "MMU.h" + +#include "arm9/GPU.h" + +extern BOOL execute; +extern BOOL click; + +//#define LOG_ARM9 +//#define LOG_ARM7 + +#define ARM9_IO_REGS ((u32 *)ARM9Mem.ARM9_REG) +#define ARM7_IO_REGS ((u32 *)MMU.ARM7_REG) +#define REG_DIVCNT (0x280>>2) +#define REG_DIV_NUMER_L (0x290>>2) +#define REG_DIV_NUMER_H (0x294>>2) +#define REG_DIV_DENOM_L (0x298>>2) +#define REG_DIV_DENOM_H (0x29C>>2) +#define REG_DIV_RESULT_L (0x2A0>>2) +#define REG_DIV_RESULT_H (0x2A4>>2) +#define REG_DIV_REMAIN_L (0x2A8>>2) +#define REG_DIV_REMAIN_H (0x2AC>>2) +#define REG_SQRTCNT (0x2B0>>2) +#define REG_SQRT_PARAM_L (0x2B8>>2) +#define REG_SQRT_PARAM_H (0x2BC>>2) +#define REG_SQRT_RESULT (0x2B4>>2) +#define reg_IPCSYNC (0x180>>1) +#define reg_IPCFIFOCNT (0x184>>1) + +#ifdef WORDS_BIGENDIAN +typedef struct +{ + u8 reserved[160]; + u16 headerCRC16; + u16 logoCRC16; + u8 logo[156]; + u8 unknown5[56]; + u32 HeaderSize; + u32 ROMSize; + u8 unknown3c[8]; + + u32 ARM7unk; + u32 ARM9unk; + u16 ROMtimeout; + u16 CRC16; + u32 IconOff; + + u32 unknown2b; + u32 unknown2a; + + u32 ARM7OverlaySize; + u32 ARM7OverlayOff; + u32 ARM9OverlaySize; + u32 ARM9OverlayOff; + + u32 FATSize; + u32 FATOff; + + u32 FNameTblSize; + u32 FNameTblOff; + + u32 ARM7binSize; + u32 ARM7cpy; + u32 ARM7exe; + u32 ARM7src; + + u32 ARM9binSize; + u32 ARM9cpy; + u32 ARM9exe; + u32 ARM9src; + + u8 flags; + u8 cardInfo[8]; + u8 cardSize; + u8 deviceCode; + u8 unitCode; + u16 makerCode; + char gameCode[4]; + char gameTile[12]; +} NDS_header; +#else +typedef struct +{ + char gameTile[12]; + char gameCode[4]; + u16 makerCode; + u8 unitCode; + u8 deviceCode; + u8 cardSize; + u8 cardInfo[8]; + u8 flags; + + u32 ARM9src; + u32 ARM9exe; + u32 ARM9cpy; + u32 ARM9binSize; + + u32 ARM7src; + u32 ARM7exe; + u32 ARM7cpy; + u32 ARM7binSize; + + u32 FNameTblOff; + u32 FNameTblSize; + + u32 FATOff; + u32 FATSize; + + u32 ARM9OverlayOff; + u32 ARM9OverlaySize; + u32 ARM7OverlayOff; + u32 ARM7OverlaySize; + + u32 unknown2a; + u32 unknown2b; + + u32 IconOff; + u16 CRC16; + u16 ROMtimeout; + u32 ARM9unk; + u32 ARM7unk; + + u8 unknown3c[8]; + u32 ROMSize; + u32 HeaderSize; + u8 unknown5[56]; + u8 logo[156]; + u16 logoCRC16; + u16 headerCRC16; + u8 reserved[160]; +} NDS_header; +#endif + +extern void debug(); + +typedef struct +{ + s32 ARM9Cycle; + s32 ARM7Cycle; + s32 cycles; + s32 timerCycle[2][4]; + BOOL timerOver[2][4]; + s32 nextHBlank; + u32 VCount; + u32 old; + s32 diff; + BOOL lignerendu; + + u16 touchX; + u16 touchY; +} NDSSystem; + +extern NDSSystem nds; + +void NDSInit(void); +void NDSDeInit(void); + +BOOL NDS_loadROM(u8 * rom, u32 mask); +NDS_header * NDS_getROMHeader(void); + +void NDS_setTouchPos(u16 x, u16 y); +void NDS_releasTouch(void); + + static INLINE void NDS_ARM9HBlankInt(void) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1]&0x10) + { + MMU.reg_IF[0] |= 2;// & (MMU.reg_IME[0] << 1);// (MMU.reg_IE[0] & (1<<1)); + NDS_ARM9.wIRQ = TRUE; + } + } + + static INLINE void NDS_ARM7HBlankInt(void) + { + if(((u16 *)MMU.ARM7_REG)[0x0004>>1]&0x10) + { + MMU.reg_IF[1] |= 2;// & (MMU.reg_IME[1] << 1);// (MMU.reg_IE[1] & (1<<1)); + NDS_ARM7.wIRQ = TRUE; + } + } + + static INLINE void NDS_ARM9VBlankInt(void) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1]&0x8) + { + MMU.reg_IF[0] |= 1;// & (MMU.reg_IME[0]);// (MMU.reg_IE[0] & 1); + NDS_ARM9.wIRQ = TRUE; + //execute = FALSE; + /*logcount++;*/ + } + } + + static INLINE void NDS_ARM7VBlankInt(void) + { + if(((u16 *)MMU.ARM7_REG)[0x0004>>1]&0x8) + MMU.reg_IF[1] |= 1;// & (MMU.reg_IME[1]);// (MMU.reg_IE[1] & 1); + NDS_ARM7.wIRQ = TRUE; + //execute = FALSE; + } + + static INLINE void NDS_swapScreen(void) + { + u16 tmp = MainScreen.offset; + MainScreen.offset = SubScreen.offset; + SubScreen.offset = tmp; + } + + #define INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF)) + static INLINE u32 NDS_exec(s32 nb, BOOL force) + { + nb += nds.cycles;//(nds.cycles>>26)<<26; + + for(; (nb >= nds.cycles) && ((force)||(execute)); ) + { + if(nds.ARM9Cycle<=nds.cycles) + { + #ifdef LOG_ARM9 + if(logcount==3){ + if(NDS_ARM9.CPSR.bits.T) + des_thumb_instructions_set[(NDS_ARM9.instruction)>>6](NDS_ARM9.instruct_adr, NDS_ARM9.instruction, logbuf); + else + des_arm_instructions_set[INDEX(NDS_ARM9.instruction)](NDS_ARM9.instruct_adr, NDS_ARM9.instruction, logbuf); + sprintf(logbuf, "%s\t%08X\n\t R00: %08X, R01: %08X, R02: %08X, R03: %08X, R04: %08X, R05: %08X, R06: %08X, R07: %08X,\n\t R08: %08X, R09: %08X, R10: %08X, R11: %08X, R12: %08X, R13: %08X, R14: %08X, R15: %08X,\n\t CPSR: %08X , SPSR: %08X", + logbuf, NDS_ARM9.instruction, NDS_ARM9.R[0], NDS_ARM9.R[1], NDS_ARM9.R[2], NDS_ARM9.R[3], NDS_ARM9.R[4], NDS_ARM9.R[5], NDS_ARM9.R[6], NDS_ARM9.R[7], + NDS_ARM9.R[8], NDS_ARM9.R[9], NDS_ARM9.R[10], NDS_ARM9.R[11], NDS_ARM9.R[12], NDS_ARM9.R[13], NDS_ARM9.R[14], NDS_ARM9.R[15], + NDS_ARM9.CPSR, NDS_ARM9.SPSR); + LOG(logbuf); + } + #endif + if(NDS_ARM9.waitIRQ) + nds.ARM9Cycle += 100; + else + //nds.ARM9Cycle += NDS_ARM9.exec(); + nds.ARM9Cycle += armcpu_exec(&NDS_ARM9); + } + if(nds.ARM7Cycle<=nds.cycles) + { + #ifdef LOG_ARM7 + if(logcount==1){ + if(NDS_ARM7.CPSR.bits.T) + des_thumb_instructions_set[(NDS_ARM7.instruction)>>6](NDS_ARM7.instruct_adr, NDS_ARM7.instruction, logbuf); + else + des_arm_instructions_set[INDEX(NDS_ARM7.instruction)](NDS_ARM7.instruct_adr, NDS_ARM7.instruction, logbuf); + sprintf(logbuf, "%s\n\t R00: %08X, R01: %08X, R02: %08X, R03: %08X, R04: %08X, R05: %08X, R06: %08X, R07: %08X,\n\t R08: %08X, R09: %08X, R10: %08X, R11: %08X, R12: %08X, R13: %08X, R14: %08X, R15: %08X,\n\t CPSR: %08X , SPSR: %08X", + logbuf, NDS_ARM7.R[0], NDS_ARM7.R[1], NDS_ARM7.R[2], NDS_ARM7.R[3], NDS_ARM7.R[4], NDS_ARM7.R[5], NDS_ARM7.R[6], NDS_ARM7.R[7], + NDS_ARM7.R[8], NDS_ARM7.R[9], NDS_ARM7.R[10], NDS_ARM7.R[11], NDS_ARM7.R[12], NDS_ARM7.R[13], NDS_ARM7.R[14], NDS_ARM7.R[15], + NDS_ARM7.CPSR, NDS_ARM7.SPSR); + LOG(logbuf); + } + #endif + if(NDS_ARM7.waitIRQ) + nds.ARM7Cycle += 100; + else + //nds.ARM7Cycle += (NDS_ARM7.exec()<<1); + nds.ARM7Cycle += (armcpu_exec(&NDS_ARM7)<<1); + } + nds.cycles = (nds.ARM9Cycle=nds.nextHBlank) + { + if(!nds.lignerendu) + { + if(nds.VCount<192) + { + GPU_ligne(MainScreen.gpu, GPU_screen + (MainScreen.offset * 256), nds.VCount); + GPU_ligne(SubScreen.gpu, GPU_screen + (SubScreen.offset * 256), nds.VCount); + ((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1] |= 2; + ((u16 *)MMU.ARM7_REG)[0x0004>>1] |= 2; + NDS_ARM9HBlankInt(); + NDS_ARM7HBlankInt(); + if(MMU.DMAStartTime[0][0] == 2) + MMU_doDMA(0, 0); + if(MMU.DMAStartTime[0][1] == 2) + MMU_doDMA(0, 1); + if(MMU.DMAStartTime[0][2] == 2) + MMU_doDMA(0, 2); + if(MMU.DMAStartTime[0][3] == 2) + MMU_doDMA(0, 3); + } + nds.lignerendu = TRUE; + } + if(nds.cycles>=nds.nextHBlank+1092) + { + ++nds.VCount; + nds.nextHBlank += 4260; + ((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1] &= 0xFFFD; + ((u16 *)MMU.ARM7_REG)[0x0004>>1] &= 0xFFFD; + + if(MMU.DMAStartTime[0][0] == 3) + MMU_doDMA(0, 0); + if(MMU.DMAStartTime[0][1] == 3) + MMU_doDMA(0, 1); + if(MMU.DMAStartTime[0][2] == 3) + MMU_doDMA(0, 2); + if(MMU.DMAStartTime[0][3] == 3) + MMU_doDMA(0, 3); + + nds.lignerendu = FALSE; + if(nds.VCount==193) + { + ((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1] |= 1; + ((u16 *)MMU.ARM7_REG)[0x0004>>1] |= 1; + NDS_ARM9VBlankInt(); + NDS_ARM7VBlankInt(); + + if(MMU.DMAStartTime[0][0] == 1) + MMU_doDMA(0, 0); + if(MMU.DMAStartTime[0][1] == 1) + MMU_doDMA(0, 1); + if(MMU.DMAStartTime[0][2] == 1) + MMU_doDMA(0, 2); + if(MMU.DMAStartTime[0][3] == 1) + MMU_doDMA(0, 3); + + if(MMU.DMAStartTime[1][0] == 1) + MMU_doDMA(1, 0); + if(MMU.DMAStartTime[1][1] == 1) + MMU_doDMA(1, 1); + if(MMU.DMAStartTime[1][2] == 1) + MMU_doDMA(1, 2); + if(MMU.DMAStartTime[1][3] == 1) + MMU_doDMA(1, 3); + } + else + if(nds.VCount==263) + { + nds.nextHBlank = 3168; + nds.VCount = 0; + ((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1] &= 0xFFFE; + ((u16 *)MMU.ARM7_REG)[0x0004>>1] &= 0xFFFE; + + nds.cycles -= (560190<<1); + nds.ARM9Cycle -= (560190<<1); + nds.ARM7Cycle -= (560190<<1); + nb -= (560190<<1); + if(MMU.timerON[0][0]) + nds.timerCycle[0][0] -= (560190<<1); + if(MMU.timerON[0][1]) + nds.timerCycle[0][1] -= (560190<<1); + if(MMU.timerON[0][2]) + nds.timerCycle[0][2] -= (560190<<1); + if(MMU.timerON[0][3]) + nds.timerCycle[0][3] -= (560190<<1); + + if(MMU.timerON[1][0]) + nds.timerCycle[1][0] -= (560190<<1); + if(MMU.timerON[1][1]) + nds.timerCycle[1][1] -= (560190<<1); + if(MMU.timerON[1][2]) + nds.timerCycle[1][2] -= (560190<<1); + if(MMU.timerON[1][3]) + nds.timerCycle[1][3] -= (560190<<1); + if(MMU.DMAing[0][0]) + MMU.DMACycle[0][0] -= (560190<<1); + if(MMU.DMAing[0][1]) + MMU.DMACycle[0][1] -= (560190<<1); + if(MMU.DMAing[0][2]) + MMU.DMACycle[0][2] -= (560190<<1); + if(MMU.DMAing[0][3]) + MMU.DMACycle[0][3] -= (560190<<1); + if(MMU.DMAing[1][0]) + MMU.DMACycle[1][0] -= (560190<<1); + if(MMU.DMAing[1][1]) + MMU.DMACycle[1][1] -= (560190<<1); + if(MMU.DMAing[1][2]) + MMU.DMACycle[1][2] -= (560190<<1); + if(MMU.DMAing[1][3]) + MMU.DMACycle[1][3] -= (560190<<1); + } + + ((u16 *)ARM9Mem.ARM9_REG)[0x0006>>1] = nds.VCount; + ((u16 *)MMU.ARM7_REG)[0x0006>>1] = nds.VCount; + + u32 vmatch = ((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1]; + if((nds.VCount==(vmatch>>8)|((vmatch<<1)&(1<<8)))) + { + ((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1] |= (1<<2); + if((((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1]&(1<<5))) + NDS_makeARM9Int(2); + } + else + ((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1] &= 0xFFFB; + + vmatch = ((u16 *)MMU.ARM7_REG)[0x0004>>1]; + if((nds.VCount==(vmatch>>8)|((vmatch<<1)&(1<<8)))) + { + ((u16 *)MMU.ARM7_REG)[0x0004>>1] |= (1<<2); + if((((u16 *)MMU.ARM7_REG)[0x0004>>1]&(1<<5))) + NDS_makeARM7Int(2); + } + else + ((u16 *)MMU.ARM7_REG)[0x0004>>1] &= 0xFFFB; + } + } + if(MMU.timerON[0][0]) + { + if(MMU.timerRUN[0][0]) + { + switch(MMU.timerMODE[0][0]) + { + case 0xFFFF : + break; + default : + { + nds.diff = (nds.cycles - nds.timerCycle[0][0])>>MMU.timerMODE[0][0]; + nds.old = MMU.timer[0][0]; + MMU.timer[0][0] += nds.diff; + nds.timerCycle[0][0] += (nds.diff << MMU.timerMODE[0][0]); + nds.timerOver[0][0] = nds.old>MMU.timer[0][0]; + if(nds.timerOver[0][0]) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x102>>1]&0x40) + NDS_makeARM9Int(3); + MMU.timer[0][0] += MMU.timerReload[0][0]; + } + } + break; + } + } + else + { + MMU.timerRUN[0][0] = TRUE; + nds.timerCycle[0][0] = nds.cycles; + } + } + if(MMU.timerON[0][1]) + { + if(MMU.timerRUN[0][1]) + { + switch(MMU.timerMODE[0][1]) + { + case 0xFFFF : + if(nds.timerOver[0][0]) + { + ++(MMU.timer[0][1]); + nds.timerOver[0][1] = !MMU.timer[0][1]; + if (nds.timerOver[0][1]) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x106>>1]&0x40) + NDS_makeARM9Int(4); + } + } + break; + default : + { + nds.diff = (nds.cycles - nds.timerCycle[0][1])>>MMU.timerMODE[0][1]; + nds.old = MMU.timer[0][1]; + MMU.timer[0][1] += nds.diff; + nds.timerCycle[0][1] += nds.diff << MMU.timerMODE[0][1]; + nds.timerOver[0][1] = nds.old>MMU.timer[0][1]; + if(nds.timerOver[0][1]) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x106>>1]&0x40) + NDS_makeARM9Int(4); + MMU.timer[0][1] += MMU.timerReload[0][1]; + } + } + break; + } + } + else + { + MMU.timerRUN[0][1] = TRUE; + nds.timerCycle[0][1] = nds.cycles; + } + } + if(MMU.timerON[0][2]) + { + if(MMU.timerRUN[0][2]) + { + switch(MMU.timerMODE[0][2]) + { + case 0xFFFF : + if(nds.timerOver[0][1]) + { + ++(MMU.timer[0][2]); + nds.timerOver[0][2] = !MMU.timer[0][2]; + if (nds.timerOver[0][2]) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x10A>>1]&0x40) + NDS_makeARM9Int(5); + } + } + break; + default : + { + nds.diff = (nds.cycles - nds.timerCycle[0][2])>>MMU.timerMODE[0][2]; + nds.old = MMU.timer[0][2]; + MMU.timer[0][2] += nds.diff; + nds.timerCycle[0][2] += nds.diff << MMU.timerMODE[0][2]; + nds.timerOver[0][2] = nds.old>MMU.timer[0][2]; + if(nds.timerOver[0][2]) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x10A>>1]&0x40) + NDS_makeARM9Int(5); + MMU.timer[0][2] += MMU.timerReload[0][2]; + } + } + break; + } + } + else + { + MMU.timerRUN[0][2] = TRUE; + nds.timerCycle[0][2] = nds.cycles; + } + } + if(MMU.timerON[0][3]) + { + if(MMU.timerRUN[0][3]) + { + switch(MMU.timerMODE[0][3]) + { + case 0xFFFF : + if(nds.timerOver[0][2]) + { + ++(MMU.timer[0][3]); + nds.timerOver[0][3] = !MMU.timer[0][3]; + if (nds.timerOver[0][3]) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x10E>>1]&0x40) + NDS_makeARM9Int(6); + } + } + break; + default : + { + nds.diff = (nds.cycles - nds.timerCycle[0][3])>>MMU.timerMODE[0][3]; + nds.old = MMU.timer[0][3]; + MMU.timer[0][3] += nds.diff; + nds.timerCycle[0][3] += nds.diff << MMU.timerMODE[0][3]; + nds.timerOver[0][3] = nds.old>MMU.timer[0][3]; + if(nds.timerOver[0][3]) + { + if(((u16 *)ARM9Mem.ARM9_REG)[0x10E>>1]&0x40) + NDS_makeARM9Int(6); + MMU.timer[0][3] += MMU.timerReload[0][3]; + } + } + break; + } + } + else + { + MMU.timerRUN[0][3] = TRUE; + nds.timerCycle[0][3] = nds.cycles; + } + } + + if(MMU.timerON[1][0]) + { + if(MMU.timerRUN[1][0]) + { + switch(MMU.timerMODE[1][0]) + { + case 0xFFFF : + break; + default : + { + nds.diff = (nds.cycles - nds.timerCycle[1][0])>>MMU.timerMODE[1][0]; + nds.old = MMU.timer[1][0]; + MMU.timer[1][0] += nds.diff; + nds.timerCycle[1][0] += nds.diff << MMU.timerMODE[1][0]; + nds.timerOver[1][0] = nds.old>MMU.timer[1][0]; + if(nds.timerOver[1][0]) + { + if(((u16 *)MMU.ARM7_REG)[0x102>>1]&0x40) + NDS_makeARM7Int(3); + MMU.timer[1][0] += MMU.timerReload[1][0]; + } + } + break; + } + } + else + { + MMU.timerRUN[1][0] = TRUE; + nds.timerCycle[1][0] = nds.cycles; + } + } + if(MMU.timerON[1][1]) + { + if(MMU.timerRUN[1][1]) + { + switch(MMU.timerMODE[1][1]) + { + case 0xFFFF : + if(nds.timerOver[1][0]) + { + ++(MMU.timer[1][1]); + nds.timerOver[1][1] = !MMU.timer[1][1]; + if (nds.timerOver[1][1]) + { + if(((u16 *)MMU.ARM7_REG)[0x106>>1]&0x40) + NDS_makeARM7Int(4); + } + } + break; + default : + { + nds.diff = (nds.cycles - nds.timerCycle[1][1])>>MMU.timerMODE[1][1]; + nds.old = MMU.timer[1][1]; + MMU.timer[1][1] += nds.diff; + nds.timerCycle[1][1] += nds.diff << MMU.timerMODE[1][1]; + nds.timerOver[1][1] = nds.old>MMU.timer[1][1]; + if(nds.timerOver[1][1]) + { + if(((u16 *)MMU.ARM7_REG)[0x106>>1]&0x40) + NDS_makeARM7Int(4); + MMU.timer[1][1] += MMU.timerReload[1][1]; + } + } + break; + } + } + else + { + MMU.timerRUN[1][1] = TRUE; + nds.timerCycle[1][1] = nds.cycles; + } + } + if(MMU.timerON[1][2]) + { + if(MMU.timerRUN[1][2]) + { + switch(MMU.timerMODE[1][2]) + { + case 0xFFFF : + if(nds.timerOver[1][1]) + { + ++(MMU.timer[1][2]); + nds.timerOver[1][2] = !MMU.timer[1][2]; + if (nds.timerOver[1][2]) + { + if(((u16 *)MMU.ARM7_REG)[0x10A>>1]&0x40) + NDS_makeARM7Int(5); + } + } + break; + default : + { + nds.diff = (nds.cycles - nds.timerCycle[1][2])>>MMU.timerMODE[1][2]; + nds.old = MMU.timer[1][2]; + MMU.timer[1][2] += nds.diff; + nds.timerCycle[1][2] += nds.diff << MMU.timerMODE[1][2]; + nds.timerOver[1][2] = nds.old>MMU.timer[1][2]; + if(nds.timerOver[1][2]) + { + if(((u16 *)MMU.ARM7_REG)[0x10A>>1]&0x40) + NDS_makeARM7Int(5); + MMU.timer[1][2] += MMU.timerReload[1][2]; + } + } + break; + } + } + else + { + MMU.timerRUN[1][2] = TRUE; + nds.timerCycle[1][2] = nds.cycles; + } + } + if(MMU.timerON[1][3]) + { + if(MMU.timerRUN[1][3]) + { + switch(MMU.timerMODE[1][3]) + { + case 0xFFFF : + if(nds.timerOver[1][2]) + { + ++(MMU.timer[1][3]); + nds.timerOver[1][3] = !MMU.timer[1][3]; + if (nds.timerOver[1][3]) + { + if(((u16 *)MMU.ARM7_REG)[0x10E>>1]&0x40) + NDS_makeARM7Int(6); + } + } + break; + default : + { + nds.diff = (nds.cycles - nds.timerCycle[1][3])>>MMU.timerMODE[1][3]; + nds.old = MMU.timer[1][3]; + MMU.timer[1][3] += nds.diff; + nds.timerCycle[1][3] += nds.diff << MMU.timerMODE[1][3]; + nds.timerOver[1][3] = nds.old>MMU.timer[1][3]; + if(nds.timerOver[1][3]) + { + if(((u16 *)MMU.ARM7_REG)[0x10E>>1]&0x40) + NDS_makeARM7Int(6); + MMU.timer[1][3] += MMU.timerReload[1][3]; + } + } + break; + } + } + else + { + MMU.timerRUN[1][3] = TRUE; + nds.timerCycle[1][3] = nds.cycles; + } + } + + if((MMU.DMAing[0][0])&&(MMU.DMACycle[0][0]<=nds.cycles)) + { + ((u32 *)ARM9Mem.ARM9_REG)[(0xB8 + (0xC*0))>>2] &= 0x7FFFFFFF; + if((MMU.DMACrt[0][0])&(1<<30)) NDS_makeARM9Int(8); + MMU.DMAing[0][0] = FALSE; + } + + if((MMU.DMAing[0][1])&&(MMU.DMACycle[0][1]<=nds.cycles)) + { + ((u32 *)ARM9Mem.ARM9_REG)[(0xB8 + (0xC*1))>>2] &= 0x7FFFFFFF; + if((MMU.DMACrt[0][1])&(1<<30)) NDS_makeARM9Int(9); + MMU.DMAing[0][1] = FALSE; + } + + if((MMU.DMAing[0][2])&&(MMU.DMACycle[0][2]<=nds.cycles)) + { + ((u32 *)ARM9Mem.ARM9_REG)[(0xB8 + (0xC*2))>>2] &= 0x7FFFFFFF; + if((MMU.DMACrt[0][2])&(1<<30)) NDS_makeARM9Int(10); + MMU.DMAing[0][2] = FALSE; + } + + if((MMU.DMAing[0][3])&&(MMU.DMACycle[0][3]<=nds.cycles)) + { + ((u32 *)ARM9Mem.ARM9_REG)[(0xB8 + (0xC*3))>>2] &= 0x7FFFFFFF; + if((MMU.DMACrt[0][3])&(1<<30)) NDS_makeARM9Int(11); + MMU.DMAing[0][3] = FALSE; + } + + if((MMU.DMAing[1][0])&&(MMU.DMACycle[1][0]<=nds.cycles)) + { + ((u32 *)MMU.ARM7_REG)[(0xB8 + (0xC*0))>>2] &= 0x7FFFFFFF; + if((MMU.DMACrt[1][0])&(1<<30)) NDS_makeARM7Int(8); + MMU.DMAing[1][0] = FALSE; + } + + if((MMU.DMAing[1][1])&&(MMU.DMACycle[1][1]<=nds.cycles)) + { + ((u32 *)MMU.ARM7_REG)[(0xB8 + (0xC*1))>>2] &= 0x7FFFFFFF; + if((MMU.DMACrt[1][1])&(1<<30)) NDS_makeARM7Int(9); + MMU.DMAing[1][1] = FALSE; + } + + if((MMU.DMAing[1][2])&&(MMU.DMACycle[1][2]<=nds.cycles)) + { + ((u32 *)MMU.ARM7_REG)[(0xB8 + (0xC*2))>>2] &= 0x7FFFFFFF; + if((MMU.DMACrt[1][2])&(1<<30)) NDS_makeARM7Int(10); + MMU.DMAing[1][2] = FALSE; + } + + if((MMU.DMAing[1][3])&&(MMU.DMACycle[1][3]<=nds.cycles)) + { + ((u32 *)MMU.ARM7_REG)[(0xB8 + (0xC*3))>>2] &= 0x7FFFFFFF; + if((MMU.DMACrt[1][3])&(1<<30)) NDS_makeARM7Int(11); + MMU.DMAing[1][3] = FALSE; + } + + if((MMU.reg_IF[0]&MMU.reg_IE[0]) && (MMU.reg_IME[0])) + //if(NDS_ARM9.irqExeption()) + if(armcpu_irqExeption(&NDS_ARM9)) + { + nds.ARM9Cycle = nds.cycles; + } + + if((MMU.reg_IF[1]&MMU.reg_IE[1]) && (MMU.reg_IME[1])) + if (armcpu_irqExeption(&NDS_ARM7)) + nds.ARM7Cycle = nds.cycles; + } + return nds.cycles; + } + +#endif diff --git a/desmume/src/arm_instructions.c b/desmume/src/arm_instructions.c new file mode 100644 index 000000000..eb6683332 --- /dev/null +++ b/desmume/src/arm_instructions.c @@ -0,0 +1,7274 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "cp15.h" +#include "debug.h" +#include "MMU.h" + +//#define ASM_CORE +//#define C_CORE + +s8 CFlag; +s8 ZFlag; +s8 NFlag; +s8 OFlag; + +#define LSL_IMM u32 shift_op = cpu->R[REG_POS(i,0)]<<((i>>7)&0x1F); + +#define S_LSL_IMM u32 shift_op = ((i>>7)&0x1F);\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], 32-shift_op);\ + shift_op = cpu->R[REG_POS(i,0)]<<((i>>7)&0x1F);\ + } + +#define LSL_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + if(shift_op>=32)\ + shift_op=0;\ + else\ + shift_op=cpu->R[REG_POS(i,0)]<R[REG_POS(i,8)])&0xFF;\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + if(shift_op<32)\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], 32-shift_op);\ + shift_op = cpu->R[REG_POS(i,0)]<R[REG_POS(i,0)]);\ + }\ + else\ + {\ + shift_op = 0;\ + c = 0;\ + } + +#define LSR_IMM u32 shift_op = ((i>>7)&0x1F);\ + if(shift_op!=0)\ + shift_op = cpu->R[REG_POS(i,0)]>>shift_op; + +#define S_LSR_IMM u32 shift_op = ((i>>7)&0x1F);\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + {\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + }\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = cpu->R[REG_POS(i,0)]>>shift_op;\ + } + +#define LSR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + if(shift_op>=32)\ + shift_op = 0;\ + else\ + shift_op = cpu->R[REG_POS(i,0)]>>shift_op; + +#define S_LSR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + {\ + shift_op = cpu->R[REG_POS(i,0)];\ + }\ + else\ + if(shift_op<32)\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = cpu->R[REG_POS(i,0)]>>shift_op;\ + }\ + else\ + if(shift_op==32)\ + {\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + shift_op = 0;\ + }\ + else\ + {\ + c = 0;\ + shift_op = 0;\ + } + +#define ASR_IMM u32 shift_op = ((i>>7)&0x1F);\ + if(shift_op==0)\ + shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\ + else\ + shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op); + +#define S_ASR_IMM u32 shift_op = ((i>>7)&0x1F);\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + {\ + shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + }\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\ + } + +#define ASR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + if(shift_op<32)\ + shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\ + else\ + shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF; + +#define S_ASR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + if(shift_op<32)\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = (u32)(((s32)(cpu->R[REG_POS(i,0)]))>>shift_op);\ + }\ + else\ + {\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + shift_op=BIT31(cpu->R[REG_POS(i,0)])*0xFFFFFFFF;\ + } + +#define ROR_IMM u32 shift_op = ((i>>7)&0x1F);\ + if(shift_op==0)\ + {\ + u32 tmp = cpu->CPSR.bits.C;\ + shift_op = (tmp<<31)|(cpu->R[REG_POS(i,0)]>>1);\ + }\ + else\ + shift_op = ROR(cpu->R[REG_POS(i,0)],shift_op); + +#define S_ROR_IMM u32 shift_op = ((i>>7)&0x1F);\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + {\ + u32 tmp = cpu->CPSR.bits.C;\ + shift_op = (tmp<<31)|(cpu->R[REG_POS(i,0)]>>1);\ + c = BIT0(cpu->R[REG_POS(i,0)]);\ + }\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = ROR(cpu->R[REG_POS(i,0)],shift_op);\ + } + +#define ROR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + if((shift_op==0)||((shift_op&0xF)==0))\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + shift_op = ROR(cpu->R[REG_POS(i,0)],(shift_op&0xF)); + +#define S_ROR_REG u32 shift_op = (cpu->R[REG_POS(i,8)])&0xFF;\ + u32 c = cpu->CPSR.bits.C;\ + if(shift_op==0)\ + shift_op=cpu->R[REG_POS(i,0)];\ + else\ + {\ + shift_op&=0xF;\ + if(shift_op==0)\ + {\ + shift_op=cpu->R[REG_POS(i,0)];\ + c = BIT31(cpu->R[REG_POS(i,0)]);\ + }\ + else\ + {\ + c = BIT_N(cpu->R[REG_POS(i,0)], shift_op-1);\ + shift_op = ROR(cpu->R[REG_POS(i,0)],(shift_op&0xF));\ + }\ + } + +#define IMM_VALUE u32 shift_op = ROR((i&0xFF), (i>>7)&0x1E); + +#define S_IMM_VALUE u32 shift_op = ROR((i&0xFF), (i>>7)&0x1E);\ + u32 c = cpu->CPSR.bits.C;\ + if((i>>8)&0xF)\ + c = BIT31(shift_op); + +#define IMM_OFF (((i>>4)&0xF0)+(i&0xF)) + +#define IMM_OFF_12 ((i)&0xFFF) + +extern BOOL execute; + +u32 FASTCALL OP_UND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LOG("Undefined instruction: %08X\n", i); + execute = FALSE; + return 1; +} + +//-----------------------AND------------------------------------ + +#define OP_AND(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OP_ANDS(a, b)\ + if(REG_POS(i,12)==15)\ + {\ + cpu->R[15] = cpu->R[REG_POS(i,16)] & shift_op;\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & shift_op;\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a; + +u32 FASTCALL OP_AND_LSL_IMM(register armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_AND(1, 3); +} + +u32 FASTCALL OP_AND_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_AND(2, 4); +} + +u32 FASTCALL OP_AND_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_AND(1, 3); +} + +u32 FASTCALL OP_AND_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_AND(2, 4); +} + +u32 FASTCALL OP_AND_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_AND(1, 3); +} + +u32 FASTCALL OP_AND_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_AND(2, 4); +} + +u32 FASTCALL OP_AND_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_AND(1, 3); +} + +u32 FASTCALL OP_AND_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_AND(2, 4); +} + +u32 FASTCALL OP_AND_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_AND(1, 3); +} + +u32 FASTCALL OP_AND_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_ANDS(2, 4); +} + +u32 FASTCALL OP_AND_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_ANDS(3, 5); +} + +u32 FASTCALL OP_AND_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_ANDS(2, 4); +} + +u32 FASTCALL OP_AND_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_ANDS(3, 5); +} + +u32 FASTCALL OP_AND_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_ANDS(2, 4); +} + +u32 FASTCALL OP_AND_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_ANDS(3, 5); +} + +u32 FASTCALL OP_AND_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_ANDS(2, 4); +} + +u32 FASTCALL OP_AND_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_ANDS(3, 5); +} + +u32 FASTCALL OP_AND_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_ANDS(2, 4); +} + +//--------------EOR------------------------------ + +#define OP_EOR(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] ^ shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OP_EORS(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] ^ shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a; + +u32 FASTCALL OP_EOR_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_EOR(1, 3); +} + +u32 FASTCALL OP_EOR_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_EOR(2, 4); +} + +u32 FASTCALL OP_EOR_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_EOR(1, 3); +} + +u32 FASTCALL OP_EOR_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_EOR(2, 4); +} + +u32 FASTCALL OP_EOR_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_EOR(1, 3); +} + +u32 FASTCALL OP_EOR_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_EOR(2, 4); +} + +u32 FASTCALL OP_EOR_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_EOR(1, 3); +} + +u32 FASTCALL OP_EOR_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_EOR(2, 4); +} + +u32 FASTCALL OP_EOR_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_EOR(1, 3); +} + +u32 FASTCALL OP_EOR_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_EORS(2, 4); +} + +u32 FASTCALL OP_EOR_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_EORS(3, 5); +} + +u32 FASTCALL OP_EOR_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_EORS(2, 4); +} + +u32 FASTCALL OP_EOR_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_EORS(3, 5); +} + +u32 FASTCALL OP_EOR_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_EORS(2, 4); +} + +u32 FASTCALL OP_EOR_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_EORS(3, 5); +} + +u32 FASTCALL OP_EOR_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_EORS(2, 4); +} + +u32 FASTCALL OP_EOR_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_EORS(3, 5); +} + +u32 FASTCALL OP_EOR_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_EORS(2, 4); +} + +//-------------SUB------------------------------------- + +#define OP_SUB(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] - shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OPSUBS(a, b) cpu->R[REG_POS(i,12)] = v - shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\ + return a; + +u32 FASTCALL OP_SUB_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_SUB(1, 3); +} + +u32 FASTCALL OP_SUB_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_SUB(2, 4); +} + +u32 FASTCALL OP_SUB_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_SUB(1, 3); +} + +u32 FASTCALL OP_SUB_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_SUB(2, 4); +} + +u32 FASTCALL OP_SUB_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_SUB(1, 3); +} + +u32 FASTCALL OP_SUB_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_SUB(2, 4); +} + +u32 FASTCALL OP_SUB_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_SUB(1, 3); +} + +u32 FASTCALL OP_SUB_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_SUB(2, 4); +} + +u32 FASTCALL OP_SUB_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_SUB(1, 3); +} + +u32 FASTCALL OP_SUB_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_IMM; + OPSUBS(2, 4); +} + +u32 FASTCALL OP_SUB_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OPSUBS(3, 5); +} + +u32 FASTCALL OP_SUB_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_IMM; + OPSUBS(2, 4); +} + +u32 FASTCALL OP_SUB_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OPSUBS(3, 5); +} + +u32 FASTCALL OP_SUB_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_IMM; + OPSUBS(2, 4); +} + +u32 FASTCALL OP_SUB_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OPSUBS(3, 5); +} + +u32 FASTCALL OP_SUB_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_IMM; + OPSUBS(2, 4); +} + +u32 FASTCALL OP_SUB_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OPSUBS(3, 5); +} + +u32 FASTCALL OP_SUB_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OPSUBS(2, 4); +} + +//------------------RSB------------------------ + +#define OP_RSB(a, b) cpu->R[REG_POS(i,12)] = shift_op - cpu->R[REG_POS(i,16)];\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OP_RSBS(a, b) cpu->R[REG_POS(i,12)] = shift_op - v;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(shift_op, v, cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(shift_op, v, cpu->R[REG_POS(i,12)]);\ + return a; + +u32 FASTCALL OP_RSB_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_RSB(1, 3); +} + +u32 FASTCALL OP_RSB_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_RSB(2, 4); +} + +u32 FASTCALL OP_RSB_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_RSB(1, 3); +} + +u32 FASTCALL OP_RSB_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_RSB(2, 4); +} + +u32 FASTCALL OP_RSB_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_RSB(1, 3); +} + +u32 FASTCALL OP_RSB_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_RSB(2, 4); +} + +u32 FASTCALL OP_RSB_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_RSB(1, 3); +} + +u32 FASTCALL OP_RSB_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_RSB(2, 4); +} + +u32 FASTCALL OP_RSB_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_RSB(1, 3); +} + +u32 FASTCALL OP_RSB_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_IMM; + OP_RSBS(2, 4); +} + +u32 FASTCALL OP_RSB_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_RSBS(3, 5); +} + +u32 FASTCALL OP_RSB_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_IMM; + OP_RSBS(2, 4); +} + +u32 FASTCALL OP_RSB_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_RSBS(3, 5); +} + +u32 FASTCALL OP_RSB_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_IMM; + OP_RSBS(2, 4); +} + +u32 FASTCALL OP_RSB_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_RSBS(3, 5); +} + +u32 FASTCALL OP_RSB_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_IMM; + OP_RSBS(2, 4); +} + +u32 FASTCALL OP_RSB_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_RSBS(3, 5); +} + +u32 FASTCALL OP_RSB_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_RSBS(2, 4); +} + +//------------------ADD----------------------------------- + +#define OP_ADD(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] + shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +u32 FASTCALL OP_ADD_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_ADD(1, 3); +} + +u32 FASTCALL OP_ADD_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_ADD(2, 4); +} + +u32 FASTCALL OP_ADD_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_ADD(1, 3); +} + +u32 FASTCALL OP_ADD_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_ADD(2, 4); +} + +u32 FASTCALL OP_ADD_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_ADD(1, 3); +} + +u32 FASTCALL OP_ADD_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_ADD(2, 4); +} + +u32 FASTCALL OP_ADD_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_ADD(1, 3); +} + +u32 FASTCALL OP_ADD_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_ADD(2, 4); +} + +u32 FASTCALL OP_ADD_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_ADD(1, 3); +} + +#define OP_ADDS(a, b) cpu->R[REG_POS(i,12)] = v + shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.V = SIGNED_OVERFLOW(v, shift_op, cpu->R[REG_POS(i,12)]);\ + return a; + +u32 FASTCALL OP_ADD_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_IMM; + OP_ADDS(2, 4); +} + +u32 FASTCALL OP_ADD_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_ADDS(3, 5); +} + +u32 FASTCALL OP_ADD_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_IMM; + OP_ADDS(2, 4); +} + +u32 FASTCALL OP_ADD_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_ADDS(3, 5); +} + +u32 FASTCALL OP_ADD_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_IMM; + OP_ADDS(2, 4); +} + +u32 FASTCALL OP_ADD_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_ADDS(3, 5); +} + +u32 FASTCALL OP_ADD_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_IMM; + OP_ADDS(2, 4); +} + +u32 FASTCALL OP_ADD_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_ADDS(3, 5); +} + +u32 FASTCALL OP_ADD_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_ADDS(2, 4); +} + +//------------------ADC----------------------------------- + +#define OP_ADC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] + shift_op + cpu->CPSR.bits.C;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +u32 FASTCALL OP_ADC_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_ADC(1, 3); +} + +u32 FASTCALL OP_ADC_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_ADC(2, 4); +} + +u32 FASTCALL OP_ADC_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_ADC(1, 3); +} + +u32 FASTCALL OP_ADC_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_ADC(2, 4); +} + +u32 FASTCALL OP_ADC_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_ADC(1, 3); +} + +u32 FASTCALL OP_ADC_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_ADC(2, 4); +} + +u32 FASTCALL OP_ADC_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_ADC(1, 3); +} + +u32 FASTCALL OP_ADC_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_ADC(2, 4); +} + +u32 FASTCALL OP_ADC_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_ADC(1, 3); +} + +#define OP_ADCS(a, b) u32 tmp = shift_op + cpu->CPSR.bits.C;\ + cpu->R[REG_POS(i,12)] = v + tmp;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(shift_op, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(v, tmp, cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.V = SIGNED_OVERFLOW(shift_op, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(v, tmp, cpu->R[REG_POS(i,12)]);\ + return a; + +u32 FASTCALL OP_ADC_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_IMM; + OP_ADCS(2, 4); +} + +u32 FASTCALL OP_ADC_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_ADCS(3, 5); +} + +u32 FASTCALL OP_ADC_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_IMM; + OP_ADCS(2, 4); +} + +u32 FASTCALL OP_ADC_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_ADCS(3, 5); +} + +u32 FASTCALL OP_ADC_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_IMM; + OP_ADCS(2, 4); +} + +u32 FASTCALL OP_ADC_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_ADCS(3, 5); +} + +u32 FASTCALL OP_ADC_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_IMM; + OP_ADCS(2, 4); +} + +u32 FASTCALL OP_ADC_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_ADCS(3, 5); +} + +u32 FASTCALL OP_ADC_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_ADCS(2, 4); +} + +//-------------SBC------------------------------------- + +#define OP_SBC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] - shift_op - (!cpu->CPSR.bits.C);\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +u32 FASTCALL OP_SBC_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_SBC(1, 3); +} + +u32 FASTCALL OP_SBC_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_SBC(2, 4); +} + +u32 FASTCALL OP_SBC_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_SBC(1, 3); +} + +u32 FASTCALL OP_SBC_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_SBC(2, 4); +} + +u32 FASTCALL OP_SBC_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_SBC(1, 3); +} + +u32 FASTCALL OP_SBC_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_SBC(2, 4); +} + +u32 FASTCALL OP_SBC_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_SBC(1, 3); +} + +u32 FASTCALL OP_SBC_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_SBC(2, 4); +} + +u32 FASTCALL OP_SBC_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_SBC(1, 3); +} + +#define OP_SBCS(a, b) u32 tmp = v - (!cpu->CPSR.bits.C);\ + cpu->R[REG_POS(i,12)] = tmp - shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(v, (!cpu->CPSR.bits.C), tmp)) & (!UNSIGNED_UNDERFLOW(tmp, shift_op, cpu->R[REG_POS(i,12)]));\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(v, (!cpu->CPSR.bits.C), tmp) | SIGNED_UNDERFLOW(tmp, shift_op, cpu->R[REG_POS(i,12)]);\ + return a; + +u32 FASTCALL OP_SBC_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_IMM; + OP_SBCS(2, 4); +} + +u32 FASTCALL OP_SBC_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_SBCS(3, 5); +} + +u32 FASTCALL OP_SBC_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_IMM; + OP_SBCS(2, 4); +} + +u32 FASTCALL OP_SBC_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_SBCS(3, 5); +} + +u32 FASTCALL OP_SBC_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_IMM; + OP_SBCS(2, 4); +} + +u32 FASTCALL OP_SBC_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_SBCS(3, 5); +} + +u32 FASTCALL OP_SBC_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_IMM; + OP_SBCS(2, 4); +} + +u32 FASTCALL OP_SBC_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_SBCS(3, 5); +} + +u32 FASTCALL OP_SBC_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_SBCS(2, 4); +} + +//---------------RSC---------------------------------- + +#define OP_RSC(a, b) cpu->R[REG_POS(i,12)] = shift_op - cpu->R[REG_POS(i,16)] - (!cpu->CPSR.bits.C);\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +u32 FASTCALL OP_RSC_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_RSC(1, 3); +} + +u32 FASTCALL OP_RSC_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_RSC(2, 4); +} + +u32 FASTCALL OP_RSC_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_RSC(1, 3); +} + +u32 FASTCALL OP_RSC_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_RSC(2, 4); +} + +u32 FASTCALL OP_RSC_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_RSC(1, 3); +} + +u32 FASTCALL OP_RSC_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_RSC(2, 4); +} + +u32 FASTCALL OP_RSC_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_RSC(1, 3); +} + +u32 FASTCALL OP_RSC_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_RSC(2, 4); +} + +u32 FASTCALL OP_RSC_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_RSC(1, 3); +} + +#define OP_RSCS(a,b) u32 tmp = shift_op - (!cpu->CPSR.bits.C);\ + cpu->R[REG_POS(i,12)] = tmp - v;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(shift_op, (!cpu->CPSR.bits.C), tmp)) & (!UNSIGNED_UNDERFLOW(tmp, v, cpu->R[REG_POS(i,12)]));\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(shift_op, (!cpu->CPSR.bits.C), tmp) | SIGNED_UNDERFLOW(tmp, v, cpu->R[REG_POS(i,12)]);\ + return a; + +u32 FASTCALL OP_RSC_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_IMM; + OP_RSCS(2,4); +} + +u32 FASTCALL OP_RSC_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSL_REG; + OP_RSCS(3,5); +} + +u32 FASTCALL OP_RSC_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_IMM; + OP_RSCS(2,4); +} + +u32 FASTCALL OP_RSC_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + LSR_REG; + OP_RSCS(3,5); +} + +u32 FASTCALL OP_RSC_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_IMM; + OP_RSCS(2,4); +} + +u32 FASTCALL OP_RSC_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ASR_REG; + OP_RSCS(3,5); +} + +u32 FASTCALL OP_RSC_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_IMM; + OP_RSCS(2,4); +} + +u32 FASTCALL OP_RSC_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + ROR_REG; + OP_RSCS(3,5); +} + +u32 FASTCALL OP_RSC_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,16)]; + IMM_VALUE; + OP_RSCS(2,4); +} + +//-------------------TST---------------------------- + +#define OP_TST(a) unsigned tmp = cpu->R[REG_POS(i,16)] & shift_op;\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(tmp);\ + cpu->CPSR.bits.Z = (tmp==0);\ + return a; + +u32 FASTCALL OP_TST_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_TST(1); +} + +u32 FASTCALL OP_TST_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_TST(2); +} + +u32 FASTCALL OP_TST_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_TST(1); +} + +u32 FASTCALL OP_TST_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_TST(2); +} + +u32 FASTCALL OP_TST_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_TST(1); +} + +u32 FASTCALL OP_TST_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_TST(2); +} + +u32 FASTCALL OP_TST_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_TST(1); +} + +u32 FASTCALL OP_TST_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_TST(2); +} + +u32 FASTCALL OP_TST_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_TST(1); +} + +//-------------------TEQ---------------------------- + +#define OP_TEQ(a) unsigned tmp = cpu->R[REG_POS(i,16)] ^ shift_op;\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(tmp);\ + cpu->CPSR.bits.Z = (tmp==0);\ + return a; + +u32 FASTCALL OP_TEQ_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_TEQ(1); +} + +u32 FASTCALL OP_TEQ_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_TEQ(2); +} + +u32 FASTCALL OP_TEQ_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_TEQ(1); +} + +u32 FASTCALL OP_TEQ_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_TEQ(2); +} + +u32 FASTCALL OP_TEQ_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_TEQ(1); +} + +u32 FASTCALL OP_TEQ_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_TEQ(2); +} + +u32 FASTCALL OP_TEQ_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_TEQ(1); +} + +u32 FASTCALL OP_TEQ_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_TEQ(2); +} + +u32 FASTCALL OP_TEQ_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_TEQ(1); +} + +//-------------CMP------------------------------------- + +#define OP_CMP(a) u32 tmp = cpu->R[REG_POS(i,16)] - shift_op;\ + cpu->CPSR.bits.N = BIT31(tmp);\ + cpu->CPSR.bits.Z = (tmp==0);\ + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\ + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\ + return a; + +u32 FASTCALL OP_CMP_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_CMP(1); +} + +u32 FASTCALL OP_CMP_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_CMP(2); +} + +u32 FASTCALL OP_CMP_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_CMP(1); +} + +u32 FASTCALL OP_CMP_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_CMP(2); +} + +u32 FASTCALL OP_CMP_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_CMP(1); +} + +u32 FASTCALL OP_CMP_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_CMP(2); +} + +u32 FASTCALL OP_CMP_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_CMP(1); +} + +u32 FASTCALL OP_CMP_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_CMP(2); +} + +u32 FASTCALL OP_CMP_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_CMP(1); +} + +//---------------CMN--------------------------- + +#define OP_CMN(a) u32 tmp = cpu->R[REG_POS(i,16)] + shift_op;\ + cpu->CPSR.bits.N = BIT31(tmp);\ + cpu->CPSR.bits.Z = (tmp==0);\ + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\ + cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_POS(i,16)], shift_op, tmp);\ + return a; + +u32 FASTCALL OP_CMN_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_CMN(1); +} + +u32 FASTCALL OP_CMN_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_CMN(2); +} + +u32 FASTCALL OP_CMN_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_CMN(1); +} + +u32 FASTCALL OP_CMN_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_CMN(2); +} + +u32 FASTCALL OP_CMN_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_CMN(1); +} + +u32 FASTCALL OP_CMN_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_CMN(2); +} + +u32 FASTCALL OP_CMN_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_CMN(1); +} + +u32 FASTCALL OP_CMN_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_CMN(2); +} + +u32 FASTCALL OP_CMN_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_CMN(1); +} + +//------------------ORR------------------- + +#define OP_ORR(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +u32 FASTCALL OP_ORR_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_ORR(1, 3); +} + +u32 FASTCALL OP_ORR_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_ORR(2, 4); +} + +u32 FASTCALL OP_ORR_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_ORR(1, 3); +} + +u32 FASTCALL OP_ORR_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_ORR(2, 4); +} + +u32 FASTCALL OP_ORR_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_ORR(1, 3); +} + +u32 FASTCALL OP_ORR_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_ORR(2, 4); +} + +u32 FASTCALL OP_ORR_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_ORR(1, 3); +} + +u32 FASTCALL OP_ORR_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_ORR(2, 4); +} + +u32 FASTCALL OP_ORR_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_ORR(1, 3); +} + +u32 FASTCALL OP_ORR_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +u32 FASTCALL OP_ORR_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 5; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 3; +} + +u32 FASTCALL OP_ORR_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +u32 FASTCALL OP_ORR_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 5; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 3; +} + +u32 FASTCALL OP_ORR_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +u32 FASTCALL OP_ORR_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 5; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 3; +} + +u32 FASTCALL OP_ORR_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +u32 FASTCALL OP_ORR_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 5; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 3; +} + +u32 FASTCALL OP_ORR_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] | shift_op; + if(REG_POS(i,12)==15) + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1)); + cpu->next_instruction = cpu->R[15]; + return 4; + } + cpu->CPSR.bits.C = c; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0); + return 2; +} + +//------------------MOV------------------- +#define OP_MOV(a, b) cpu->R[REG_POS(i,12)] = shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = shift_op;\ + return b;\ + }\ + return a; + +#define OP_MOV_S(a, b) cpu->R[REG_POS(i,12)] = shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a;\ + +u32 FASTCALL OP_MOV_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OP_MOV(1,3); +} + +u32 FASTCALL OP_MOV_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OP_MOV(2,4); +} + +u32 FASTCALL OP_MOV_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OP_MOV(1,3); +} + +u32 FASTCALL OP_MOV_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OP_MOV(2,4); +} + +u32 FASTCALL OP_MOV_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OP_MOV(1,3); +} + +u32 FASTCALL OP_MOV_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OP_MOV(2,4); +} + +u32 FASTCALL OP_MOV_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OP_MOV(2,4); +} + +u32 FASTCALL OP_MOV_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OP_MOV(2,4); +} + +u32 FASTCALL OP_MOV_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OP_MOV(1,3); +} + +u32 FASTCALL OP_MOV_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OP_MOV_S(2,4); +} + +u32 FASTCALL OP_MOV_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OP_MOV_S(3,5); +} + +u32 FASTCALL OP_MOV_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OP_MOV_S(2,4); +} + +u32 FASTCALL OP_MOV_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OP_MOV_S(3,5); +} + +u32 FASTCALL OP_MOV_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OP_MOV_S(2,4); +} + +u32 FASTCALL OP_MOV_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OP_MOV_S(3,5); +} + +u32 FASTCALL OP_MOV_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OP_MOV_S(2,4); +} + +u32 FASTCALL OP_MOV_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OP_MOV_S(3,5); +} + +u32 FASTCALL OP_MOV_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OP_MOV_S(2,4); +} + +//------------------BIC------------------- +#define OPP_BIC(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & (~shift_op);\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OPP_BIC_S(a, b) cpu->R[REG_POS(i,12)] = cpu->R[REG_POS(i,16)] & (~shift_op);\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a; + +u32 FASTCALL OP_BIC_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OPP_BIC(1,3); +} + +u32 FASTCALL OP_BIC_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OPP_BIC(2,4); +} + +u32 FASTCALL OP_BIC_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OPP_BIC(1,3); +} + +u32 FASTCALL OP_BIC_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OPP_BIC(2,4); +} + +u32 FASTCALL OP_BIC_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OPP_BIC(1,3); +} + +u32 FASTCALL OP_BIC_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OPP_BIC(2,4); +} + +u32 FASTCALL OP_BIC_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OPP_BIC(1,3); +} + +u32 FASTCALL OP_BIC_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OPP_BIC(2,4); +} + +u32 FASTCALL OP_BIC_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OPP_BIC(1,3); +} + +u32 FASTCALL OP_BIC_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OPP_BIC_S(2,4); +} + +u32 FASTCALL OP_BIC_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OPP_BIC_S(3,5); +} + +u32 FASTCALL OP_BIC_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OPP_BIC_S(2,4); +} + +u32 FASTCALL OP_BIC_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OPP_BIC_S(3,5); +} + +u32 FASTCALL OP_BIC_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OPP_BIC_S(2,4); +} + +u32 FASTCALL OP_BIC_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OPP_BIC_S(3,5); +} + +u32 FASTCALL OP_BIC_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OPP_BIC_S(2,4); +} + +u32 FASTCALL OP_BIC_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OPP_BIC_S(3,5); +} + +u32 FASTCALL OP_BIC_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OPP_BIC_S(2,4); +} + +//------------------MVN------------------- +#define OPP_MVN(a, b) cpu->R[REG_POS(i,12)] = ~shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + return a; + +#define OPP_MVN_S(a, b) cpu->R[REG_POS(i,12)] = ~shift_op;\ + if(REG_POS(i,12)==15)\ + {\ + Status_Reg SPSR = cpu->SPSR;\ + armcpu_switchMode(cpu, SPSR.bits.mode);\ + cpu->CPSR=SPSR;\ + cpu->R[15] &= (0X0FFFFFFC|(((u32)SPSR.bits.T)<<1));\ + cpu->next_instruction = cpu->R[15];\ + return b;\ + }\ + cpu->CPSR.bits.C = c;\ + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,12)]);\ + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,12)]==0);\ + return a; + +u32 FASTCALL OP_MVN_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + OPP_MVN(1,3); +} + +u32 FASTCALL OP_MVN_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_REG; + OPP_MVN(2,4); +} + +u32 FASTCALL OP_MVN_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + OPP_MVN(1,3); +} + +u32 FASTCALL OP_MVN_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_REG; + OPP_MVN(2,4); +} + +u32 FASTCALL OP_MVN_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + OPP_MVN(1,3); +} + +u32 FASTCALL OP_MVN_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_REG; + OPP_MVN(2,4); +} + +u32 FASTCALL OP_MVN_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + OPP_MVN(1,3); +} + +u32 FASTCALL OP_MVN_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_REG; + OPP_MVN(2,4); +} + +u32 FASTCALL OP_MVN_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + OPP_MVN(1,3); +} + +u32 FASTCALL OP_MVN_S_LSL_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_IMM; + OPP_MVN_S(2,4); +} + +u32 FASTCALL OP_MVN_S_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSL_REG; + OPP_MVN_S(3,5); +} + +u32 FASTCALL OP_MVN_S_LSR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_IMM; + OPP_MVN_S(2,4); +} + +u32 FASTCALL OP_MVN_S_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_LSR_REG; + OPP_MVN_S(3,5); +} + +u32 FASTCALL OP_MVN_S_ASR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_IMM; + OPP_MVN_S(2,4); +} + +u32 FASTCALL OP_MVN_S_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ASR_REG; + OPP_MVN_S(3,5); +} + +u32 FASTCALL OP_MVN_S_ROR_IMM(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_IMM; + OPP_MVN_S(2,4); +} + +u32 FASTCALL OP_MVN_S_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_ROR_REG; + OPP_MVN_S(3,5); +} + +u32 FASTCALL OP_MVN_S_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + S_IMM_VALUE; + OPP_MVN_S(2,4); +} + +//-------------MUL------------------------ +#define OPP_M(a,b) v >>= 8;\ + if((v==0)||(v==0xFFFFFF))\ + return b;\ + v >>= 8;\ + if((v==0)||(v==0xFFFF))\ + return b+1;\ + v >>= 8;\ + if((v==0)||(v==0xFF))\ + return b+2;\ + return a;\ + +u32 FASTCALL OP_MUL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v; + OPP_M(5,2); +} + +u32 FASTCALL OP_MLA(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u32 a = cpu->R[REG_POS(i,8)]; + u32 b = cpu->R[REG_POS(i,12)]; + cpu->R[REG_POS(i,16)] = a * v + b; + + OPP_M(6,3); +} + +u32 FASTCALL OP_MUL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v; + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0); + + OPP_M(6,3); +} + +u32 FASTCALL OP_MLA_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,16)] = cpu->R[REG_POS(i,8)] * v + cpu->R[REG_POS(i,12)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0); + OPP_M(7,4); +} + +//----------UMUL-------------------------- + +u32 FASTCALL OP_UMULL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] = (u32)(res>>32); + + OPP_M(6,3); +} + +u32 FASTCALL OP_UMLAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)] + (u64)cpu->R[REG_POS(i,12)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] += (u32)(res>>32); + + OPP_M(7,4); +} + +u32 FASTCALL OP_UMULL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] = (u32)(res>>32); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0); + + OPP_M(7,4); +} + +u32 FASTCALL OP_UMLAL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_POS(i,0)]; + u64 res = (u64)v * (u64)cpu->R[REG_POS(i,8)] + (u64)cpu->R[REG_POS(i,12)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] += (u32)(res>>32); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0); + + OPP_M(8,5); +} + +//----------SMUL-------------------------- + +u32 FASTCALL OP_SMULL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 v = (s32)cpu->R[REG_POS(i,0)]; + s64 b = (s32)cpu->R[REG_POS(i,8)]; + s64 res = v * b; + + cpu->R[REG_POS(i,12)] = (u32)(res&0xFFFFFFFF); + cpu->R[REG_POS(i,16)] = (u32)(res>>32); + + v &= 0xFFFFFFFF; + + OPP_M(6,3); +} + +u32 FASTCALL OP_SMLAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + s64 v = (s32)cpu->R[REG_POS(i,0)]; + s64 b = (s32)cpu->R[REG_POS(i,8)]; + s64 res = v * b + (u64)cpu->R[REG_POS(i,12)]; + + //LOG("%08X * %08X + %08X%08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], cpu->R[REG_POS(i,16)], cpu->R[REG_POS(i,12)]); + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] += (u32)(res>>32); + + //LOG("= %08X%08X %08X%08X\r\n", cpu->R[REG_POS(i,16)], cpu->R[REG_POS(i,12)], res); + + v &= 0xFFFFFFFF; + + OPP_M(7,4); +} + +u32 FASTCALL OP_SMULL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 v = (s32)cpu->R[REG_POS(i,0)]; + s64 b = (s32)cpu->R[REG_POS(i,8)]; + s64 res = v * b; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] = (u32)(res>>32); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0); + + v &= 0xFFFFFFFF; + + OPP_M(7,4); +} + +u32 FASTCALL OP_SMLAL_S(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 v = (s32)cpu->R[REG_POS(i,0)]; + s64 b = (s32)cpu->R[REG_POS(i,8)]; + s64 res = v * b + (u64)cpu->R[REG_POS(i,12)]; + + cpu->R[REG_POS(i,12)] = (u32)res; + cpu->R[REG_POS(i,16)] += (u32)(res>>32); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_POS(i,16)]); + cpu->CPSR.bits.Z = (cpu->R[REG_POS(i,16)]==0) & (cpu->R[REG_POS(i,12)]==0); + + v &= 0xFFFFFFFF; + + OPP_M(8,5); +} + +//---------------SWP------------------------------ + +u32 FASTCALL OP_SWP(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 tmp = ROR(MMU_readWord(cpu->proc_ID, adr), ((cpu->R[REG_POS(i,16)]&3)<<3)); + + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,0)]); + cpu->R[REG_POS(i,12)] = tmp; + + return 4 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]*2; +} + +u32 FASTCALL OP_SWPB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u8 tmp = MMU_readByte(cpu->proc_ID, adr); + MMU_writeByte(cpu->proc_ID, adr, (u8)(cpu->R[REG_POS(i,0)]&0xFF)); + cpu->R[REG_POS(i,12)] = tmp; + + return 4 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]*2; +} + +//------------LDRH----------------------------- + +u32 FASTCALL OP_LDRH_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_PRE_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_PRE_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_POS_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + cpu->R[REG_POS(i,16)] += IMM_OFF; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_POS_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + cpu->R[REG_POS(i,16)] -= IMM_OFF; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_POS_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)]; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_POS_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)]; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//------------STRH----------------------------- + +u32 FASTCALL OP_STRH_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_PRE_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_PRE_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_POS_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] += IMM_OFF; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_POS_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] -= IMM_OFF; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_POS_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)]; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_POS_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)]; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//----------------LDRSH-------------------------- + +u32 FASTCALL OP_LDRSH_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_PRE_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_PRE_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_PRE_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_PRE_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_POS_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] += IMM_OFF; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_POS_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] -= IMM_OFF; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_POS_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)]; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_POS_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)]; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//----------------------LDRSB---------------------- + +u32 FASTCALL OP_LDRSB_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_PRE_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_PRE_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_PRE_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_PRE_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - cpu->R[REG_POS(i,0)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_POS_INDE_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] += IMM_OFF; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_POS_INDE_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] -= IMM_OFF; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_POS_INDE_P_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] += cpu->R[REG_POS(i,0)]; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_POS_INDE_M_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + cpu->R[REG_POS(i,12)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + cpu->R[REG_POS(i,16)] -= cpu->R[REG_POS(i,0)]; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//--------------MRS-------------------------------- + +u32 FASTCALL OP_MRS_CPSR(armcpu_t *cpu) +{ + cpu->R[REG_POS(cpu->instruction,12)] = cpu->CPSR.val; + + return 1; +} + +u32 FASTCALL OP_MRS_SPSR(armcpu_t *cpu) +{ + cpu->R[REG_POS(cpu->instruction,12)] = cpu->SPSR.val; + + return 1; +} + +//--------------MSR-------------------------------- + +u32 FASTCALL OP_MSR_CPSR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 operand = cpu->R[REG_POS(i,0)]; + + if(cpu->CPSR.bits.mode!=USR) + { + if(BIT16(i)) + { + armcpu_switchMode(cpu, operand & 0x1F); + cpu->CPSR.val = (cpu->CPSR.val & 0xFFFFFF00) | (operand & 0xFF); + } + if(BIT17(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0xFFFF00FF) | (operand & 0xFF00); + if(BIT18(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0xFF00FFFF) | (operand & 0xFF0000); + } + if(BIT19(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (operand & 0xFF000000); + + return 1; +} + +u32 FASTCALL OP_MSR_SPSR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 operand = cpu->R[REG_POS(i,0)]; + + if(cpu->CPSR.bits.mode!=USR) + { + if(BIT16(i)) + { + cpu->SPSR.val = (cpu->SPSR.val & 0xFFFFFF00) | (operand & 0XFF); + } + if(BIT17(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFFFF00FF) | (operand & 0XFF00); + if(BIT18(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFF00FFFF) | (operand & 0XFF0000); + } + if(BIT19(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0x00FFFFFF) | (operand & 0XFF000000); + + return 1; +} + +u32 FASTCALL OP_MSR_CPSR_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + + if(cpu->CPSR.bits.mode!=USR) + { + if(BIT16(i)) + { + armcpu_switchMode(cpu, shift_op & 0x1F); + cpu->CPSR.val = (cpu->CPSR.val & 0xFFFFFF00) | (shift_op & 0XFF); + } + if(BIT17(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0xFFFF00FF) | (shift_op & 0XFF00); + if(BIT18(i)) + cpu->CPSR.val = (cpu->CPSR.val & 0xFF00FFFF) | (shift_op & 0XFF0000); + } + if(BIT19(i)) + { + //cpu->CPSR.val = (cpu->CPSR.val & 0xFF000000) | (shift_op & 0XFF000000); + cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (shift_op & 0xFF000000); + } + + return 1; +} + +u32 FASTCALL OP_MSR_SPSR_IMM_VAL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + IMM_VALUE; + + if(cpu->CPSR.bits.mode!=USR) + { + if(BIT16(i)) + { + cpu->SPSR.val = (cpu->SPSR.val & 0xFFFFFF00) | (shift_op & 0XFF); + } + if(BIT17(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFFFF00FF) | (shift_op & 0XFF00); + if(BIT18(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFF00FFFF) | (shift_op & 0XFF0000); + } + if(BIT19(i)) + cpu->SPSR.val = (cpu->SPSR.val & 0xFF000000) | (shift_op & 0XFF000000); + + return 1; +} + +//-----------------BRANCH-------------------------- + +u32 FASTCALL OP_BX(armcpu_t *cpu) +{ + u32 tmp = cpu->R[REG_POS(cpu->instruction, 0)]; + + cpu->CPSR.bits.T = BIT0(tmp); + cpu->R[15] = tmp & 0x0FFFFFFE; + cpu->next_instruction = cpu->R[15]; + return 3; +} + +u32 FASTCALL OP_BLX_REG(armcpu_t *cpu) +{ + u32 tmp = cpu->R[REG_POS(cpu->instruction, 0)]; + + cpu->R[14] = cpu->next_instruction; + cpu->CPSR.bits.T = BIT0(tmp); + cpu->R[15] = tmp & 0x0FFFFFFE; + cpu->next_instruction = cpu->R[15]; + return 3; +} + +#define SIGNEXTEND_24(i) (((s32)((i)<<8))>>8) + +u32 FASTCALL OP_B(armcpu_t *cpu) +{ + u32 off = SIGNEXTEND_24(cpu->instruction); + if(CONDITION(cpu->instruction)==0xF) + { + cpu->R[14] = cpu->next_instruction; + cpu->CPSR.bits.T = 1; + } + cpu->R[15] += (off<<2); + cpu->next_instruction = cpu->R[15]; + return 3; +} + +u32 FASTCALL OP_BL(armcpu_t *cpu) +{ + u32 off = SIGNEXTEND_24(cpu->instruction); + if(CONDITION(cpu->instruction)==0xF) + { + cpu->CPSR.bits.T = 1; + cpu->R[15] += 2; + } + cpu->R[14] = cpu->next_instruction; + cpu->R[15] += (off<<2); + cpu->next_instruction = cpu->R[15]; + return 3; +} + +//----------------CLZ------------------------------- + +u8 CLZ_TAB[16]= +{ + 0, // 0000 + 1, // 0001 + 2, 2, // 001X + 3, 3, 3, 3, // 01XX + 4, 4, 4, 4, 4, 4, 4, 4 // 1XXX +}; + +u32 FASTCALL OP_CLZ(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 Rm = cpu->R[REG_POS(i,0)]; + + if(Rm==0) + { + cpu->R[REG_POS(i,12)]=32; + return 2; + } + + Rm |= (Rm >>1); + Rm |= (Rm >>2); + Rm |= (Rm >>4); + Rm |= (Rm >>8); + Rm |= (Rm >>16); + + u32 pos = + CLZ_TAB[Rm&0xF] + + CLZ_TAB[(Rm>>4)&0xF] + + CLZ_TAB[(Rm>>8)&0xF] + + CLZ_TAB[(Rm>>12)&0xF] + + CLZ_TAB[(Rm>>16)&0xF] + + CLZ_TAB[(Rm>>20)&0xF] + + CLZ_TAB[(Rm>>24)&0xF] + + CLZ_TAB[(Rm>>28)&0xF]; + + cpu->R[REG_POS(i,12)]=32 - pos; + + return 2; +} + +//--------------------QADD--QSUB------------------------------ + +u32 FASTCALL OP_QADD(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 res = cpu->R[REG_POS(i,16)]+cpu->R[REG_POS(i,0)]; + + LOG("spe add\r\n"); + if(SIGNED_OVERFLOW(cpu->R[REG_POS(i,16)],cpu->R[REG_POS(i,0)], res)) + { + cpu->CPSR.bits.Q=1; + cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res); + return 2; + } + cpu->R[REG_POS(i,12)]=res; + if(REG_POS(i,12)==15) + { + cpu->R[15] &= 0X0FFFFFFC; + cpu->next_instruction = cpu->R[15]; + return 3; + } + return 2; +} + +u32 FASTCALL OP_QSUB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 res = cpu->R[REG_POS(i,0)]-cpu->R[REG_POS(i,16)]; + + LOG("spe add\r\n"); + if(SIGNED_UNDERFLOW(cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,16)], res)) + { + cpu->CPSR.bits.Q=1; + cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res); + return 2; + } + cpu->R[REG_POS(i,12)]=res; + if(REG_POS(i,12)==15) + { + cpu->R[15] &= 0X0FFFFFFC; + cpu->next_instruction = cpu->R[15]; + return 3; + } + return 2; +} + +u32 FASTCALL OP_QDADD(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 mul = cpu->R[REG_POS(i,16)]<<1; + u32 res; + + + LOG("spe add\r\n"); + if(BIT31(cpu->R[REG_POS(i,16)])!=BIT31(mul)) + { + cpu->CPSR.bits.Q=1; + mul = 0x80000000-BIT31(mul); + } + + res = mul + cpu->R[REG_POS(i,0)]; + if(SIGNED_OVERFLOW(cpu->R[REG_POS(i,0)],mul, res)) + { + cpu->CPSR.bits.Q=1; + cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res); + return 2; + } + cpu->R[REG_POS(i,12)]=res; + if(REG_POS(i,12)==15) + { + cpu->R[15] &= 0X0FFFFFFC; + cpu->next_instruction = cpu->R[15]; + return 3; + } + return 2; +} + +u32 FASTCALL OP_QDSUB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 mul = cpu->R[REG_POS(i,16)]<<1; + u32 res; + + + LOG("spe add\r\n"); + if(BIT31(cpu->R[REG_POS(i,16)])!=BIT31(mul)) + { + cpu->CPSR.bits.Q=1; + mul = 0x80000000-BIT31(mul); + } + + res = cpu->R[REG_POS(i,0)] - mul; + if(SIGNED_UNDERFLOW(cpu->R[REG_POS(i,0)], mul, res)) + { + cpu->CPSR.bits.Q=1; + cpu->R[REG_POS(i,12)]=0x80000000-BIT31(res); + return 2; + } + cpu->R[REG_POS(i,12)]=res; + if(REG_POS(i,12)==15) + { + cpu->R[15] &= 0X0FFFFFFC; + cpu->next_instruction = cpu->R[15]; + return 3; + } + return 2; +} + +//-----------------SMUL------------------------------- + +#define HWORD(i) ((s32)(((s32)(i))>>16)) +#define LWORD(i) (s32)(((s32)((i)<<16))>>16) + +u32 FASTCALL OP_SMUL_B_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + cpu->R[REG_POS(i,16)] = (u32)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + + return 2; +} + +u32 FASTCALL OP_SMUL_B_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + cpu->R[REG_POS(i,16)] = (u32)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + + return 2; +} + +u32 FASTCALL OP_SMUL_T_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + cpu->R[REG_POS(i,16)] = (u32)(HWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + + return 2; +} + +u32 FASTCALL OP_SMUL_T_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + cpu->R[REG_POS(i,16)] = (u32)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + + return 2; +} + +//-----------SMLA---------------------------- + +u32 FASTCALL OP_SMLA_B_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = (u32)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLABB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +u32 FASTCALL OP_SMLA_B_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = (u32)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLABT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +u32 FASTCALL OP_SMLA_T_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = (u32)(HWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLATB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +u32 FASTCALL OP_SMLA_T_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = (u32)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLATT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, tmp + a); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +//--------------SMLAL--------------------------------------- + +u32 FASTCALL OP_SMLAL_B_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)(LWORD(cpu->R[REG_POS(i,0)])* LWORD(cpu->R[REG_POS(i,8)])); + u64 res = (u64)tmp + cpu->R[REG_POS(i,12)]; + + LOG("SMLALBB %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + (res + ((tmp<0)*0xFFFFFFFF))), (int)(u32) res); + + cpu->R[REG_POS(i,12)] = (u32) res; + cpu->R[REG_POS(i,16)] += (res + ((tmp<0)*0xFFFFFFFF)); + + return 2; +} + +u32 FASTCALL OP_SMLAL_B_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)(LWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + u64 res = (u64)tmp + cpu->R[REG_POS(i,12)]; + + LOG("SMLALBT %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res); + + cpu->R[REG_POS(i,12)] = (u32) res; + cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF); + + return 2; +} + +u32 FASTCALL OP_SMLAL_T_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)(HWORD(cpu->R[REG_POS(i,0)])* (s64)LWORD(cpu->R[REG_POS(i,8)])); + u64 res = (u64)tmp + cpu->R[REG_POS(i,12)]; + + LOG("SMLALTB %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res); + + cpu->R[REG_POS(i,12)] = (u32) res; + cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF); + + return 2; +} + +u32 FASTCALL OP_SMLAL_T_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)(HWORD(cpu->R[REG_POS(i,0)])* HWORD(cpu->R[REG_POS(i,8)])); + u64 res = (u64)tmp + cpu->R[REG_POS(i,12)]; + + LOG("SMLALTT %08X * %08X + %08X%08X = %08X%08X\r\n", (int)cpu->R[REG_POS(i,0)], (int)cpu->R[REG_POS(i,8)], (int)cpu->R[REG_POS(i,16)], (int)cpu->R[REG_POS(i,12)], (int)(cpu->R[REG_POS(i,16)] + res + ((tmp<0)*0xFFFFFFFF)), (int)(u32) res); + + cpu->R[REG_POS(i,12)] = (u32) res; + cpu->R[REG_POS(i,16)] += res + ((tmp<0)*0xFFFFFFFF); + + return 2; +} + +//--------------SMULW-------------------- + +u32 FASTCALL OP_SMULW_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)LWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]); + + //LOG("SMULWB %08X * %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], ((tmp>>16)&0xFFFFFFFF); + + cpu->R[REG_POS(i,16)] = ((tmp>>16)&0xFFFFFFFF); + + return 2; +} + +u32 FASTCALL OP_SMULW_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)HWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]); + + //LOG("SMULWT %08X * %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], ((tmp>>16)&0xFFFFFFFF)); + + cpu->R[REG_POS(i,16)] = ((tmp>>16)&0xFFFFFFFF); + + return 2; +} + +//--------------SMLAW------------------- +u32 FASTCALL OP_SMLAW_B(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)LWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLAWB %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, (tmp>>16) + a); + + tmp = (tmp>>16); + + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +u32 FASTCALL OP_SMLAW_T(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + s64 tmp = (s64)HWORD(cpu->R[REG_POS(i,8)]) * (s64)((s32)cpu->R[REG_POS(i,0)]); + u32 a = cpu->R[REG_POS(i,12)]; + + //LOG("SMLAWT %08X * %08X + %08X = %08X\r\n", cpu->R[REG_POS(i,0)], cpu->R[REG_POS(i,8)], a, ((tmp>>16)&0xFFFFFFFF) + a); + + tmp = ((tmp>>16)&0xFFFFFFFF); + cpu->R[REG_POS(i,16)] = tmp + a; + + if(SIGNED_OVERFLOW(tmp, a, cpu->R[REG_POS(i,16)])) + cpu->CPSR.bits.Q = 1; + + return 2; +} + +//------------LDR--------------------------- + +u32 FASTCALL OP_LDR_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +//------------------------------------------------------------ +u32 FASTCALL OP_LDR_P_IMM_OFF_POSTIND2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + u32 old = armcpu_switchMode(cpu, USR); + cpu->R[REG_POS(i,12)] = val; + armcpu_switchMode(cpu, old); + + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +//------------------------------------------------------------ + +u32 FASTCALL OP_LDR_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + shift_op; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - shift_op; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + shift_op; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - shift_op; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + shift_op; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - shift_op; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr + shift_op; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readWord(cpu->proc_ID, adr); + + if(adr&3) + val = ROR(val, 8*(adr&3)); + + if(REG_POS(i,12)==15) + { + cpu->R[15] = val & (0X0FFFFFFC | (((u32)cpu->LDTBit)<<1)); + cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; + cpu->next_instruction = cpu->R[15]; + cpu->R[REG_POS(i,16)] = adr - shift_op; + return 5 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + } + + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +//-----------------LDRB------------------------------------------- + +u32 FASTCALL OP_LDRB_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//----------------------STR-------------------------------- + +u32 FASTCALL OP_STR_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +//-----------------------STRB------------------------------------- + +u32 FASTCALL OP_STRB_P_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_LSL_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_LSR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_ASR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_ROR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; + MMU_writeByte(cpu->proc_ID, adr, cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)] - IMM_OFF_12; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_LSL_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_LSR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_ASR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] + shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_ROR_IMM_OFF_PREIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)] - shift_op; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//-----------------------LDRBT------------------------------------- + +u32 FASTCALL OP_LDRBT_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + u32 oldmode = armcpu_switchMode(cpu, SYS); + + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_P_REG_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + cpu->R[REG_POS(i,0)]; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRBT_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + u32 val = MMU_readByte(cpu->proc_ID, adr); + cpu->R[REG_POS(i,12)] = val; + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//----------------------STRBT---------------------------- + +u32 FASTCALL OP_STRBT_P_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + IMM_OFF_12; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_M_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - IMM_OFF_12; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_P_REG_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + cpu->R[REG_POS(i,0)]; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_M_REG_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - cpu->R[REG_POS(i,0)]; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_P_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_M_LSL_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + LSL_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_P_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_M_LSR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + LSR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_P_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_M_ASR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + ASR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_P_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr + shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRBT_M_ROR_IMM_OFF_POSTIND(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 oldmode = armcpu_switchMode(cpu, SYS); + + + u32 i = cpu->instruction; + ROR_IMM; + u32 adr = cpu->R[REG_POS(i,16)]; + MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_POS(i,12)]); + cpu->R[REG_POS(i,16)] = adr - shift_op; + + armcpu_switchMode(cpu, oldmode); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +//---------------------LDM----------------------------- + +#define OP_L_IA(reg, adr) if(BIT##reg(i))\ + {\ + registres[reg] = MMU_readWord(cpu->proc_ID, start);\ + c += waitState[(start>>24)&0xF];\ + adr += 4;\ + } + +#define OP_L_IB(reg, adr) if(BIT##reg(i))\ + {\ + adr += 4;\ + registres[reg] = MMU_readWord(cpu->proc_ID, start);\ + c += waitState[(start>>24)&0xF];\ + } + +#define OP_L_DA(reg, adr) if(BIT##reg(i))\ + {\ + registres[reg] = MMU_readWord(cpu->proc_ID, start);\ + c += waitState[(start>>24)&0xF];\ + adr -= 4;\ + } + +#define OP_L_DB(reg, adr) if(BIT##reg(i))\ + {\ + adr -= 4;\ + registres[reg] = MMU_readWord(cpu->proc_ID, start);\ + c += waitState[(start>>24)&0xF];\ + } + +u32 FASTCALL OP_LDMIA(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + OP_L_IA(0, start); + OP_L_IA(1, start); + OP_L_IA(2, start); + OP_L_IA(3, start); + OP_L_IA(4, start); + OP_L_IA(5, start); + OP_L_IA(6, start); + OP_L_IA(7, start); + OP_L_IA(8, start); + OP_L_IA(9, start); + OP_L_IA(10, start); + OP_L_IA(11, start); + OP_L_IA(12, start); + OP_L_IA(13, start); + OP_L_IA(14, start); + + if(BIT15(i)) + { + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + //start += 4; + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + + return c + 2; +} + +u32 FASTCALL OP_LDMIB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + OP_L_IB(0, start); + OP_L_IB(1, start); + OP_L_IB(2, start); + OP_L_IB(3, start); + OP_L_IB(4, start); + OP_L_IB(5, start); + OP_L_IB(6, start); + OP_L_IB(7, start); + OP_L_IB(8, start); + OP_L_IB(9, start); + OP_L_IB(10, start); + OP_L_IB(11, start); + OP_L_IB(12, start); + OP_L_IB(13, start); + OP_L_IB(14, start); + + if(BIT15(i)) + { + start += 4; + c += waitState[(start>>24)&0xF]; + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + cpu->next_instruction = registres[15]; + c += 2 + (c==0); + } + + return c + 2; +} + +u32 FASTCALL OP_LDMDA(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + c += waitState[(start>>24)&0xF]; + start -= 4; + cpu->next_instruction = registres[15]; + } + + OP_L_DA(14, start); + OP_L_DA(13, start); + OP_L_DA(12, start); + OP_L_DA(11, start); + OP_L_DA(10, start); + OP_L_DA(9, start); + OP_L_DA(8, start); + OP_L_DA(7, start); + OP_L_DA(6, start); + OP_L_DA(5, start); + OP_L_DA(4, start); + OP_L_DA(3, start); + OP_L_DA(2, start); + OP_L_DA(1, start); + OP_L_DA(0, start); + + return c + 2; +} + +u32 FASTCALL OP_LDMDB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + start -= 4; + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + + OP_L_DB(14, start); + OP_L_DB(13, start); + OP_L_DB(12, start); + OP_L_DB(11, start); + OP_L_DB(10, start); + OP_L_DB(9, start); + OP_L_DB(8, start); + OP_L_DB(7, start); + OP_L_DB(6, start); + OP_L_DB(5, start); + OP_L_DB(4, start); + OP_L_DB(3, start); + OP_L_DB(2, start); + OP_L_DB(1, start); + OP_L_DB(0, start); + + return c + 2; +} + +u32 FASTCALL OP_LDMIA_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + OP_L_IA(0, start); + OP_L_IA(1, start); + OP_L_IA(2, start); + OP_L_IA(3, start); + OP_L_IA(4, start); + OP_L_IA(5, start); + OP_L_IA(6, start); + OP_L_IA(7, start); + OP_L_IA(8, start); + OP_L_IA(9, start); + OP_L_IA(10, start); + OP_L_IA(11, start); + OP_L_IA(12, start); + OP_L_IA(13, start); + OP_L_IA(14, start); + + if(BIT15(i)) + { + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + c += waitState[(start>>24)&0xF]; + start += 4; + cpu->next_instruction = registres[15]; + } + + cpu->R[REG_POS(i,16)] = start; + return c + 2; +} + +u32 FASTCALL OP_LDMIB_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + OP_L_IB(0, start); + OP_L_IB(1, start); + OP_L_IB(2, start); + OP_L_IB(3, start); + OP_L_IB(4, start); + OP_L_IB(5, start); + OP_L_IB(6, start); + OP_L_IB(7, start); + OP_L_IB(8, start); + OP_L_IB(9, start); + OP_L_IB(10, start); + OP_L_IB(11, start); + OP_L_IB(12, start); + OP_L_IB(13, start); + OP_L_IB(14, start); + + if(BIT15(i)) + { + start += 4; + c += waitState[(start>>24)&0xF]; + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + cpu->next_instruction = registres[15]; + c += 2 + (c==0); + } + cpu->R[REG_POS(i,16)] = start; + return c + 2; +} + +u32 FASTCALL OP_LDMDA_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + c += waitState[(start>>24)&0xF]; + start -= 4; + cpu->next_instruction = registres[15]; + } + + OP_L_DA(14, start); + OP_L_DA(13, start); + OP_L_DA(12, start); + OP_L_DA(11, start); + OP_L_DA(10, start); + OP_L_DA(9, start); + OP_L_DA(8, start); + OP_L_DA(7, start); + OP_L_DA(6, start); + OP_L_DA(5, start); + OP_L_DA(4, start); + OP_L_DA(3, start); + OP_L_DA(2, start); + OP_L_DA(1, start); + OP_L_DA(0, start); + + cpu->R[REG_POS(i,16)] = start; + return c + 2; +} + +u32 FASTCALL OP_LDMDB_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 start = cpu->R[REG_POS(i,16)]; + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + start -= 4; + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR.bits.T = BIT0(tmp); + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + + OP_L_DB(14, start); + OP_L_DB(13, start); + OP_L_DB(12, start); + OP_L_DB(11, start); + OP_L_DB(10, start); + OP_L_DB(9, start); + OP_L_DB(8, start); + OP_L_DB(7, start); + OP_L_DB(6, start); + OP_L_DB(5, start); + OP_L_DB(4, start); + OP_L_DB(3, start); + OP_L_DB(2, start); + OP_L_DB(1, start); + OP_L_DB(0, start); + + cpu->R[REG_POS(i,16)] = start; + return c + 2; +} + +u32 FASTCALL OP_LDMIA2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 oldmode; + + u32 c = 0; + + u32 start = cpu->R[REG_POS(i,16)]; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 1; + oldmode = armcpu_switchMode(cpu, SYS); + } + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + OP_L_IA(0, start); + OP_L_IA(1, start); + OP_L_IA(2, start); + OP_L_IA(3, start); + OP_L_IA(4, start); + OP_L_IA(5, start); + OP_L_IA(6, start); + OP_L_IA(7, start); + OP_L_IA(8, start); + OP_L_IA(9, start); + OP_L_IA(10, start); + OP_L_IA(11, start); + OP_L_IA(12, start); + OP_L_IA(13, start); + OP_L_IA(14, start); + + if(BIT15(i)) + { + u32 tmp = MMU_readWord(cpu->proc_ID, start); + cpu->R[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + //start += 4; + cpu->next_instruction = cpu->R[15]; + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + else + { + armcpu_switchMode(cpu, oldmode); + } + return c + 2; +} + +u32 FASTCALL OP_LDMIB2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 oldmode; + u32 c = 0; + + u32 start = cpu->R[REG_POS(i,16)]; + execute = FALSE; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + OP_L_IB(0, start); + OP_L_IB(1, start); + OP_L_IB(2, start); + OP_L_IB(3, start); + OP_L_IB(4, start); + OP_L_IB(5, start); + OP_L_IB(6, start); + OP_L_IB(7, start); + OP_L_IB(8, start); + OP_L_IB(9, start); + OP_L_IB(10, start); + OP_L_IB(11, start); + OP_L_IB(12, start); + OP_L_IB(13, start); + OP_L_IB(14, start); + + if(BIT15(i)) + { + start += 4; + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + else + { + armcpu_switchMode(cpu, oldmode); + } + return c + 2; +} + +u32 FASTCALL OP_LDMDA2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + u32 oldmode; + u32 c = 0; + + u32 start = cpu->R[REG_POS(i,16)]; + execute = FALSE; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR = cpu->SPSR; + c += waitState[(start>>24)&0xF]; + start -= 4; + cpu->next_instruction = registres[15]; + } + + OP_L_DA(14, start); + OP_L_DA(13, start); + OP_L_DA(12, start); + OP_L_DA(11, start); + OP_L_DA(10, start); + OP_L_DA(9, start); + OP_L_DA(8, start); + OP_L_DA(7, start); + OP_L_DA(6, start); + OP_L_DA(5, start); + OP_L_DA(4, start); + OP_L_DA(3, start); + OP_L_DA(2, start); + OP_L_DA(1, start); + OP_L_DA(0, start); + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + } + else + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + } + + return c + 2; +} + +u32 FASTCALL OP_LDMDB2(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + + u32 oldmode; + u32 c = 0; + + u32 start = cpu->R[REG_POS(i,16)]; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + start -= 4; + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR = cpu->SPSR; + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + } + + OP_L_DB(14, start); + OP_L_DB(13, start); + OP_L_DB(12, start); + OP_L_DB(11, start); + OP_L_DB(10, start); + OP_L_DB(9, start); + OP_L_DB(8, start); + OP_L_DB(7, start); + OP_L_DB(6, start); + OP_L_DB(5, start); + OP_L_DB(4, start); + OP_L_DB(3, start); + OP_L_DB(2, start); + OP_L_DB(1, start); + OP_L_DB(0, start); + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + } + else + { + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + } + + return 2 + c; +} + +u32 FASTCALL OP_LDMIA2_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + + u32 oldmode; + u32 start = cpu->R[REG_POS(i,16)]; + execute = FALSE; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + OP_L_IA(0, start); + OP_L_IA(1, start); + OP_L_IA(2, start); + OP_L_IA(3, start); + OP_L_IA(4, start); + OP_L_IA(5, start); + OP_L_IA(6, start); + OP_L_IA(7, start); + OP_L_IA(8, start); + OP_L_IA(9, start); + OP_L_IA(10, start); + OP_L_IA(11, start); + OP_L_IA(12, start); + OP_L_IA(13, start); + OP_L_IA(14, start); + + if(BIT15(i)==0) + { + registres[REG_POS(i,16)] = start; + armcpu_switchMode(cpu, oldmode); + return c + 2; + } + + registres[REG_POS(i,16)] = start + 4; + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + cpu->next_instruction = registres[15]; + c += waitState[(start>>24)&0xF]; + + return c + 2; +} + +u32 FASTCALL OP_LDMIB2_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + + u32 oldmode; + u32 start = cpu->R[REG_POS(i,16)]; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + OP_L_IB(0, start); + OP_L_IB(1, start); + OP_L_IB(2, start); + OP_L_IB(3, start); + OP_L_IB(4, start); + OP_L_IB(5, start); + OP_L_IB(6, start); + OP_L_IB(7, start); + OP_L_IB(8, start); + OP_L_IB(9, start); + OP_L_IB(10, start); + OP_L_IB(11, start); + OP_L_IB(12, start); + OP_L_IB(13, start); + OP_L_IB(14, start); + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + registres[REG_POS(i,16)] = start; + + return c + 2; + } + + registres[REG_POS(i,16)] = start + 4; + u32 tmp = MMU_readWord(cpu->proc_ID, start + 4); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR = cpu->SPSR; + cpu->next_instruction = registres[15]; + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + c += waitState[(start>>24)&0xF]; + + return c + 2; +} + +u32 FASTCALL OP_LDMDA2_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + + u32 oldmode; + u32 start = cpu->R[REG_POS(i,16)]; + execute = FALSE; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + u32 tmp = MMU_readWord(cpu->proc_ID, start); + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + c += waitState[(start>>24)&0xF]; + start -= 4; + cpu->next_instruction = registres[15]; + } + + OP_L_DA(14, start); + OP_L_DA(13, start); + OP_L_DA(12, start); + OP_L_DA(11, start); + OP_L_DA(10, start); + OP_L_DA(9, start); + OP_L_DA(8, start); + OP_L_DA(7, start); + OP_L_DA(6, start); + OP_L_DA(5, start); + OP_L_DA(4, start); + OP_L_DA(3, start); + OP_L_DA(2, start); + OP_L_DA(1, start); + OP_L_DA(0, start); + + registres[REG_POS(i,16)] = start; + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + return c + 2; + } + + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + return c + 2; +} + +u32 FASTCALL OP_LDMDB2_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + + u32 oldmode; + u32 start = cpu->R[REG_POS(i,16)]; + execute = FALSE; + if(BIT15(i)==0) + { + if(cpu->CPSR.bits.mode==USR) + return 2; + oldmode = armcpu_switchMode(cpu, SYS); + } + + u32 * registres = cpu->R; + u32 * waitState = MMU.MMU_WAIT32[cpu->proc_ID]; + + if(BIT15(i)) + { + start -= 4; + u32 tmp = MMU_readWord(cpu->proc_ID, start); + c += waitState[(start>>24)&0xF]; + registres[15] = tmp & (0X0FFFFFFC | (BIT0(tmp)<<1)); + cpu->CPSR = cpu->SPSR; + cpu->next_instruction = registres[15]; + } + + OP_L_DB(14, start); + OP_L_DB(13, start); + OP_L_DB(12, start); + OP_L_DB(11, start); + OP_L_DB(10, start); + OP_L_DB(9, start); + OP_L_DB(8, start); + OP_L_DB(7, start); + OP_L_DB(6, start); + OP_L_DB(5, start); + OP_L_DB(4, start); + OP_L_DB(3, start); + OP_L_DB(2, start); + OP_L_DB(1, start); + OP_L_DB(0, start); + + registres[REG_POS(i,16)] = start; + + if(BIT15(i)==0) + { + armcpu_switchMode(cpu, oldmode); + return c + 2; + } + + Status_Reg SPSR = cpu->SPSR; + armcpu_switchMode(cpu, SPSR.bits.mode); + cpu->CPSR=SPSR; + return c + 2; +} + +//------------------------------STM---------------------------------- + +u32 FASTCALL OP_STMIA(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 b; + + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + MMU_writeWord(cpu->proc_ID, start, cpu->R[b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start += 4; + } + } + return c + 1; +} + +u32 FASTCALL OP_STMIB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 b; + + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + start += 4; + MMU_writeWord(cpu->proc_ID, start, cpu->R[b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + return c + 1; +} + +u32 FASTCALL OP_STMDA(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 b; + + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + MMU_writeWord(cpu->proc_ID, start, cpu->R[15-b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start -= 4; + } + } + return c + 1; +} + +u32 FASTCALL OP_STMDB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 b; + + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + start -= 4; + MMU_writeWord(cpu->proc_ID, start, cpu->R[15-b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + return c + 1; +} + +u32 FASTCALL OP_STMIA_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 b; + + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + MMU_writeWord(cpu->proc_ID, start, cpu->R[b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start += 4; + } + } + + cpu->R[REG_POS(i,16)] = start; + return c + 1; +} + +u32 FASTCALL OP_STMIB_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 b; + + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + start += 4; + MMU_writeWord(cpu->proc_ID, start, cpu->R[b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + cpu->R[REG_POS(i,16)] = start; + return c + 1; +} + +u32 FASTCALL OP_STMDA_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 b; + + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + MMU_writeWord(cpu->proc_ID, start, cpu->R[15-b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start -= 4; + } + } + + cpu->R[REG_POS(i,16)] = start; + return c + 1; +} + +u32 FASTCALL OP_STMDB_W(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 c = 0; + u32 b; + u32 start = cpu->R[REG_POS(i,16)]; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + start -= 4; + MMU_writeWord(cpu->proc_ID, start, cpu->R[15-b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + + cpu->R[REG_POS(i,16)] = start; + return c + 1; +} + +u32 FASTCALL OP_STMIA2(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 i = cpu->instruction; + u32 start = cpu->R[REG_POS(i,16)]; + u32 oldmode = armcpu_switchMode(cpu, SYS); + u32 b; + + execute = FALSE; + u32 c = 0; + + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + MMU_writeWord(cpu->proc_ID, start, cpu->R[b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start += 4; + } + } + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +u32 FASTCALL OP_STMIB2(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 i = cpu->instruction; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 oldmode = armcpu_switchMode(cpu, SYS); + u32 b; + + execute = FALSE; + u32 c = 0; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + start += 4; + MMU_writeWord(cpu->proc_ID, start, cpu->R[b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +u32 FASTCALL OP_STMDA2(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + u32 c = 0; + + u32 i = cpu->instruction; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 b; + + execute = FALSE; + u32 oldmode = armcpu_switchMode(cpu, SYS); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + MMU_writeWord(cpu->proc_ID, start, cpu->R[15-b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start -= 4; + } + } + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +u32 FASTCALL OP_STMDB2(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + u32 c = 0; + u32 b; + + u32 i = cpu->instruction; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 oldmode = armcpu_switchMode(cpu, SYS); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + start -= 4; + MMU_writeWord(cpu->proc_ID, start, cpu->R[15-b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +u32 FASTCALL OP_STMIA2_W(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + u32 c = 0; + u32 b; + + u32 i = cpu->instruction; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + MMU_writeWord(cpu->proc_ID, start, cpu->R[b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start += 4; + } + } + + cpu->R[REG_POS(i,16)] = start; + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +u32 FASTCALL OP_STMIB2_W(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + u32 c = 0; + u32 b; + + u32 i = cpu->instruction; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 oldmode = armcpu_switchMode(cpu, SYS); + + for(b=0; b<16; ++b) + { + if(BIT_N(i, b)) + { + start += 4; + MMU_writeWord(cpu->proc_ID, start, cpu->R[b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + armcpu_switchMode(cpu, oldmode); + cpu->R[REG_POS(i,16)] = start; + + return c + 1; +} + +u32 FASTCALL OP_STMDA2_W(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 i = cpu->instruction; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + u32 c = 0; + u32 b; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + MMU_writeWord(cpu->proc_ID, start, cpu->R[15-b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + start -= 4; + } + } + + cpu->R[REG_POS(i,16)] = start; + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +u32 FASTCALL OP_STMDB2_W(armcpu_t *cpu) +{ + if(cpu->CPSR.bits.mode==USR) + return 2; + + u32 i = cpu->instruction; + + u32 start = cpu->R[REG_POS(i,16)]; + u32 oldmode = armcpu_switchMode(cpu, SYS); + execute = FALSE; + + u32 c = 0; + u32 b; + + for(b=0; b<16; ++b) + { + if(BIT_N(i, 15-b)) + { + start -= 4; + MMU_writeWord(cpu->proc_ID, start, cpu->R[15-b]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(start>>24)&0xF]; + } + } + + cpu->R[REG_POS(i,16)] = start; + + armcpu_switchMode(cpu, oldmode); + return c + 1; +} + +//---------------------STC---------------------------------- + +u32 FASTCALL OP_STC_P_IMM_OFF(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_STC_M_IMM_OFF(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_STC_P_PREIND(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_STC_M_PREIND(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_STC_P_POSTIND(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_STC_M_POSTIND(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_STC_OPTION(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +//---------------------LDC---------------------------------- + +u32 FASTCALL OP_LDC_P_IMM_OFF(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_LDC_M_IMM_OFF(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_LDC_P_PREIND(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_LDC_M_PREIND(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_LDC_P_POSTIND(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_LDC_M_POSTIND(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +u32 FASTCALL OP_LDC_OPTION(armcpu_t *cpu) +{ + { + execute = FALSE; + return 2; + } +} + +//----------------MCR----------------------- + +u32 FASTCALL OP_MCR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 cpnum = REG_POS(i, 8); + + if(!cpu->coproc[cpnum]) + { + execute = FALSE; + return 2; + } + + armcp15_moveARM2CP((armcp15_t*)cpu->coproc[cpnum], cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7); + //cpu->coproc[cpnum]->moveARM2CP(cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7); + return 2; +} + +//----------------MRC----------------------- + +u32 FASTCALL OP_MRC(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 cpnum = REG_POS(i, 8); + + if(!cpu->coproc[cpnum]) + { + execute = FALSE; + return 2; + } + + armcp15_moveCP2ARM((armcp15_t*)cpu->coproc[cpnum], &cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7); + //cpu->coproc[cpnum]->moveCP2ARM(&cpu->R[REG_POS(i, 12)], REG_POS(i, 16), REG_POS(i, 0), (i>>21)&7, (i>>5)&7); + return 4; +} + +//--------------SWI------------------------------- +u32 FASTCALL OP_SWI(armcpu_t *cpu) +{ + u32 swinum = (cpu->instruction>>16)&0x1F; + return cpu->swi_tab[swinum](cpu) + 3; +} + +//----------------BKPT------------------------- +u32 FASTCALL OP_BKPT(armcpu_t *cpu) +{ + execute = FALSE; + return 4; +} + +//----------------CDP----------------------- + +u32 FASTCALL OP_CDP(armcpu_t *cpu) +{ + execute = FALSE; + return 4; +} + +#define TYPE_RETOUR u32 +#define PARAMETRES armcpu_t *cpu +#define CALLTYPE FASTCALL +#define NOM_TAB arm_instructions_set + +#include "instruction_tabdef.inc" + + + + + + + + + + + + + + + + + + + + + diff --git a/desmume/src/armcpu.c b/desmume/src/armcpu.c new file mode 100644 index 000000000..55ecc3ae1 --- /dev/null +++ b/desmume/src/armcpu.c @@ -0,0 +1,255 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "arm_instructions.h" +#include "thumb_instructions.h" +#include "cp15.h" +#include "bios.h" +#include +#include + +armcpu_t NDS_ARM7; +armcpu_t NDS_ARM9; + +#define SWAP(a, b, c) c=a;\ + a=b;\ + b=c; + +int armcpu_new(armcpu_t *armcpu, u32 id) +{ + + armcpu->proc_ID = id; + + if(id==0) armcpu->swi_tab = ARM9_swi_tab; + else armcpu->swi_tab = ARM7_swi_tab; + + armcpu_init(armcpu, 0); + + return 0; +} + +void armcpu_init(armcpu_t *armcpu, u32 adr) +{ + u32 i; + + armcpu->LDTBit = (armcpu->proc_ID==0); //Si ARM9 utiliser le syte v5 pour le load + armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0); + armcpu->waitIRQ = FALSE; + armcpu->wirq = FALSE; + + if(armcpu->coproc[15]) free(armcpu->coproc[15]); + + for(i = 0; i < 15; ++i) + { + armcpu->R[i] = 0; + armcpu->coproc[i] = NULL; + } + + armcpu->CPSR.val = armcpu->SPSR.val = SYS; + + armcpu->R13_usr = armcpu->R14_usr = 0; + armcpu->R13_svc = armcpu->R14_svc = 0; + armcpu->R13_abt = armcpu->R14_abt = 0; + armcpu->R13_und = armcpu->R14_und = 0; + armcpu->R13_irq = armcpu->R14_irq = 0; + armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0; + + armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0; + armcpu->next_instruction = adr; + armcpu->R[15] = adr; + armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu); + + armcpu_prefetch(armcpu); +} + +u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode) +{ + u32 oldmode = armcpu->CPSR.bits.mode; + + switch(oldmode) + { + case USR : + case SYS : + armcpu->R13_usr = armcpu->R[13]; + armcpu->R14_usr = armcpu->R[14]; + break; + + case FIQ : + { + u32 tmp; + SWAP(armcpu->R[8], armcpu->R8_fiq, tmp); + SWAP(armcpu->R[9], armcpu->R9_fiq, tmp); + SWAP(armcpu->R[10], armcpu->R10_fiq, tmp); + SWAP(armcpu->R[11], armcpu->R11_fiq, tmp); + SWAP(armcpu->R[12], armcpu->R12_fiq, tmp); + armcpu->R13_fiq = armcpu->R[13]; + armcpu->R14_fiq = armcpu->R[14]; + armcpu->SPSR_fiq = armcpu->SPSR; + break; + } + case IRQ : + armcpu->R13_irq = armcpu->R[13]; + armcpu->R14_irq = armcpu->R[14]; + armcpu->SPSR_irq = armcpu->SPSR; + break; + + case SVC : + armcpu->R13_svc = armcpu->R[13]; + armcpu->R14_svc = armcpu->R[14]; + armcpu->SPSR_svc = armcpu->SPSR; + break; + + case ABT : + armcpu->R13_abt = armcpu->R[13]; + armcpu->R14_abt = armcpu->R[14]; + armcpu->SPSR_abt = armcpu->SPSR; + break; + + case UND : + armcpu->R13_und = armcpu->R[13]; + armcpu->R14_und = armcpu->R[14]; + armcpu->SPSR_und = armcpu->SPSR; + break; + default : + break; + } + + switch(mode) + { + case USR : + case SYS : + armcpu->R[13] = armcpu->R13_usr; + armcpu->R[14] = armcpu->R14_usr; + //SPSR = CPSR; + break; + + case FIQ : + { + u32 tmp; + SWAP(armcpu->R[8], armcpu->R8_fiq, tmp); + SWAP(armcpu->R[9], armcpu->R9_fiq, tmp); + SWAP(armcpu->R[10], armcpu->R10_fiq, tmp); + SWAP(armcpu->R[11], armcpu->R11_fiq, tmp); + SWAP(armcpu->R[12], armcpu->R12_fiq, tmp); + armcpu->R[13] = armcpu->R13_fiq; + armcpu->R[14] = armcpu->R14_fiq; + armcpu->SPSR = armcpu->SPSR_fiq; + break; + } + + case IRQ : + armcpu->R[13] = armcpu->R13_irq; + armcpu->R[14] = armcpu->R14_irq; + armcpu->SPSR = armcpu->SPSR_irq; + break; + + case SVC : + armcpu->R[13] = armcpu->R13_svc; + armcpu->R[14] = armcpu->R14_svc; + armcpu->SPSR = armcpu->SPSR_svc; + break; + + case ABT : + armcpu->R[13] = armcpu->R13_abt; + armcpu->R[14] = armcpu->R14_abt; + armcpu->SPSR = armcpu->SPSR_abt; + break; + + case UND : + armcpu->R[13] = armcpu->R13_und; + armcpu->R[14] = armcpu->R14_und; + armcpu->SPSR = armcpu->SPSR_und; + break; + + default : + break; + } + + armcpu->CPSR.bits.mode = mode & 0x1F; + return oldmode; +} + +u32 armcpu_prefetch(armcpu_t *armcpu) +{ + if(armcpu->CPSR.bits.T == 0) + { + armcpu->instruction = MMU_readWord(armcpu->proc_ID, armcpu->next_instruction); + armcpu->instruct_adr = armcpu->next_instruction; + armcpu->next_instruction += 4; + armcpu->R[15] = armcpu->next_instruction + 4; + return MMU.MMU_WAIT32[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF]; + } + armcpu->instruction = MMU_readHWord(armcpu->proc_ID, armcpu->next_instruction); + armcpu->instruct_adr = armcpu->next_instruction; + armcpu->next_instruction = armcpu->next_instruction + 2; + armcpu->R[15] = armcpu->next_instruction + 2; + return MMU.MMU_WAIT16[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF]; +} + +u32 armcpu_exec(armcpu_t *armcpu) +{ + u32 c = 1; + if(armcpu->CPSR.bits.T == 0) + { + if((TEST_COND(CONDITION(armcpu->instruction), armcpu->CPSR)) || ((CONDITION(armcpu->instruction)==0xF)&&(CODE(armcpu->instruction)==0x5))) + { + c = arm_instructions_set[INSTRUCTION_INDEX(armcpu->instruction)](armcpu); + } + c += armcpu_prefetch(armcpu); + return c; + } + c = thumb_instructions_set[armcpu->instruction>>6](armcpu); + c += armcpu_prefetch(armcpu); + return c; +} + +BOOL armcpu_irqExeption(armcpu_t *armcpu) +{ + if(armcpu->CPSR.bits.I) return FALSE; + Status_Reg tmp = armcpu->CPSR; + armcpu_switchMode(armcpu, IRQ); + armcpu->R[14] = armcpu->instruct_adr + 4; + armcpu->SPSR = tmp; + armcpu->CPSR.bits.T = 0; + armcpu->CPSR.bits.I = 1; + armcpu->next_instruction = armcpu->intVector + 0x18; + armcpu->R[15] = armcpu->next_instruction; + armcpu->waitIRQ = 0; + armcpu_prefetch(armcpu); + return TRUE; +} + +BOOL armcpu_prefetchExeption(armcpu_t *armcpu) +{ + if(armcpu->CPSR.bits.I) return FALSE; + Status_Reg tmp = armcpu->CPSR; + armcpu_switchMode(armcpu, ABT); + armcpu->R[14] = armcpu->instruct_adr + 4; + armcpu->SPSR = tmp; + armcpu->CPSR.bits.T = 0; + armcpu->CPSR.bits.I = 1; + armcpu->next_instruction = armcpu->intVector + 0xC; + armcpu->R[15] = armcpu->next_instruction; + armcpu->waitIRQ = 0; + armcpu_prefetch(armcpu); + return TRUE; +} + diff --git a/desmume/src/armcpu.h b/desmume/src/armcpu.h index 0f81c9ede..0ecef50f9 100644 --- a/desmume/src/armcpu.h +++ b/desmume/src/armcpu.h @@ -24,7 +24,7 @@ #include "types.h" #include "bits.h" -#include "MMU.hpp" +#include "MMU.h" #define ARMCPU_ARM7 1 #define ARMCPU_ARM9 0 @@ -155,13 +155,13 @@ BOOL armcpu_prefetchExeption(armcpu_t *armcpu); extern armcpu_t NDS_ARM7; extern armcpu_t NDS_ARM9; -INLINE void NDS_makeARM9Int(u32 num) +static INLINE void NDS_makeARM9Int(u32 num) { MMU.reg_IF[0] |= (1< +#include "MMU.h" +#include "debug.h" + +extern BOOL execute; + +u32 bios_nop(armcpu_t * cpu) +{ + //sprintf(biostxt, "PROC %d, SWI PO IMPLEMENTE %08X R0:%08X", cpu->proc_ID, (cpu->instruction)&0x1F, cpu->R[0]); + //execute = FALSE; + //log::ajouter(biostxt); + return 3; +} + +u32 delayLoop(armcpu_t * cpu) +{ + return cpu->R[0] * 4; +} + +//u32 oldmode[2]; + +u32 intrWaitARM(armcpu_t * cpu) +{ + u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; + u32 intr; + u32 intrFlag = 0; + + //execute = FALSE; + if(cpu->proc_ID) + { + intrFlagAdr = 0x380FFF8; + } else { + intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; + } + intr = MMU_readWord(cpu->proc_ID, intrFlagAdr); + intrFlag = cpu->R[1] & intr; + + if(intrFlag) + { + // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s) + // on efface son(les) occurence(s). + intr ^= intrFlag; + MMU_writeWord(cpu->proc_ID, intrFlagAdr, intr); + //cpu->switchMode(oldmode[cpu->proc_ID]); + return 1; + } + + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + cpu->waitIRQ = 1; + //oldmode[cpu->proc_ID] = cpu->switchMode(SVC); + + return 1; +} + +u32 waitVBlankARM(armcpu_t * cpu) +{ + u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; + u32 intr; + u32 intrFlag = 0; + + //execute = FALSE; + if(cpu->proc_ID) + { + intrFlagAdr = 0x380FFF8; + } else { + intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; + } + intr = MMU_readWord(cpu->proc_ID, intrFlagAdr); + intrFlag = 1 & intr; + + if(intrFlag) + { + // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s) + // on efface son(les) occurence(s). + intr ^= intrFlag; + MMU_writeWord(cpu->proc_ID, intrFlagAdr, intr); + //cpu->switchMode(oldmode[cpu->proc_ID]); + return 1; + } + + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + cpu->waitIRQ = 1; + //oldmode[cpu->proc_ID] = cpu->switchMode(SVC); + + return 1; +} + +u32 wait4IRQ(armcpu_t* cpu) +{ + //execute= FALSE; + if(cpu->wirq) + { + if(!cpu->waitIRQ) + { + cpu->waitIRQ = 0; + cpu->wirq = 0; + //cpu->switchMode(oldmode[cpu->proc_ID]); + return 1; + } + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + return 1; + } + cpu->waitIRQ = 1; + cpu->wirq = 1; + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + //oldmode[cpu->proc_ID] = cpu->switchMode(SVC); + return 1; +} + +u32 devide(armcpu_t* cpu) +{ + s32 num = (s32)cpu->R[0]; + s32 dnum = (s32)cpu->R[1]; + + if(dnum==0) return 0; + + cpu->R[0] = (u32)(num / dnum); + cpu->R[1] = (u32)(num % dnum); + cpu->R[3] = (u32) (((s32)cpu->R[0])<0 ? -cpu->R[0] : cpu->R[0]); + + return 6; +} + +u32 copy(armcpu_t* cpu) +{ + u32 src = cpu->R[0]; + u32 dst = cpu->R[1]; + u32 cnt = cpu->R[2]; + + switch(BIT26(cnt)) + { + case 0: + src &= 0xFFFFFFFE; + dst &= 0xFFFFFFFE; + switch(BIT24(cnt)) + { + case 0: + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_writeHWord(cpu->proc_ID, dst, MMU_readHWord(cpu->proc_ID, src)); + cnt--; + dst+=2; + src+=2; + } + break; + case 1: + { + u32 val = MMU_readHWord(cpu->proc_ID, src); + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_writeHWord(cpu->proc_ID, dst, val); + cnt--; + dst+=2; + } + } + break; + } + break; + case 1: + src &= 0xFFFFFFFC; + dst &= 0xFFFFFFFC; + switch(BIT24(cnt)) + { + case 0: + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_writeWord(cpu->proc_ID, dst, MMU_readWord(cpu->proc_ID, src)); + cnt--; + dst+=4; + src+=4; + } + break; + case 1: + { + u32 val = MMU_readWord(cpu->proc_ID, src); + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_writeWord(cpu->proc_ID, dst, val); + cnt--; + dst+=4; + } + } + break; + } + break; + } + return 1; +} + +u32 fastCopy(armcpu_t* cpu) +{ + u32 src = cpu->R[0] & 0xFFFFFFFC; + u32 dst = cpu->R[1] & 0xFFFFFFFC; + u32 cnt = cpu->R[2]; + + switch(BIT24(cnt)) + { + case 0: + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_writeWord(cpu->proc_ID, dst, MMU_readWord(cpu->proc_ID, src)); + cnt--; + dst+=4; + src+=4; + } + break; + case 1: + { + u32 val = MMU_readWord(cpu->proc_ID, src); + cnt &= 0x1FFFFF; + while(cnt) + { + MMU_writeWord(cpu->proc_ID, dst, val); + cnt--; + dst+=4; + } + } + break; + } + return 1; +} + +u32 LZ77UnCompVram(armcpu_t* cpu) +{ + int i1, i2; + u32 source = cpu->R[0]; + u32 dest = cpu->R[1]; + + u32 header = MMU_readWord(cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + int byteCount = 0; + int byteShift = 0; + u32 writeValue = 0; + + int len = header >> 8; + + while(len > 0) { + u8 d = MMU_readByte(cpu->proc_ID, source++); + + if(d) { + for(i1 = 0; i1 < 8; i1++) { + if(d & 0x80) { + u16 data = MMU_readByte(cpu->proc_ID, source++) << 8; + data |= MMU_readByte(cpu->proc_ID, source++); + int length = (data >> 12) + 3; + int offset = (data & 0x0FFF); + u32 windowOffset = dest + byteCount - offset - 1; + for(i2 = 0; i2 < length; i2++) { + writeValue |= (MMU_readByte(cpu->proc_ID, windowOffset++) << byteShift); + byteShift += 8; + byteCount++; + + if(byteCount == 2) { + MMU_writeHWord(cpu->proc_ID, dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + } else { + writeValue |= (MMU_readByte(cpu->proc_ID, source++) << byteShift); + byteShift += 8; + byteCount++; + if(byteCount == 2) { + MMU_writeHWord(cpu->proc_ID, dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + d <<= 1; + } + } else { + for(i1 = 0; i1 < 8; i1++) { + writeValue |= (MMU_readByte(cpu->proc_ID, source++) << byteShift); + byteShift += 8; + byteCount++; + if(byteCount == 2) { + MMU_writeHWord(cpu->proc_ID, dest, writeValue); + dest += 2; + byteShift = 0; + byteCount = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + } + } + return 1; +} + +u32 LZ77UnCompWram(armcpu_t* cpu) +{ + int i1, i2; + u32 source = cpu->R[0]; + u32 dest = cpu->R[1]; + + u32 header = MMU_readWord(cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + int len = header >> 8; + + while(len > 0) { + u8 d = MMU_readByte(cpu->proc_ID, source++); + + if(d) { + for(i1 = 0; i1 < 8; i1++) { + if(d & 0x80) { + u16 data = MMU_readByte(cpu->proc_ID, source++) << 8; + data |= MMU_readByte(cpu->proc_ID, source++); + int length = (data >> 12) + 3; + int offset = (data & 0x0FFF); + u32 windowOffset = dest - offset - 1; + for(i2 = 0; i2 < length; i2++) { + MMU_writeByte(cpu->proc_ID, dest++, MMU_readByte(cpu->proc_ID, windowOffset++)); + len--; + if(len == 0) + return 0; + } + } else { + MMU_writeByte(cpu->proc_ID, dest++, MMU_readByte(cpu->proc_ID, source++)); + len--; + if(len == 0) + return 0; + } + d <<= 1; + } + } else { + for(i1 = 0; i1 < 8; i1++) { + MMU_writeByte(cpu->proc_ID, dest++, MMU_readByte(cpu->proc_ID, source++)); + len--; + if(len == 0) + return 0; + } + } + } + return 1; +} + +u32 RLUnCompVram(armcpu_t* cpu) +{ + int i; + u32 source = cpu->R[0]; + u32 dest = cpu->R[1]; + + u32 header = MMU_readWord(cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + int len = header >> 8; + int byteCount = 0; + int byteShift = 0; + u32 writeValue = 0; + + while(len > 0) { + u8 d = MMU_readByte(cpu->proc_ID, source++); + int l = d & 0x7F; + if(d & 0x80) { + u8 data = MMU_readByte(cpu->proc_ID, source++); + l += 3; + for(i = 0;i < l; i++) { + writeValue |= (data << byteShift); + byteShift += 8; + byteCount++; + + if(byteCount == 2) { + MMU_writeHWord(cpu->proc_ID, dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + } else { + l++; + for(i = 0; i < l; i++) { + writeValue |= (MMU_readByte(cpu->proc_ID, source++) << byteShift); + byteShift += 8; + byteCount++; + if(byteCount == 2) { + MMU_writeHWord(cpu->proc_ID, dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if(len == 0) + return 0; + } + } + } + return 1; +} + +u32 RLUnCompWram(armcpu_t* cpu) +{ + int i; + u32 source = cpu->R[0]; + u32 dest = cpu->R[1]; + + u32 header = MMU_readWord(cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + int len = header >> 8; + + while(len > 0) { + u8 d = MMU_readByte(cpu->proc_ID, source++); + int l = d & 0x7F; + if(d & 0x80) { + u8 data = MMU_readByte(cpu->proc_ID, source++); + l += 3; + for(i = 0;i < l; i++) { + MMU_writeByte(cpu->proc_ID, dest++, data); + len--; + if(len == 0) + return 0; + } + } else { + l++; + for(i = 0; i < l; i++) { + MMU_writeByte(cpu->proc_ID, dest++, MMU_readByte(cpu->proc_ID, source++)); + len--; + if(len == 0) + return 0; + } + } + } + return 1; +} + +u32 UnCompHuffman(armcpu_t* cpu) +{ + u32 source, dest, writeValue, header, treeStart, mask; + u32 data; + u8 treeSize, currentNode, rootNode; + int byteCount, byteShift, len, pos; + int writeData; + + source = cpu->R[0]; + dest = cpu->R[1]; + + header = MMU_readByte(cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + treeSize = MMU_readByte(cpu->proc_ID, source++); + + treeStart = source; + + source += ((treeSize+1)<<1)-1; // minus because we already skipped one byte + + len = header >> 8; + + mask = 0x80000000; + data = MMU_readByte(cpu->proc_ID, source); + source += 4; + + pos = 0; + rootNode = MMU_readByte(cpu->proc_ID, treeStart); + currentNode = rootNode; + writeData = 0; + byteShift = 0; + byteCount = 0; + writeValue = 0; + + if((header & 0x0F) == 8) { + while(len > 0) { + // take left + if(pos == 0) + pos++; + else + pos += (((currentNode & 0x3F)+1)<<1); + + if(data & mask) { + // right + if(currentNode & 0x40) + writeData = 1; + currentNode = MMU_readByte(cpu->proc_ID, treeStart+pos+1); + } else { + // left + if(currentNode & 0x80) + writeData = 1; + currentNode = MMU_readByte(cpu->proc_ID, treeStart+pos); + } + + if(writeData) { + writeValue |= (currentNode << byteShift); + byteCount++; + byteShift += 8; + + pos = 0; + currentNode = rootNode; + writeData = 0; + + if(byteCount == 4) { + byteCount = 0; + byteShift = 0; + MMU_writeByte(cpu->proc_ID, dest, writeValue); + writeValue = 0; + dest += 4; + len -= 4; + } + } + mask >>= 1; + if(mask == 0) { + mask = 0x80000000; + data = MMU_readByte(cpu->proc_ID, source); + source += 4; + } + } + } else { + int halfLen = 0; + int value = 0; + while(len > 0) { + // take left + if(pos == 0) + pos++; + else + pos += (((currentNode & 0x3F)+1)<<1); + + if((data & mask)) { + // right + if(currentNode & 0x40) + writeData = 1; + currentNode = MMU_readByte(cpu->proc_ID, treeStart+pos+1); + } else { + // left + if(currentNode & 0x80) + writeData = 1; + currentNode = MMU_readByte(cpu->proc_ID, treeStart+pos); + } + + if(writeData) { + if(halfLen == 0) + value |= currentNode; + else + value |= (currentNode<<4); + + halfLen += 4; + if(halfLen == 8) { + writeValue |= (value << byteShift); + byteCount++; + byteShift += 8; + + halfLen = 0; + value = 0; + + if(byteCount == 4) { + byteCount = 0; + byteShift = 0; + MMU_writeByte(cpu->proc_ID, dest, writeValue); + dest += 4; + writeValue = 0; + len -= 4; + } + } + pos = 0; + currentNode = rootNode; + writeData = 0; + } + mask >>= 1; + if(mask == 0) { + mask = 0x80000000; + data = MMU_readByte(cpu->proc_ID, source); + source += 4; + } + } + } + return 1; +} + +u32 BitUnPack(armcpu_t* cpu) +{ + u32 source,dest,header,base,d,temp; + int len,bits,revbits,dataSize,data,bitwritecount,mask,bitcount,addBase; + u8 b; + + source = cpu->R[0]; + dest = cpu->R[1]; + header = cpu->R[2]; + + len = MMU_readHWord(cpu->proc_ID, header); + // check address + bits = MMU_readByte(cpu->proc_ID, header+2); + revbits = 8 - bits; + // u32 value = 0; + base = MMU_readByte(cpu->proc_ID, header+4); + addBase = (base & 0x80000000) ? 1 : 0; + base &= 0x7fffffff; + dataSize = MMU_readByte(cpu->proc_ID, header+3); + + data = 0; + bitwritecount = 0; + while(1) { + len -= 1; + if(len < 0) + break; + mask = 0xff >> revbits; + b = MMU_readByte(cpu->proc_ID, source); + source++; + bitcount = 0; + while(1) { + if(bitcount >= 8) + break; + d = b & mask; + temp = d >> bitcount; + if(!temp && addBase) { + temp += base; + } + data |= temp << bitwritecount; + bitwritecount += dataSize; + if(bitwritecount >= 32) { + MMU_writeByte(cpu->proc_ID, dest, data); + dest += 4; + data = 0; + bitwritecount = 0; + } + mask <<= bits; + bitcount += bits; + } + } + return 1; +} + +u32 Diff8bitUnFilterWram(armcpu_t* cpu) +{ + u32 source,dest,header; + u8 data,diff; + int len; + + source = cpu->R[0]; + dest = cpu->R[1]; + + header = MMU_readByte(cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff) & 0xe000000) == 0)) + return 0; + + len = header >> 8; + + data = MMU_readByte(cpu->proc_ID, source++); + MMU_writeByte(cpu->proc_ID, dest++, data); + len--; + + while(len > 0) { + diff = MMU_readByte(cpu->proc_ID, source++); + data += diff; + MMU_writeByte(cpu->proc_ID, dest++, data); + len--; + } + return 1; +} + +u32 Diff16bitUnFilter(armcpu_t* cpu) +{ + u32 source,dest,header; + u16 data; + int len; + + source = cpu->R[0]; + dest = cpu->R[1]; + + header = MMU_readByte(cpu->proc_ID, source); + source += 4; + + if(((source & 0xe000000) == 0) || + ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return 0; + + len = header >> 8; + + data = MMU_readHWord(cpu->proc_ID, source); + source += 2; + MMU_writeHWord(cpu->proc_ID, dest, data); + dest += 2; + len -= 2; + + while(len >= 2) { + u16 diff = MMU_readHWord(cpu->proc_ID, source); + source += 2; + data += diff; + MMU_writeHWord(cpu->proc_ID, dest, data); + dest += 2; + len -= 2; + } + return 1; +} + +u32 bios_sqrt(armcpu_t* cpu) +{ + cpu->R[0] = (u32)sqrt((double)(cpu->R[0])); + return 1; +} + +u32 setHaltCR(armcpu_t* cpu) +{ + MMU_writeByte(cpu->proc_ID, 0x4000300+cpu->proc_ID, cpu->R[0]); + return 1; +} + +u32 getPitchTab(armcpu_t* cpu) +{ + return 1; +} + +u32 getVolumeTab(armcpu_t* cpu) +{ + return 1; +} + +u32 (* ARM9_swi_tab[32])(armcpu_t* cpu)={ + bios_nop, + bios_nop, + bios_nop, + delayLoop, + intrWaitARM, + waitVBlankARM, + wait4IRQ, + bios_nop, + bios_nop, + devide, + bios_nop, + copy, + fastCopy, + bios_sqrt, + bios_nop, + bios_nop, + BitUnPack, + LZ77UnCompWram, + LZ77UnCompVram, + UnCompHuffman, + RLUnCompWram, + RLUnCompVram, + Diff8bitUnFilterWram, + bios_nop, + Diff16bitUnFilter, + bios_nop, + bios_nop, + bios_nop, + bios_nop, + bios_nop, + bios_nop, + setHaltCR, +}; + +u32 (* ARM7_swi_tab[32])(armcpu_t* cpu)={ + bios_nop, + bios_nop, + bios_nop, + delayLoop, + intrWaitARM, + waitVBlankARM, + wait4IRQ, + wait4IRQ, + bios_nop, + devide, + bios_nop, + copy, + fastCopy, + bios_sqrt, + bios_nop, + bios_nop, + BitUnPack, + LZ77UnCompWram, + LZ77UnCompVram, + UnCompHuffman, + RLUnCompWram, + RLUnCompVram, + Diff8bitUnFilterWram, + bios_nop, + bios_nop, + bios_nop, + bios_nop, + getPitchTab, + getVolumeTab, + bios_nop, + bios_nop, + setHaltCR, +}; diff --git a/desmume/src/bios.h b/desmume/src/bios.h new file mode 100644 index 000000000..7f717cb8c --- /dev/null +++ b/desmume/src/bios.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef BIOS_H +#define BIOS_H + +#include "armcpu.h" + +extern u32 (* ARM9_swi_tab[32])(armcpu_t * cpu); +extern u32 (* ARM7_swi_tab[32])(armcpu_t * cpu); +extern u32 wait4IRQ(armcpu_t * cpu); + +#endif + diff --git a/desmume/src/cp15.c b/desmume/src/cp15.c new file mode 100644 index 000000000..75dbe8dfe --- /dev/null +++ b/desmume/src/cp15.c @@ -0,0 +1,388 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include "cp15.h" +#include "debug.h" +#include "MMU.h" + +armcp15_t *armcp15_new(armcpu_t * c) +{ + armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t)); + if(!armcp15) return NULL; + + armcp15->cpu = c; + armcp15->IDCode = 0x41049460; + armcp15->cacheType = 0x0F0D2112; + armcp15->TCMSize = 0x00140140; + armcp15->ctrl = 0x00000000; + armcp15->DCConfig = 0x0; + armcp15->ICConfig = 0x0; + armcp15->writeBuffCtrl = 0x0; + armcp15->und = 0x0; + armcp15->DaccessPerm = 0x22222222; + armcp15->IaccessPerm = 0x22222222; + armcp15->protectBaseSize0 = 0x0; + armcp15->protectBaseSize1 = 0x0; + armcp15->protectBaseSize2 = 0x0; + armcp15->protectBaseSize3 = 0x0; + armcp15->protectBaseSize4 = 0x0; + armcp15->protectBaseSize5 = 0x0; + armcp15->protectBaseSize6 = 0x0; + armcp15->protectBaseSize7 = 0x0; + armcp15->cacheOp = 0x0; + armcp15->DcacheLock = 0x0; + armcp15->IcacheLock = 0x0; + armcp15->ITCMRegion = 0x0C; + armcp15->DTCMRegion = 0x0080000A; + armcp15->processID = 0; + + return armcp15; +} + + +BOOL armcp15_dataProcess(armcp15_t *armcp15, u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) +{ + return FALSE; +} + +BOOL armcp15_load(armcp15_t *armcp15, u8 CRd, u8 adr) +{ + return FALSE; +} + +BOOL armcp15_store(armcp15_t *armcp15, u8 CRd, u8 adr) +{ + return FALSE; +} + +BOOL armcp15_moveCP2ARM(armcp15_t *armcp15, u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) +{ + if(armcp15->cpu->CPSR.bits.mode == USR) return FALSE; + + switch(CRn) + { + case 0 : + if((opcode1 == 0)&&(CRm==0)) + { + switch(opcode2) + { + case 1 : + *R = armcp15->cacheType; + return TRUE; + case 2 : + *R = armcp15->TCMSize; + return TRUE; + default : + *R = armcp15->IDCode; + return TRUE; + } + } + return FALSE; + case 1 : + if((opcode1==0) && (opcode2==0) && (CRm==0)) + { + *R = armcp15->ctrl; + return TRUE; + } + return FALSE; + + case 2 : + if((opcode1==0) && (CRm==0)) + { + switch(opcode2) + { + case 0 : + *R = armcp15->DCConfig; + return TRUE; + case 1 : + *R = armcp15->ICConfig; + return TRUE; + default : + return FALSE; + } + } + return FALSE; + case 3 : + if((opcode1==0) && (opcode2==0) && (CRm==0)) + { + *R = armcp15->writeBuffCtrl; + return TRUE; + } + return FALSE; + case 5 : + if((opcode1==0) && (CRm==0)) + { + switch(opcode2) + { + case 2 : + *R = armcp15->DaccessPerm; + return TRUE; + case 3 : + *R = armcp15->IaccessPerm; + return TRUE; + default : + return FALSE; + } + } + return FALSE; + case 6 : + if((opcode1==0) && (opcode2==0)) + { + switch(CRm) + { + case 0 : + *R = armcp15->protectBaseSize0; + return TRUE; + case 1 : + *R = armcp15->protectBaseSize1; + return TRUE; + case 2 : + *R = armcp15->protectBaseSize2; + return TRUE; + case 3 : + *R = armcp15->protectBaseSize3; + return TRUE; + case 4 : + *R = armcp15->protectBaseSize4; + return TRUE; + case 5 : + *R = armcp15->protectBaseSize5; + return TRUE; + case 6 : + *R = armcp15->protectBaseSize6; + return TRUE; + case 7 : + *R = armcp15->protectBaseSize7; + return TRUE; + default : + return FALSE; + } + } + return FALSE; + case 9 : + if((opcode1==0)) + { + switch(CRm) + { + case 0 : + switch(opcode2) + { + case 0 : + *R = armcp15->DcacheLock; + return TRUE; + case 1 : + *R = armcp15->IcacheLock; + return TRUE; + default : + return FALSE; + } + case 1 : + switch(opcode2) + { + case 0 : + *R = armcp15->DTCMRegion; + return TRUE; + case 1 : + *R = armcp15->ITCMRegion; + return TRUE; + default : + return FALSE; + } + } + } + return FALSE; + default : + return FALSE; + } +} + + +u32 CP15wait4IRQ(armcpu_t *cpu) +{ + if(cpu->wirq) + { + if(!cpu->waitIRQ) + { + cpu->waitIRQ = 0; + cpu->wirq = 0; + //cpu->switchMode(oldmode[cpu->proc_ID]); + return 1; + } + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + return 1; + } + cpu->waitIRQ = 1; + cpu->wirq = 1; + cpu->R[15] = cpu->instruct_adr; + cpu->next_instruction = cpu->R[15]; + MMU.reg_IME[0] = 1; + return 1; +} + +BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) +{ + if(armcp15->cpu->CPSR.bits.mode == USR) return FALSE; + + switch(CRn) + { + case 1 : + if((opcode1==0) && (opcode2==0) && (CRm==0)) + { + armcp15->ctrl = val; + MMU.ARM9_RW_MODE = BIT7(val); + armcp15->cpu->intVector = 0x0FFF0000 * (BIT13(val)); + armcp15->cpu->LDTBit = !BIT15(val); //TBit + /*if(BIT17(val)) + { + log::ajouter("outch !!!!!!!"); + } + if(BIT19(val)) + { + log::ajouter("outch !!!!!!!"); + }*/ + return TRUE; + } + return FALSE; + case 2 : + if((opcode1==0) && (CRm==0)) + { + switch(opcode2) + { + case 0 : + armcp15->DCConfig = val; + return TRUE; + case 1 : + armcp15->ICConfig = val; + return TRUE; + default : + return FALSE; + } + } + return FALSE; + case 3 : + if((opcode1==0) && (opcode2==0) && (CRm==0)) + { + armcp15->writeBuffCtrl = val; + return TRUE; + } + return FALSE; + if((opcode1==0) && (CRm==0)) + { + switch(opcode2) + { + case 2 : + armcp15->DaccessPerm = val; + return TRUE; + case 3 : + armcp15->IaccessPerm = val; + return TRUE; + default : + return FALSE; + } + } + return FALSE; + case 6 : + if((opcode1==0) && (opcode2==0)) + { + switch(CRm) + { + case 0 : + armcp15->protectBaseSize0 = val; + return TRUE; + case 1 : + armcp15->protectBaseSize1 = val; + return TRUE; + case 2 : + armcp15->protectBaseSize2 = val; + return TRUE; + case 3 : + armcp15->protectBaseSize3 = val; + return TRUE; + case 4 : + armcp15->protectBaseSize4 = val; + return TRUE; + case 5 : + armcp15->protectBaseSize5 = val; + return TRUE; + case 6 : + armcp15->protectBaseSize6 = val; + return TRUE; + case 7 : + armcp15->protectBaseSize7 = val; + return TRUE; + default : + return FALSE; + } + } + return FALSE; + case 7 : + if((CRm==0)&&(opcode1==0)&&((opcode2==4))) + { + CP15wait4IRQ(armcp15->cpu); + return TRUE; + } + return FALSE; + case 9 : + if((opcode1==0)) + { + switch(CRm) + { + case 0 : + switch(opcode2) + { + case 0 : + armcp15->DcacheLock = val; + return TRUE; + case 1 : + armcp15->IcacheLock = val; + return TRUE; + default : + return FALSE; + } + case 1 : + switch(opcode2) + { + case 0 : + armcp15->DTCMRegion = val; + MMU.DTCMRegion = val & 0x0FFFFFFC0; + /*sprintf(logbuf, "%08X", val); + log::ajouter(logbuf);*/ + return TRUE; + case 1 : + armcp15->ITCMRegion = val; + MMU.ITCMRegion = val & 0x0FFFFFFC0; + return TRUE; + default : + return FALSE; + } + } + } + return FALSE; + default : + return FALSE; + } +} + + + diff --git a/desmume/src/saves.c b/desmume/src/saves.c index fb49f3558..0da865349 100644 --- a/desmume/src/saves.c +++ b/desmume/src/saves.c @@ -3,7 +3,7 @@ #endif #include #include "saves.h" -#include "MMU.hpp" +#include "MMU.h" u8 sram_read (u32 address) { address = address - SRAM_ADDRESS; diff --git a/desmume/src/thumb_instructions.c b/desmume/src/thumb_instructions.c new file mode 100644 index 000000000..728560570 --- /dev/null +++ b/desmume/src/thumb_instructions.c @@ -0,0 +1,903 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "bios.h" +#include "debug.h" +#include "MMU.h" + +#define REG_NUM(i, n) (((i)>>n)&0x7) + +extern BOOL execute; + +u32 FASTCALL OP_UND_THUMB(armcpu_t *cpu) +{ + execute = FALSE; + return 1; +} + +u32 FASTCALL OP_LSL_0(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +u32 FASTCALL OP_LSL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = (i>>6) & 0x1F; + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v); + cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +u32 FASTCALL OP_LSR_0(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + // cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); + cpu->R[REG_NUM(i, 0)] = 0; + cpu->CPSR.bits.N = 0; + cpu->CPSR.bits.Z = 1; + + return 2; +} + +u32 FASTCALL OP_LSR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = (i>>6) & 0x1F; + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); + cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +u32 FASTCALL OP_ASR_0(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); + cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +u32 FASTCALL OP_ASR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = (i>>6) & 0x1F; + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1); + cpu->R[REG_NUM(i, 0)] = (((s32)cpu->R[REG_NUM(i, 3)]) >> v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +u32 FASTCALL OP_ADD_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + u32 b = cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = a + b; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); + + return 3; +} + +u32 FASTCALL OP_SUB_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + u32 b = cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = a - b; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); + + return 3; +} + +u32 FASTCALL OP_ADD_IMM3(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + cpu->R[REG_NUM(i, 0)] = a + REG_NUM(i, 6); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); + + return 2; +} + +u32 FASTCALL OP_SUB_IMM3(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + cpu->R[REG_NUM(i, 0)] = a - REG_NUM(i, 6); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); + + return 2; +} + +u32 FASTCALL OP_MOV_IMM8(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 8)] = i & 0xFF; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0; + + return 2; +} + +u32 FASTCALL OP_CMP_IMM8(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF); + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + + return 2; +} + +u32 FASTCALL OP_ADD_IMM8(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 8)] + (i & 0xFF); + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->R[REG_NUM(i, 8)] = tmp; + + return 2; +} + +u32 FASTCALL OP_SUB_IMM8(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF); + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->R[REG_NUM(i, 8)] = tmp; + + return 2; +} + +u32 FASTCALL OP_AND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +u32 FASTCALL OP_EOR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +u32 FASTCALL OP_LSL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; + + if(!v) + { + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v<32) + { + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v); + cpu->R[REG_NUM(i, 0)] <<= v; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v==32) + cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]); + else + cpu->CPSR.bits.C = 0; + cpu->R[REG_NUM(i, 0)] = 0; + cpu->CPSR.bits.N = 0; + cpu->CPSR.bits.Z = 1; + + return 3; +} + +u32 FASTCALL OP_LSR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; + + if(!v) + { + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v<32) + { + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); + cpu->R[REG_NUM(i, 0)] >>= v; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v==32) + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); + else + cpu->CPSR.bits.C = 0; + cpu->R[REG_NUM(i, 0)] = 0; + cpu->CPSR.bits.N = 0; + cpu->CPSR.bits.Z = 1; + + return 3; +} + +u32 FASTCALL OP_ASR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; + + if(!v) + { + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v<32) + { + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); + cpu->R[REG_NUM(i, 0)] = (u32)(((s32)cpu->R[REG_NUM(i, 0)]) >> v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +u32 FASTCALL OP_ADC_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 0)]; + u32 b = cpu->R[REG_NUM(i, 3)]; + u32 tmp = b + cpu->CPSR.bits.C; + u32 res = a + tmp; + + cpu->R[REG_NUM(i, 0)] = res; + + cpu->CPSR.bits.N = BIT31(res); + cpu->CPSR.bits.Z = res == 0; + + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(tmp, a, res); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, a, res); + + return 3; +} + +u32 FASTCALL OP_SBC_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 0)]; + u32 b = cpu->R[REG_NUM(i, 3)]; + u32 tmp = a - (!cpu->CPSR.bits.C); + u32 res = tmp - b; + cpu->R[REG_NUM(i, 0)] = res; + + cpu->CPSR.bits.N = BIT31(res); + cpu->CPSR.bits.Z = res == 0; + + cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp)) & (!UNSIGNED_OVERFLOW(tmp, b, res)); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, b, res); + + return 3; +} + +u32 FASTCALL OP_ROR_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; + + if(v == 0) + { + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + v &= 0xF; + if(v == 0) + { + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); + cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +u32 FASTCALL OP_TST(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + + return 3; +} + +u32 FASTCALL OP_NEG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + cpu->R[REG_NUM(i, 0)] = -a; + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]); + + return 3; +} + +u32 FASTCALL OP_CMP(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 0)] -cpu->R[REG_NUM(i, 3)]; + + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); + + return 3; +} + +u32 FASTCALL OP_CMN(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)]; + + //execute = FALSE; + //log::ajouter("OP_CMN THUMB"); + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); + + return 3; +} + +u32 FASTCALL OP_ORR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +u32 FASTCALL OP_MUL_REG(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] *= cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +u32 FASTCALL OP_BIC(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +u32 FASTCALL OP_MVN(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +u32 FASTCALL OP_ADD_SPE(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u8 Rd = (i&7) | ((i>>4)&8); + cpu->R[Rd] += cpu->R[REG_POS(i, 3)]; + + if(Rd==15) + cpu->next_instruction = cpu->R[15]; + + return 2; +} + +u32 FASTCALL OP_CMP_SPE(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u8 Rn = (i&7) | ((i>>4)&8); + u32 tmp = cpu->R[Rn] -cpu->R[REG_POS(i, 3)]; + + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp); + + return 3; +} + +u32 FASTCALL OP_MOV_SPE(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u8 Rd = (i&7) | ((i>>4)&8); + cpu->R[Rd] = cpu->R[REG_POS(i, 3)]; + + if(Rd==15) + cpu->next_instruction = cpu->R[15]; + + return 2; +} + +u32 FASTCALL OP_BX_THUMB(armcpu_t *cpu) +{ + u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)]; + + cpu->CPSR.bits.T = BIT0(Rm); + cpu->R[15] = (Rm & 0xFFFFFFFE); + cpu->next_instruction = cpu->R[15]; + + return 3; +} + +u32 FASTCALL OP_BLX_THUMB(armcpu_t *cpu) +{ + u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)]; + + cpu->CPSR.bits.T = BIT0(Rm); + cpu->R[14] = cpu->next_instruction | 1; + cpu->R[15] = (Rm & 0xFFFFFFFE); + cpu->next_instruction = cpu->R[15]; + + return 3; +} + +u32 FASTCALL OP_LDR_PCREL(armcpu_t *cpu) +{ + u32 adr = (cpu->R[15]&0xFFFFFFFC) + ((cpu->instruction&0xFF)<<2); + + cpu->R[REG_NUM(cpu->instruction, 8)] = MMU_readWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)]; + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_NUM(i, 0)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + MMU_writeHWord(cpu->proc_ID, adr, ((u16)cpu->R[REG_NUM(i, 0)])); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + MMU_writeByte(cpu->proc_ID, adr, ((u8)cpu->R[REG_NUM(i, 0)])); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSB_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = MMU_readWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = (u32)MMU_readHWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = (u32)MMU_readByte(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRSH_REG_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr)); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_NUM(i, 0)]); + + return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); + cpu->R[REG_NUM(i, 0)] = MMU_readWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRB_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); + MMU_writeByte(cpu->proc_ID, adr, cpu->R[REG_NUM(i, 0)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRB_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); + cpu->R[REG_NUM(i, 0)] = MMU_readByte(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STRH_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); + MMU_writeHWord(cpu->proc_ID, adr, cpu->R[REG_NUM(i, 0)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDRH_IMM_OFF(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); + cpu->R[REG_NUM(i, 0)] = MMU_readHWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_STR_SPREL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[13] + ((i&0xFF)<<2); + MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_NUM(i, 8)]); + + return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_LDR_SPREL(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[13] + ((i&0xFF)<<2); + cpu->R[REG_NUM(i, 8)] = MMU_readWord(cpu->proc_ID, adr); + + return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; +} + +u32 FASTCALL OP_ADD_2PC(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2); + + return 5; +} + +u32 FASTCALL OP_ADD_2SP(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2); + + return 2; +} + +u32 FASTCALL OP_ADJUST_P_SP(armcpu_t *cpu) +{ + cpu->R[13] += ((cpu->instruction&0x7F)<<2); + + return 1; +} + +u32 FASTCALL OP_ADJUST_M_SP(armcpu_t *cpu) +{ + cpu->R[13] -= ((cpu->instruction&0x7F)<<2); + + return 1; +} + +u32 FASTCALL OP_PUSH(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[13] - 4; + u32 c = 0; + u32 j; + + for(j = 0; j<8; ++j) + if(BIT_N(i, 7-j)) + { + MMU_writeWord(cpu->proc_ID, adr, cpu->R[7-j]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + adr -= 4; + } + cpu->R[13] = adr + 4; + + return c + 3; +} + +u32 FASTCALL OP_PUSH_LR(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[13] - 4; + u32 c = 0; + u32 j; + + MMU_writeWord(cpu->proc_ID, adr, cpu->R[14]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + adr -= 4; + + for(j = 0; j<8; ++j) + if(BIT_N(i, 7-j)) + { + MMU_writeWord(cpu->proc_ID, adr, cpu->R[7-j]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + adr -= 4; + } + cpu->R[13] = adr + 4; + + return c + 4; +} + +u32 FASTCALL OP_POP(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[13]; + u32 c = 0; + u32 j; + + for(j = 0; j<8; ++j) + if(BIT_N(i, j)) + { + cpu->R[j] = MMU_readWord(cpu->proc_ID, adr); + c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + adr += 4; + } + cpu->R[13] = adr; + + return c + 2; +} + +u32 FASTCALL OP_POP_PC(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[13]; + u32 c = 0; + u32 j; + + for(j = 0; j<8; ++j) + if(BIT_N(i, j)) + { + cpu->R[j] = MMU_readWord(cpu->proc_ID, adr); + c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + adr += 4; + } + + u32 v = MMU_readWord(cpu->proc_ID, adr); + c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + cpu->R[15] = v & 0xFFFFFFFE; + cpu->next_instruction = v & 0xFFFFFFFE; + if(cpu->proc_ID==0) + cpu->CPSR.bits.T = BIT0(v); + adr += 4; + + cpu->R[13] = adr; + return c + 5; +} + +u32 FASTCALL OP_BKPT_THUMB(armcpu_t *cpu) +{ + return 1; +} + +u32 FASTCALL OP_STMIA_THUMB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 8)]; + u32 c = 0; + u32 j; + + for(j = 0; j<8; ++j) + if(BIT_N(i, j)) + { + MMU_writeWord(cpu->proc_ID, adr, cpu->R[j]); + c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + adr += 4; + } + cpu->R[REG_NUM(i, 8)] = adr; + return c + 2; +} + +u32 FASTCALL OP_LDMIA_THUMB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 8)]; + u32 c = 0; + u32 j; + + for(j = 0; j<8; ++j) + if(BIT_N(i, j)) + { + cpu->R[j] = MMU_readWord(cpu->proc_ID, adr); + c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF]; + adr += 4; + } + cpu->R[REG_NUM(i, 8)] = adr; + return c + 3; +} + +u32 FASTCALL OP_B_COND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + if(!TEST_COND((i>>8)&0xF, cpu->CPSR)) + return 1; + + cpu->R[15] += ((s32)((s8)(i&0xFF)))<<1; + cpu->next_instruction = cpu->R[15]; + return 3; +} + +u32 FASTCALL OP_SWI_THUMB(armcpu_t *cpu) +{ + u32 swinum = cpu->instruction & 0xFF; + return cpu->swi_tab[swinum](cpu) + 3; + //return 3; +} + +#define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800)) + +u32 FASTCALL OP_B_UNCOND(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[15] += (SIGNEEXT_IMM11(i)<<1); + cpu->next_instruction = cpu->R[15]; + return 3; +} + +u32 FASTCALL OP_BLX(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC; + cpu->R[14] = cpu->next_instruction | 1; + cpu->next_instruction = cpu->R[15]; + cpu->CPSR.bits.T = 0; + return 3; +} + +u32 FASTCALL OP_BL_10(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12); + return 1; +} + +u32 FASTCALL OP_BL_THUMB(armcpu_t *cpu) +{ + u32 i = cpu->instruction; + cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1)); + cpu->R[14] = cpu->next_instruction | 1; + cpu->next_instruction = cpu->R[15]; + return 3; +} + +#define TYPE_RETOUR u32 +#define CALLTYPE FASTCALL +#define PARAMETRES armcpu_t *cpu +#define NOM_THUMB_TAB thumb_instructions_set + +#include "thumb_tabdef.inc" diff --git a/desmume/src/windows/CWindow.c b/desmume/src/windows/CWindow.c new file mode 100644 index 000000000..cae1bffe8 --- /dev/null +++ b/desmume/src/windows/CWindow.c @@ -0,0 +1,173 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "CWindow.h" +#include "resource.h" + +CRITICAL_SECTION section; +cwindow_struct *updatewindowlist = NULL; + +////////////////////////////////////////////////////////////////////////////// + +int CWindow_Init(void *win, HINSTANCE hInst, const char * cname, const char * title, int style, int sx, int sy, LRESULT CALLBACK (* wP) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)) +{ + static BOOL first = FALSE; + RECT clientaera; + cwindow_struct *win2=(cwindow_struct *)win; + + win2->autoup = FALSE; + + if(!first) + { + WNDCLASSEX wincl; // Data structure for the windowclass + + // The Window structure + wincl.hInstance = hInst; + wincl.lpszClassName = cname; + wincl.lpfnWndProc = wP; // This function is called by windows + wincl.style = CS_DBLCLKS; // Catch double-clicks + wincl.cbSize = sizeof (WNDCLASSEX); + + // Use default icon and mouse-pointer + wincl.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IconDeSmuME));//IDI_APPLICATION); + wincl.hIconSm = LoadIcon (hInst, MAKEINTRESOURCE(IconDeSmuME));//IDI_APPLICATION); + wincl.hCursor = LoadCursor (NULL, IDC_ARROW); + wincl.lpszMenuName = NULL; // No menu + wincl.cbClsExtra = 0; // No extra bytes after the window class + wincl.cbWndExtra = 0; // structure or the window instance + // Use Windows's default color as the background of the window + wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; + + // Register the window class, and if it fails quit the program + if (!RegisterClassEx (&wincl)) + return -1; + win2->first=NULL; + first = TRUE; + } + + clientaera.left = 0; + clientaera.top = 0; + clientaera.right = sx; + clientaera.bottom = sy; + + AdjustWindowRectEx(&clientaera, style, TRUE, 0); + + // The class is registered, let's create the program + win2->hwnd = CreateWindowEx ( + 0, // Extended possibilites for variation + cname, // Classname + title, // Title Text + style, // default window + CW_USEDEFAULT, // Windows decides the position + CW_USEDEFAULT, // where the window ends up on the screen + clientaera.right - clientaera.left, // The programs width + clientaera.bottom - clientaera.top, // and height in pixels + HWND_DESKTOP, // The window is a child-window to desktop + NULL, // No menu + hInst, // Program Instance handler + NULL // No Window Creation data + ); + + win2->prev = NULL; + win2->next = NULL; + win2->Refresh = &CWindow_Refresh; + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +int CWindow_Init2(void *win, HINSTANCE hInst, HWND parent, char * title, int ID, BOOL CALLBACK (*wP) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)) +{ + cwindow_struct *win2=(cwindow_struct *)win; + + win2->autoup = FALSE; + win2->hwnd = CreateDialog(hInst, MAKEINTRESOURCE(ID), parent, wP); + SetWindowLong(win2->hwnd, DWL_USER, (LONG)win2); + SetWindowText(win2->hwnd, title); + win2->prev = NULL; + win2->next = NULL; + win2->Refresh = &CWindow_Refresh; + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +void CWindow_Show(void *win) +{ + ShowWindow (((cwindow_struct *)win)->hwnd, SW_SHOW); +} + +////////////////////////////////////////////////////////////////////////////// + +void CWindow_Hide(void *win) +{ + ShowWindow (((cwindow_struct *)win)->hwnd, SW_HIDE); +} + +////////////////////////////////////////////////////////////////////////////// + +void CWindow_Refresh(void *win) +{ + InvalidateRect(((cwindow_struct *)win)->hwnd, NULL, FALSE); +} + +////////////////////////////////////////////////////////////////////////////// + +void CWindow_AddToRefreshList(void *win) +{ + cwindow_struct *win2=(cwindow_struct *)win; + + EnterCriticalSection(§ion); + win2->prev = NULL; + win2->next = updatewindowlist; + if(updatewindowlist) + updatewindowlist->prev = win; + updatewindowlist = (cwindow_struct *)win; + LeaveCriticalSection(§ion); +} + +////////////////////////////////////////////////////////////////////////////// + +void CWindow_RemoveFromRefreshList(void *win) +{ + cwindow_struct *win2=(cwindow_struct *)win; + + EnterCriticalSection(§ion); + if(updatewindowlist == win) + { + updatewindowlist = (cwindow_struct *)win2->next; + if(updatewindowlist) updatewindowlist->prev = NULL; + } + else + if(win2->prev) + { + ((cwindow_struct *)win2->prev)->next = win2->next; + if(win2->next) ((cwindow_struct *)win2->next)->prev = win2->prev; + } + win2->next = NULL; + win2->prev = NULL; + LeaveCriticalSection(§ion); +} + +////////////////////////////////////////////////////////////////////////////// + diff --git a/desmume/src/windows/CWindow.h b/desmume/src/windows/CWindow.h new file mode 100644 index 000000000..cb078e8f3 --- /dev/null +++ b/desmume/src/windows/CWindow.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef CWINDOW_H +#define CWINDOW_H + +#include +#include "../types.h" + +extern CRITICAL_SECTION section; + +typedef struct +{ + HWND hwnd; + BOOL autoup; + void *prev; + void *next; + void *first; + void (*Refresh)(void *win); +} cwindow_struct; + +int CWindow_Init(void *win, HINSTANCE hInst, const char * cname, const char * title, int style, int sx, int sy, LRESULT CALLBACK (* wP) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)); +int CWindow_Init2(void *win, HINSTANCE hInst, HWND parent, char * title, int ID, BOOL CALLBACK (*wP) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)); +void CWindow_Show(void *win); +void CWindow_Hide(void *win); +void CWindow_Refresh(void *win); +void CWindow_AddToRefreshList(void *win); +void CWindow_RemoveFromRefreshList(void *win); + +extern cwindow_struct *updatewindowlist; + +static INLINE void CWindow_RefreshALL() +{ + cwindow_struct *aux; + EnterCriticalSection(§ion); + aux = updatewindowlist; + while(aux) + { + aux->Refresh(aux); + aux = (cwindow_struct *)aux->next; + } + LeaveCriticalSection(§ion); +} + +#endif diff --git a/desmume/src/windows/ConfigKeys.c b/desmume/src/windows/ConfigKeys.c new file mode 100644 index 000000000..8b7b0577a --- /dev/null +++ b/desmume/src/windows/ConfigKeys.c @@ -0,0 +1,277 @@ +#include +#include +#include +#include +#include +#include + +#include "CWindow.h" + +#include "../debug.h" +#include "resource.h" + +#define FNAME_LENGTH 512 + +char IniName[FNAME_LENGTH+1]; +char vPath[256],*szPath,currDir[256]; +u32 keytab[12]; + +const char tabkeytext[48][8] = {"0","1","2","3","4","5","6","7","8","9","A","B","C", +"D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X", +"Y","Z","SPACE","UP","DOWN","LEFT","RIGHT","TAB","SHIFT","DEL","INSERT","HOME","END","ENTER"}; + +DWORD dds_up=37; +DWORD dds_down=38; +DWORD dds_left=39; +DWORD dds_right=40; + +DWORD dds_a=31; +DWORD dds_b=11; +DWORD dds_x=16; +DWORD dds_y=17; + +DWORD dds_l=12; +DWORD dds_r=23; + +DWORD dds_select=36; +DWORD dds_start=47; + +DWORD dds_debug=13; + +extern DWORD ds_up; +extern DWORD ds_down; +extern DWORD ds_left; +extern DWORD ds_right; +extern DWORD ds_a; +extern DWORD ds_b; +extern DWORD ds_x; +extern DWORD ds_y; +extern DWORD ds_l; +extern DWORD ds_r; +extern DWORD ds_select; +extern DWORD ds_start; + +#define KEY_UP ds_up +#define KEY_DOWN ds_down +#define KEY_LEFT ds_left +#define KEY_RIGHT ds_right +#define KEY_X ds_x +#define KEY_Y ds_y +#define KEY_A ds_a +#define KEY_B ds_b +#define KEY_L ds_l +#define KEY_R ds_r +#define KEY_START ds_start +#define KEY_SELECT ds_select +#define KEY_DEBUG ds_debug + +const char *get_path() +{ + if (*vPath) return vPath; + ZeroMemory(vPath, sizeof(vPath)); + GetModuleFileName(NULL, vPath, sizeof(vPath)); + char *p = vPath + lstrlen(vPath); + while (p >= vPath && *p != '\\') p--; + if (++p >= vPath) *p = 0; + return vPath; +} + +void ReadConfig(void) +{ + FILE *fp; + int i; + + szPath = (char*)get_path(); + wsprintf(IniName,"%s\\desmume.ini",szPath); + + fp=fopen(IniName,"r"); + fclose(fp); + if(fp==NULL) + { + WritePrivateProfileString(NULL, NULL, NULL, IniName); + } + + i=GetPrivateProfileInt("KEYS","KEY_A",-1, IniName); + KEY_A = i; + + i=GetPrivateProfileInt("KEYS","KEY_B",-1, IniName); + KEY_B = i; + + i=GetPrivateProfileInt("KEYS","KEY_SELECT",-1, IniName); + KEY_SELECT = i; + + i=GetPrivateProfileInt("KEYS","KEY_START",-1, IniName); + if(i==13) + KEY_START = 47; + else + KEY_START = i; + + i=GetPrivateProfileInt("KEYS","KEY_RIGHT",-1, IniName); + KEY_RIGHT = i; + + i=GetPrivateProfileInt("KEYS","KEY_LEFT",-1, IniName); + KEY_LEFT = i; + + i=GetPrivateProfileInt("KEYS","KEY_UP",-1, IniName); + KEY_UP = i; + + i=GetPrivateProfileInt("KEYS","KEY_DOWN",-1, IniName); + KEY_DOWN = i; + + i=GetPrivateProfileInt("KEYS","KEY_R",-1, IniName); + KEY_R = i; + + i=GetPrivateProfileInt("KEYS","KEY_L",-1, IniName); + KEY_L = i; + + i=GetPrivateProfileInt("KEYS","KEY_X",-1, IniName); + KEY_X = i; + + i=GetPrivateProfileInt("KEYS","KEY_Y",-1, IniName); + KEY_Y = i; + + /*i=GetPrivateProfileInt("KEYS","KEY_DEBUG",-1, IniName); + KEY_DEBUG = i;*/ +} + +void WritePrivateProfileInt(char* appname, char* keyname, int val, char* file) +{ + char temp[256] = ""; + sprintf(temp, "%d", val); + WritePrivateProfileString(appname, keyname, temp, file); +} + +void WriteConfig(void) +{ + FILE *fp; + int i; + + szPath = (char*)get_path(); + wsprintf(IniName,"%s\\desmume.ini",szPath); + + fp=fopen(IniName,"w"); + fclose(fp); + if(fp==NULL) + { + WritePrivateProfileString(NULL, NULL, NULL, IniName); + } + + WritePrivateProfileInt("KEYS","KEY_A",KEY_A,IniName); + WritePrivateProfileInt("KEYS","KEY_B",KEY_B,IniName); + WritePrivateProfileInt("KEYS","KEY_SELECT",KEY_SELECT,IniName); + + if(KEY_START==47) + WritePrivateProfileInt("KEYS","KEY_START",13,IniName); + else + WritePrivateProfileInt("KEYS","KEY_START",KEY_START,IniName); + + WritePrivateProfileInt("KEYS","KEY_RIGHT",KEY_RIGHT,IniName); + WritePrivateProfileInt("KEYS","KEY_LEFT",KEY_LEFT,IniName); + WritePrivateProfileInt("KEYS","KEY_UP",KEY_UP,IniName); + WritePrivateProfileInt("KEYS","KEY_DOWN",KEY_DOWN,IniName); + WritePrivateProfileInt("KEYS","KEY_R",KEY_R,IniName); + WritePrivateProfileInt("KEYS","KEY_L",KEY_L,IniName); + WritePrivateProfileInt("KEYS","KEY_X",KEY_X,IniName); + WritePrivateProfileInt("KEYS","KEY_Y",KEY_Y,IniName); + /*WritePrivateProfileInt("KEYS","KEY_DEBUG",KEY_DEBUG,IniName);*/ +} + +void dsDefaultKeys(void) +{ + KEY_A=dds_a; + KEY_B=dds_b; + KEY_SELECT=dds_select; + KEY_START=dds_start; + KEY_RIGHT=dds_right; + KEY_LEFT=dds_left; + KEY_UP=dds_up; + KEY_DOWN=dds_down; + KEY_R=dds_r; + KEY_L=dds_l; + KEY_X=dds_x; + KEY_Y=dds_y; + //KEY_DEBUG=dds_debug; +} + +DWORD key_combos[12]={ +IDC_COMBO1, +IDC_COMBO2, +IDC_COMBO3, +IDC_COMBO4, +IDC_COMBO5, +IDC_COMBO6, +IDC_COMBO7, +IDC_COMBO8, +IDC_COMBO9, +IDC_COMBO10, +IDC_COMBO11, +IDC_COMBO12}; + +BOOL CALLBACK ConfigView_Proc(HWND dialog,UINT komunikat,WPARAM wparam,LPARAM lparam) +{ + int i,j; + char tempstring[256]; + switch(komunikat) + { + case WM_INITDIALOG: + ReadConfig(); + for(i=0;i<48;i++)for(j=0;j<12;j++)SendDlgItemMessage(dialog,key_combos[j],CB_ADDSTRING,0,(LPARAM)&tabkeytext[i]); + SendDlgItemMessage(dialog,IDC_COMBO1,CB_SETCURSEL,KEY_UP,0); + SendDlgItemMessage(dialog,IDC_COMBO2,CB_SETCURSEL,KEY_LEFT,0); + SendDlgItemMessage(dialog,IDC_COMBO3,CB_SETCURSEL,KEY_RIGHT,0); + SendDlgItemMessage(dialog,IDC_COMBO4,CB_SETCURSEL,KEY_DOWN,0); + SendDlgItemMessage(dialog,IDC_COMBO5,CB_SETCURSEL,KEY_Y,0); + SendDlgItemMessage(dialog,IDC_COMBO6,CB_SETCURSEL,KEY_X,0); + SendDlgItemMessage(dialog,IDC_COMBO7,CB_SETCURSEL,KEY_A,0); + SendDlgItemMessage(dialog,IDC_COMBO8,CB_SETCURSEL,KEY_B,0); + SendDlgItemMessage(dialog,IDC_COMBO9,CB_SETCURSEL,KEY_START,0); + SendDlgItemMessage(dialog,IDC_COMBO10,CB_SETCURSEL,KEY_L,0); + SendDlgItemMessage(dialog,IDC_COMBO11,CB_SETCURSEL,KEY_R,0); + SendDlgItemMessage(dialog,IDC_COMBO12,CB_SETCURSEL,KEY_SELECT,0); + //SendDlgItemMessage(dialog,IDC_COMBO13,CB_SETCURSEL,KEY_DEBUG,0); + break; + + case WM_COMMAND: + if((HIWORD(wparam)==BN_CLICKED)&&(((int)LOWORD(wparam))==IDC_BUTTON1)) + { + dsDefaultKeys(); + SendDlgItemMessage(dialog,IDC_COMBO1,CB_SETCURSEL,KEY_UP,0); + SendDlgItemMessage(dialog,IDC_COMBO2,CB_SETCURSEL,KEY_LEFT,0); + SendDlgItemMessage(dialog,IDC_COMBO3,CB_SETCURSEL,KEY_RIGHT,0); + SendDlgItemMessage(dialog,IDC_COMBO4,CB_SETCURSEL,KEY_DOWN,0); + SendDlgItemMessage(dialog,IDC_COMBO5,CB_SETCURSEL,KEY_Y,0); + SendDlgItemMessage(dialog,IDC_COMBO6,CB_SETCURSEL,KEY_X,0); + SendDlgItemMessage(dialog,IDC_COMBO7,CB_SETCURSEL,KEY_A,0); + SendDlgItemMessage(dialog,IDC_COMBO8,CB_SETCURSEL,KEY_B,0); + SendDlgItemMessage(dialog,IDC_COMBO9,CB_SETCURSEL,KEY_START,0); + SendDlgItemMessage(dialog,IDC_COMBO10,CB_SETCURSEL,KEY_L,0); + SendDlgItemMessage(dialog,IDC_COMBO11,CB_SETCURSEL,KEY_R,0); + SendDlgItemMessage(dialog,IDC_COMBO12,CB_SETCURSEL,KEY_SELECT,0); + //SendDlgItemMessage(dialog,IDC_COMBO13,CB_SETCURSEL,KEY_DEBUG,0); + } + else + if((HIWORD(wparam)==BN_CLICKED)&&(((int)LOWORD(wparam))==IDC_FERMER)) + { + KEY_UP=SendDlgItemMessage(dialog,IDC_COMBO1,CB_GETCURSEL,0,0); + KEY_LEFT=SendDlgItemMessage(dialog,IDC_COMBO2,CB_GETCURSEL,0,0); + KEY_RIGHT=SendDlgItemMessage(dialog,IDC_COMBO3,CB_GETCURSEL,0,0); + KEY_DOWN=SendDlgItemMessage(dialog,IDC_COMBO4,CB_GETCURSEL,0,0); + KEY_Y=SendDlgItemMessage(dialog,IDC_COMBO5,CB_GETCURSEL,0,0); + KEY_X=SendDlgItemMessage(dialog,IDC_COMBO6,CB_GETCURSEL,0,0); + KEY_A=SendDlgItemMessage(dialog,IDC_COMBO7,CB_GETCURSEL,0,0); + KEY_B=SendDlgItemMessage(dialog,IDC_COMBO8,CB_GETCURSEL,0,0); + KEY_START=SendDlgItemMessage(dialog,IDC_COMBO9,CB_GETCURSEL,0,0); + KEY_L=SendDlgItemMessage(dialog,IDC_COMBO10,CB_GETCURSEL,0,0); + KEY_R=SendDlgItemMessage(dialog,IDC_COMBO11,CB_GETCURSEL,0,0); + KEY_SELECT=SendDlgItemMessage(dialog,IDC_COMBO12,CB_GETCURSEL,0,0); + //KEY_DEBUG=SendDlgItemMessage(dialog,IDC_COMBO13,CB_GETCURSEL,0,0); + WriteConfig(); + EndDialog(dialog,0); + return 1; + } + break; + } + return 0; +} + + diff --git a/desmume/src/windows/ConfigKeys.h b/desmume/src/windows/ConfigKeys.h new file mode 100644 index 000000000..16e2efa22 --- /dev/null +++ b/desmume/src/windows/ConfigKeys.h @@ -0,0 +1,26 @@ + +#ifndef CONFIGKEYS_H +#define CONFIGKEYS_H + +extern unsigned long keytab[12]; +extern const DWORD tabkey[48]; +extern DWORD ds_up; +extern DWORD ds_down; +extern DWORD ds_left; +extern DWORD ds_right; +extern DWORD ds_a; +extern DWORD ds_b; +extern DWORD ds_x; +extern DWORD ds_y; +extern DWORD ds_l; +extern DWORD ds_r; +extern DWORD ds_select; +extern DWORD ds_start; +extern DWORD ds_debug; + +char *get_path(); +void ReadConfig(void); + +BOOL CALLBACK ConfigView_Proc(HWND dialog,UINT komunikat,WPARAM wparam,LPARAM lparam); + +#endif diff --git a/desmume/src/windows/IORegView.c b/desmume/src/windows/IORegView.c new file mode 100644 index 000000000..7a7e79b99 --- /dev/null +++ b/desmume/src/windows/IORegView.c @@ -0,0 +1,96 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "CWindow.h" +#include "resource.h" +#include "../MMU.h" +#include + +////////////////////////////////////////////////////////////////////////////// + +LRESULT Ioreg_OnPaint(HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + PAINTSTRUCT ps; + TCHAR text[80]; +// NDS_header * header = nds.getROMHeader(); + + hdc = BeginPaint(hwnd, &ps); + + sprintf(text, "%08X", (int)((u32 *)ARM9Mem.ARM9_DTCM)[0x3FFC>>2]); + SetWindowText(GetDlgItem(hwnd, IDC_INTHAND), text); + + sprintf(text, "%08X", (int)MMU.reg_IF[0]); + SetWindowText(GetDlgItem(hwnd, IDC_IE), text); + + sprintf(text, "%08X", (int)MMU.reg_IME[0]); + SetWindowText(GetDlgItem(hwnd, IDC_IME), text); + + sprintf(text, "%08X", ((u16 *)ARM9Mem.ARM9_REG)[0x0004>>1]);//((u32 *)ARM9.ARM9_REG)[0x10>>2]); + SetWindowText(GetDlgItem(hwnd, IDC_DISPCNT), text); + + sprintf(text, "%08X", ((u16 *)MMU.ARM7_REG)[0x0004>>1]);//MMU.DMACycle[0][1]);//((u16 *)ARM9.ARM9_REG)[0x16>>1]); + SetWindowText(GetDlgItem(hwnd, IDC_DISPSTAT), text); + + sprintf(text, "%08X", (int)((u32 *)ARM9Mem.ARM9_REG)[0x180>>2]);//MMU.DMACycle[0][2]);//((u32 *)ARM9.ARM9_REG)[0x001C>>2]);//MMU.fifos[0].data[MMU.fifos[0].begin]);//((u32 *)MMU.ARM7_REG)[0x210>>2]); + SetWindowText(GetDlgItem(hwnd, IDC_IPCSYNC), text); + + sprintf(text, "%08X", (int)((u32 *)MMU.ARM7_REG)[0x180>>2]);//MMU.DMACycle[0][3]);//nds.ARM9.SPSR.bits.I);//((u32 *)MMU.ARM7_REG)[0x184>>2]); + SetWindowText(GetDlgItem(hwnd, IDC_IPCFIFO), text); + + EndPaint(hwnd, &ps); + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +BOOL CALLBACK IoregView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + cwindow_struct *win = (cwindow_struct *)GetWindowLong(hwnd, DWL_USER); + switch (message) + { + case WM_INITDIALOG : + return 1; + case WM_CLOSE : + CWindow_RemoveFromRefreshList(win); + free(win); + EndDialog(hwnd, 0); + return 1; + case WM_PAINT: + Ioreg_OnPaint(hwnd, wParam, lParam); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_FERMER : + CWindow_RemoveFromRefreshList(win); + free(win); + EndDialog(hwnd, 0); + return 1; + } + return 0; + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/desmume/src/windows/IORegView.h b/desmume/src/windows/IORegView.h new file mode 100644 index 000000000..65287f0b6 --- /dev/null +++ b/desmume/src/windows/IORegView.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef IO_REG_H +#define IO_REG_H + +BOOL CALLBACK IoregView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/desmume/src/windows/Makefile.am b/desmume/src/windows/Makefile.am index 39c394922..5e32b93fe 100644 --- a/desmume/src/windows/Makefile.am +++ b/desmume/src/windows/Makefile.am @@ -1,13 +1,13 @@ bin_PROGRAMS = desmume desmume_SOURCES = \ - CWindow.cpp CWindow.hpp cflash.cpp cflash.h \ - des_view.cpp des_view.hpp ginfo.cpp ginfo.hpp \ - IORegView.cpp IORegView.hpp \ - main.cpp mapView.cpp mapView.hpp mem_view.cpp mem_view.hpp \ - oamView.cpp oamView.hpp palView.cpp palView.hpp \ - resource.h saves.cpp saves.hpp \ - tileView.cpp tileView.hpp yopyop_private.hpp \ - ConfigKeys.cpp ConfigKeys.hpp + CWindow.c CWindow.h cflash.c cflash.h \ + disView.c disView.h ginfo.c ginfo.h \ + IORegView.c IORegView.h \ + main.cpp mapView.c mapView.h memView.c memView.h \ + oamView.c oamView.h palView.c palView.h \ + resource.h \ + tileView.c tileView.h yopyop_private.h \ + ConfigKeys.c ConfigKeys.h desmume_LDADD = ../libdesmume.a yopyop_private.o yopyop_private.o: yopyop_private.rc resources.rc resource.h windres yopyop_private.rc -o yopyop_private.o diff --git a/desmume/src/windows/disView.c b/desmume/src/windows/disView.c new file mode 100644 index 000000000..0da9c6465 --- /dev/null +++ b/desmume/src/windows/disView.c @@ -0,0 +1,788 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include "../MMU.h" +#include "../Disassembler.h" +#include "disView.h" +#include "resource.h" + +#define INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF)) + +extern HDC hdc; + +LRESULT CALLBACK DisViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +u32 cycles = 1; + +void InitDesViewBox() +{ + WNDCLASSEX wc; + + wc.cbSize = sizeof(wc); + wc.lpszClassName = _T("DesViewBox"); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = DisViewBoxWndProc; + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hIcon = 0; + wc.lpszMenuName = 0; + wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE); + wc.style = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(cwindow_struct *); + wc.hIconSm = 0; + + RegisterClassEx(&wc); +} + +/* +LRESULT DesViewBox_OnPaint(CDesView * win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = GetDlgItem(win->hwnd, IDC_DES_BOX); + HDC hdc; + PAINTSTRUCT ps; + SIZE fontsize; + TCHAR text[100]; + TCHAR txt[100]; + + RECT rect; + GetClientRect(hwnd, &rect); + int lg = rect.right - rect.left; + int ht = rect.bottom - rect.top; + + hdc = BeginPaint(hwnd, &ps); + + HDC mem_dc = CreateCompatibleDC(hdc); + HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, lg, ht); + SelectObject(mem_dc, mem_bmp); + + FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + SelectObject(mem_dc, GetStockObject(SYSTEM_FIXED_FONT)); + + GetTextExtentPoint32(mem_dc, "0", 1, &fontsize); + + u32 nbligne = ht/fontsize.cy; + + SetTextColor(mem_dc, RGB(0,0,0)); + + if((win->mode==1) || ((win->mode==0) && (win->cpu->CPSR.bits.T == 0))) + { + u32 adr = win->curr_ligne*4; + + for(u32 i = 0; i < nbligne; ++i) + { + u32 ins = MMU_readWord(win->cpu->proc_ID, adr); + des_arm_instructions_set[INDEX(ins)](adr, ins, txt); + sprintf(text, "%04X:%04X %08X %s", (int)(adr>>16), (int)(adr&0xFFFF), (int)ins, txt); + DrawText(mem_dc, text, -1, &rect, DT_TOP | DT_LEFT | DT_NOPREFIX); + rect.top+=fontsize.cy; + adr += 4; + } + + if(((win->cpu->instruct_adr&0x0FFFFFFF) >= win->curr_ligne<<2)&&((win->cpu->instruct_adr&0x0FFFFFFF) <= (win->curr_ligne+nbligne<<2))) + { + HBRUSH brjaune = CreateSolidBrush(RGB(255, 255, 0)); + SetBkColor(mem_dc, RGB(255, 255, 0)); + rect.top = (((win->cpu->instruct_adr&0x0FFFFFFF)>>2) - win->curr_ligne)*fontsize.cy; + rect.bottom = rect.top + fontsize.cy; + FillRect(mem_dc, &rect, brjaune); + des_arm_instructions_set[INDEX(win->cpu->instruction)](win->cpu->instruct_adr, win->cpu->instruction, txt); + sprintf(text, "%04X:%04X %08X %s", (int)((win->cpu->instruct_adr&0x0FFFFFFF)>>16), (int)(win->cpu->instruct_adr&0xFFFF), (int)win->cpu->instruction, txt); + DrawText(mem_dc, text, -1, &rect, DT_TOP | DT_LEFT | DT_NOPREFIX); + DeleteObject(brjaune); + } + } + else + { + u32 adr = win->curr_ligne*2; + + for(u32 i = 0; i < nbligne; ++i) + { + u32 ins = MMU_readHWord(win->cpu->proc_ID, adr); + des_thumb_instructions_set[ins>>6](adr, ins, txt); + sprintf(text, "%04X:%04X %04X %s", (int)(adr>>16), (int)(adr&0xFFFF), (int)ins, txt); + DrawText(mem_dc, text, -1, &rect, DT_TOP | DT_LEFT | DT_NOPREFIX); + rect.top+=fontsize.cy; + adr += 2; + } + + if(((win->cpu->instruct_adr&0x0FFFFFFF) >= win->curr_ligne<<1)&&((win->cpu->instruct_adr&0x0FFFFFFF) <= (win->curr_ligne+nbligne<<1))) + { + HBRUSH brjaune = CreateSolidBrush(RGB(255, 255, 0)); + SetBkColor(mem_dc, RGB(255, 255, 0)); + + rect.top = (((win->cpu->instruct_adr&0x0FFFFFFF)>>1) - win->curr_ligne)*fontsize.cy; + rect.bottom = rect.top + fontsize.cy; + FillRect(mem_dc, &rect, brjaune); + des_thumb_instructions_set[((win->cpu->instruction)&0xFFFF)>>6](win->cpu->instruct_adr, win->cpu->instruction&0xFFFF, txt); + sprintf(text, "%04X:%04X %04X %s", (int)((win->cpu->instruct_adr&0x0FFFFFFF)>>16), (int)(win->cpu->instruct_adr&0xFFFF), (int)(win->cpu->instruction&0xFFFF), txt); + DrawText(mem_dc, text, -1, &rect, DT_TOP | DT_LEFT | DT_NOPREFIX); + DeleteObject(brjaune); + } + } + + BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY); + + DeleteDC(mem_dc); + DeleteObject(mem_bmp); + + EndPaint(hwnd, &ps); + return 1; +} + +LRESULT DesViewDialog_OnPaint(HWND hwnd, CDesView * win, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + PAINTSTRUCT ps; + TCHAR text[80]; + + hdc = BeginPaint(hwnd, &ps); + + for(u32 i = 0; i < 16; ++i) + { + sprintf(text, "%08X", (int)win->cpu->R[i]); + SetWindowText(GetDlgItem(hwnd, IDC_R0+i), text); + } + + #define OFF 16 + + SetBkMode(hdc, TRANSPARENT); + if(win->cpu->CPSR.bits.N) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 452+OFF, 238, "N", 1); + + if(win->cpu->CPSR.bits.Z) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 464+OFF, 238, "Z", 1); + + if(win->cpu->CPSR.bits.C) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 475+OFF, 238, "C", 1); + + if(win->cpu->CPSR.bits.V) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 486+OFF, 238, "V", 1); + + if(win->cpu->CPSR.bits.Q) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 497+OFF, 238, "Q", 1); + + if(!win->cpu->CPSR.bits.I) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 508+OFF, 238, "I", 1); + + sprintf(text, "%02X", (int)win->cpu->CPSR.bits.mode); + SetWindowText(GetDlgItem(hwnd, IDC_MODE), text); + + sprintf(text, "%08X", MMU.timer[0][0]);//win->cpu->SPSR); + SetWindowText(GetDlgItem(hwnd, IDC_TMP), text); + + EndPaint(hwnd, &ps); + return 1; +} + +LRESULT CALLBACK DesViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CDesView * win = (CDesView *)GetWindowLong(hwnd, 0); + + switch(msg) + { + case WM_NCCREATE: + SetScrollRange(hwnd, SB_VERT, 0, 0x3FFFFF7, TRUE); + SetScrollPos(hwnd, SB_VERT, 10, TRUE); + return 1; + + case WM_NCDESTROY: + free(win); + return 1; + + case WM_PAINT: + DesViewBox_OnPaint(win, wParam, lParam); + return 1; + + case WM_VSCROLL : + { + RECT rect; + SIZE fontsize; + GetClientRect(hwnd, &rect); + HDC dc = GetDC(hwnd); + HFONT old = (HFONT)SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT)); + GetTextExtentPoint32(dc, "0", 1, &fontsize); + + int nbligne = (rect.bottom - rect.top)/fontsize.cy; + + switch LOWORD(wParam) + { + case SB_LINEDOWN : + win->curr_ligne = min(0x3FFFFF7*(1+win->cpu->CPSR.bits.T), win->curr_ligne+1); + break; + case SB_LINEUP : + win->curr_ligne = (u32)max(0, (s32)win->curr_ligne-1); + break; + case SB_PAGEDOWN : + win->curr_ligne = min(0x3FFFFF7*(1+win->cpu->CPSR.bits.T), win->curr_ligne+nbligne); + break; + case SB_PAGEUP : + win->curr_ligne = (u32)max(0, (s32)win->curr_ligne-nbligne); + break; + } + + SelectObject(dc, old); + SetScrollPos(hwnd, SB_VERT, win->curr_ligne, TRUE); + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(hwnd); + } + return 1; + + case WM_ERASEBKGND: + return 1; + default: + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + + +// DES VIEWER +BOOL CALLBACK des_view_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CDesView * win = (CDesView *)GetWindowLong(hwnd, DWL_USER); + + switch (message) + { + case WM_INITDIALOG : + SetDlgItemInt(hwnd, IDC_SETPNUM, 1, FALSE); + SendMessage(GetDlgItem(hwnd, IDC_AUTO_DES), BM_SETCHECK, TRUE, 0); + return 1; + case WM_CLOSE : + win->remove2RefreshList(); + delete win; + EndDialog(hwnd, 0); + return 1; + case WM_PAINT: + DesViewDialog_OnPaint(hwnd, win, wParam, lParam); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_FERMER : + win->remove2RefreshList(); + delete win; + EndDialog(hwnd, 0); + return 0; + case IDC_AUTO_DES : + win->mode = 0; + InvalidateRect(GetDlgItem(hwnd, IDC_DES_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_DES_BOX)); + return 1; + case IDC_ARM : + win->mode = 1; + InvalidateRect(GetDlgItem(hwnd, IDC_DES_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_DES_BOX)); + return 1; + case IDC_THUMB : + win->mode = 2; + InvalidateRect(GetDlgItem(hwnd, IDC_DES_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_DES_BOX)); + return 1; + case IDC_AUTO_UPDATE : + if(win->autoup) + { + win->remove2RefreshList(); + win->autoup = FALSE; + return 1; + } + win->add2RefreshList(); + win->autoup = TRUE; + return 1; + case IDC_STEP : + { + BITMAPV4HEADER bmi; + + //CreateBitmapIndirect(&bmi); + memset(&bmi, 0, sizeof(bmi)); + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB|BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + bmi.bV4Width = 256; + bmi.bV4Height = -192; + int ndstep = GetDlgItemInt(hwnd, IDC_SETPNUM, NULL, FALSE); + NDS_exec(ndstep, TRUE); + if(!win->autoup) win->refresh(); + CWindow::refreshALL(); + SetDIBitsToDevice(hdc, 0, 0, 256, 192*2, 0, 0, 0, 192*2, GPU_screen, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + } + return 1; + case IDC_GO : + { + char tmp[8]; + int lg = GetDlgItemText(hwnd, IDC_GOTODES, tmp, 8); + u32 adr = 0; + for(u16 i = 0; i='A')&&(tmp[i]<='F')) + { + adr = adr*16 + (tmp[i]-'A'+10); + continue; + } + if((tmp[i]>='0')&&(tmp[i]<='9')) + { + adr = adr*16 + (tmp[i]-'0'); + continue; + } + } + win->curr_ligne = adr>>2; + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_DES_BOX)); + } + return 1; + return 1; + } + return 0; + } + return 0; +} + +CDesView::CDesView(HINSTANCE hInst, HWND parent, char * titre, armcpu_t * CPU) : + CWindow(hInst, parent, titre, IDD_DESASSEMBLEUR_VIEWER, des_view_proc), cpu(CPU), mode(0) +{ + SetWindowLong(GetDlgItem(hwnd, IDC_DES_BOX), 0, (LONG)this); +} + +void CDesView::refresh() +{ + if(((cpu->instruct_adr&0x0FFFFFFF)>>(2-cpu->CPSR.bits.T))>=8) + if(((cpu->instruct_adr&0x0FFFFFFF)>>(2-cpu->CPSR.bits.T))<=0x3FFFFF7*(1+cpu->CPSR.bits.T)) + curr_ligne = ((cpu->instruct_adr&0x0FFFFFFF)>>(2-cpu->CPSR.bits.T))-8; + else + curr_ligne = 0x3FFFFEF*(1+cpu->CPSR.bits.T); + else + curr_ligne = 0; + SetScrollRange(GetDlgItem(hwnd, IDC_DES_BOX), SB_VERT, 0, 0x3FFFFF7*(1+cpu->CPSR.bits.T), TRUE); + SetScrollPos(GetDlgItem(hwnd, IDC_DES_BOX), SB_VERT, curr_ligne, TRUE); + InvalidateRect(hwnd, NULL, FALSE); +} +*/ +////////////////////////////////////////////////////////////////////////////// + +LRESULT DisViewBox_OnPaint(disview_struct *win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = GetDlgItem(win->hwnd, IDC_DES_BOX); + HDC hdc; + PAINTSTRUCT ps; + SIZE fontsize; + TCHAR text[100]; + TCHAR txt[100]; + + RECT rect; + GetClientRect(hwnd, &rect); + int lg = rect.right - rect.left; + int ht = rect.bottom - rect.top; + + hdc = BeginPaint(hwnd, &ps); + + HDC mem_dc = CreateCompatibleDC(hdc); + HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, lg, ht); + SelectObject(mem_dc, mem_bmp); + + FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + SelectObject(mem_dc, GetStockObject(SYSTEM_FIXED_FONT)); + + GetTextExtentPoint32(mem_dc, "0", 1, &fontsize); + + u32 nbligne = ht/fontsize.cy; + + SetTextColor(mem_dc, RGB(0,0,0)); + + if((win->mode==1) || ((win->mode==0) && (win->cpu->CPSR.bits.T == 0))) + { + u32 i; + u32 adr = win->curr_ligne*4; + + for(i = 0; i < nbligne; ++i) + { + u32 ins = MMU_readWord(win->cpu->proc_ID, adr); + des_arm_instructions_set[INDEX(ins)](adr, ins, txt); + sprintf(text, "%04X:%04X %08X %s", (int)(adr>>16), (int)(adr&0xFFFF), (int)ins, txt); + DrawText(mem_dc, text, -1, &rect, DT_TOP | DT_LEFT | DT_NOPREFIX); + rect.top+=fontsize.cy; + adr += 4; + } + + if(((win->cpu->instruct_adr&0x0FFFFFFF) >= win->curr_ligne<<2)&&((win->cpu->instruct_adr&0x0FFFFFFF) <= (win->curr_ligne+nbligne<<2))) + { + HBRUSH brjaune = CreateSolidBrush(RGB(255, 255, 0)); + SetBkColor(mem_dc, RGB(255, 255, 0)); + rect.top = (((win->cpu->instruct_adr&0x0FFFFFFF)>>2) - win->curr_ligne)*fontsize.cy; + rect.bottom = rect.top + fontsize.cy; + FillRect(mem_dc, &rect, brjaune); + des_arm_instructions_set[INDEX(win->cpu->instruction)](win->cpu->instruct_adr, win->cpu->instruction, txt); + sprintf(text, "%04X:%04X %08X %s", (int)((win->cpu->instruct_adr&0x0FFFFFFF)>>16), (int)(win->cpu->instruct_adr&0xFFFF), (int)win->cpu->instruction, txt); + DrawText(mem_dc, text, -1, &rect, DT_TOP | DT_LEFT | DT_NOPREFIX); + DeleteObject(brjaune); + } + } + else + { + u32 i; + u32 adr = win->curr_ligne*2; + + for(i = 0; i < nbligne; ++i) + { + u32 ins = MMU_readHWord(win->cpu->proc_ID, adr); + des_thumb_instructions_set[ins>>6](adr, ins, txt); + sprintf(text, "%04X:%04X %04X %s", (int)(adr>>16), (int)(adr&0xFFFF), (int)ins, txt); + DrawText(mem_dc, text, -1, &rect, DT_TOP | DT_LEFT | DT_NOPREFIX); + rect.top+=fontsize.cy; + adr += 2; + } + + if(((win->cpu->instruct_adr&0x0FFFFFFF) >= win->curr_ligne<<1)&&((win->cpu->instruct_adr&0x0FFFFFFF) <= (win->curr_ligne+nbligne<<1))) + { + HBRUSH brjaune = CreateSolidBrush(RGB(255, 255, 0)); + SetBkColor(mem_dc, RGB(255, 255, 0)); + + rect.top = (((win->cpu->instruct_adr&0x0FFFFFFF)>>1) - win->curr_ligne)*fontsize.cy; + rect.bottom = rect.top + fontsize.cy; + FillRect(mem_dc, &rect, brjaune); + des_thumb_instructions_set[((win->cpu->instruction)&0xFFFF)>>6](win->cpu->instruct_adr, win->cpu->instruction&0xFFFF, txt); + sprintf(text, "%04X:%04X %04X %s", (int)((win->cpu->instruct_adr&0x0FFFFFFF)>>16), (int)(win->cpu->instruct_adr&0xFFFF), (int)(win->cpu->instruction&0xFFFF), txt); + DrawText(mem_dc, text, -1, &rect, DT_TOP | DT_LEFT | DT_NOPREFIX); + DeleteObject(brjaune); + } + } + + BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY); + + DeleteDC(mem_dc); + DeleteObject(mem_bmp); + + EndPaint(hwnd, &ps); + return 1; +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT DisViewDialog_OnPaint(HWND hwnd, disview_struct *win, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + PAINTSTRUCT ps; + TCHAR text[80]; + u32 i; + + hdc = BeginPaint(hwnd, &ps); + + for(i = 0; i < 16; ++i) + { + sprintf(text, "%08X", (int)win->cpu->R[i]); + SetWindowText(GetDlgItem(hwnd, IDC_R0+i), text); + } + + #define OFF 16 + + SetBkMode(hdc, TRANSPARENT); + if(win->cpu->CPSR.bits.N) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 452+OFF, 238, "N", 1); + + if(win->cpu->CPSR.bits.Z) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 464+OFF, 238, "Z", 1); + + if(win->cpu->CPSR.bits.C) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 475+OFF, 238, "C", 1); + + if(win->cpu->CPSR.bits.V) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 486+OFF, 238, "V", 1); + + if(win->cpu->CPSR.bits.Q) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 497+OFF, 238, "Q", 1); + + if(!win->cpu->CPSR.bits.I) + SetTextColor(hdc, RGB(255,0,0)); + else + SetTextColor(hdc, RGB(70, 70, 70)); + TextOut(hdc, 508+OFF, 238, "I", 1); + + sprintf(text, "%02X", (int)win->cpu->CPSR.bits.mode); + SetWindowText(GetDlgItem(hwnd, IDC_MODE), text); + + sprintf(text, "%08X", MMU.timer[0][0]);//win->cpu->SPSR); + SetWindowText(GetDlgItem(hwnd, IDC_TMP), text); + + EndPaint(hwnd, &ps); + return 1; +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK DisViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + disview_struct *win = (disview_struct *)GetWindowLong(hwnd, 0); + + switch(msg) + { + case WM_NCCREATE: + SetScrollRange(hwnd, SB_VERT, 0, 0x3FFFFF7, TRUE); + SetScrollPos(hwnd, SB_VERT, 10, TRUE); + return 1; + + case WM_NCDESTROY: + free(win); + return 1; + + case WM_PAINT: + DisViewBox_OnPaint(win, wParam, lParam); + return 1; + + case WM_VSCROLL : + { + RECT rect; + SIZE fontsize; + GetClientRect(hwnd, &rect); + HDC dc = GetDC(hwnd); + HFONT old = (HFONT)SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT)); + GetTextExtentPoint32(dc, "0", 1, &fontsize); + + int nbligne = (rect.bottom - rect.top)/fontsize.cy; + + switch LOWORD(wParam) + { + case SB_LINEDOWN : + win->curr_ligne = min(0x3FFFFF7*(1+win->cpu->CPSR.bits.T), win->curr_ligne+1); + break; + case SB_LINEUP : + win->curr_ligne = (u32)max(0, (s32)win->curr_ligne-1); + break; + case SB_PAGEDOWN : + win->curr_ligne = min(0x3FFFFF7*(1+win->cpu->CPSR.bits.T), win->curr_ligne+nbligne); + break; + case SB_PAGEUP : + win->curr_ligne = (u32)max(0, (s32)win->curr_ligne-nbligne); + break; + } + + SelectObject(dc, old); + SetScrollPos(hwnd, SB_VERT, win->curr_ligne, TRUE); + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(hwnd); + } + return 1; + + case WM_ERASEBKGND: + return 1; + default: + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +////////////////////////////////////////////////////////////////////////////// + +// DES VIEWER +BOOL CALLBACK DisView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + disview_struct *win = (disview_struct *)GetWindowLong(hwnd, DWL_USER); + + switch (message) + { + case WM_INITDIALOG : + SetDlgItemInt(hwnd, IDC_SETPNUM, 1, FALSE); + SendMessage(GetDlgItem(hwnd, IDC_AUTO_DES), BM_SETCHECK, TRUE, 0); + return 1; + case WM_CLOSE : + CWindow_RemoveFromRefreshList(win); + DisView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case WM_PAINT: + DisViewDialog_OnPaint(hwnd, win, wParam, lParam); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_FERMER : + CWindow_RemoveFromRefreshList(win); + DisView_Deinit(win); + EndDialog(hwnd, 0); + return 0; + case IDC_AUTO_DES : + win->mode = 0; + InvalidateRect(GetDlgItem(hwnd, IDC_DES_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_DES_BOX)); + return 1; + case IDC_ARM : + win->mode = 1; + InvalidateRect(GetDlgItem(hwnd, IDC_DES_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_DES_BOX)); + return 1; + case IDC_THUMB : + win->mode = 2; + InvalidateRect(GetDlgItem(hwnd, IDC_DES_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_DES_BOX)); + return 1; + case IDC_AUTO_UPDATE : + if(win->autoup) + { + CWindow_RemoveFromRefreshList(win); + win->autoup = FALSE; + return 1; + } + CWindow_AddToRefreshList(win); + win->autoup = TRUE; + return 1; + case IDC_STEP : + { + BITMAPV4HEADER bmi; + + //CreateBitmapIndirect(&bmi); + memset(&bmi, 0, sizeof(bmi)); + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB|BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + bmi.bV4Width = 256; + bmi.bV4Height = -192; + int ndstep = GetDlgItemInt(hwnd, IDC_SETPNUM, NULL, FALSE); + NDS_exec(ndstep, TRUE); + if(!win->autoup) win->Refresh(win); + CWindow_RefreshALL(); + SetDIBitsToDevice(hdc, 0, 0, 256, 192*2, 0, 0, 0, 192*2, GPU_screen, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + } + return 1; + case IDC_GO : + { + u16 i; + char tmp[8]; + int lg = GetDlgItemText(hwnd, IDC_GOTODES, tmp, 8); + u32 adr = 0; + for(i = 0; i='A')&&(tmp[i]<='F')) + { + adr = adr*16 + (tmp[i]-'A'+10); + continue; + } + if((tmp[i]>='0')&&(tmp[i]<='9')) + { + adr = adr*16 + (tmp[i]-'0'); + continue; + } + } + win->curr_ligne = adr>>2; + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_DES_BOX)); + } + return 1; + return 1; + } + return 0; + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +disview_struct *DisView_Init(HINSTANCE hInst, HWND parent, char *title, armcpu_t *CPU) +{ + disview_struct *DisView=NULL; + + if ((DisView = (disview_struct *)malloc(sizeof(disview_struct))) == NULL) + return DisView; + + if (CWindow_Init2(DisView, hInst, parent, title, IDD_DESASSEMBLEUR_VIEWER, DisView_Proc) != 0) + { + free(DisView); + return NULL; + } + + DisView->cpu = CPU; + DisView->mode = 0; + DisView->Refresh = (void (*)(void *))&DisView_Refresh; + + SetWindowLong(GetDlgItem(DisView->hwnd, IDC_DES_BOX), 0, (LONG)DisView); + + return DisView; +} + +////////////////////////////////////////////////////////////////////////////// + +void DisView_Deinit(disview_struct *DisView) +{ + if (DisView) + free(DisView); +} + +////////////////////////////////////////////////////////////////////////////// + +void DisView_Refresh(disview_struct *DisView) +{ + if(((DisView->cpu->instruct_adr&0x0FFFFFFF)>>(2-DisView->cpu->CPSR.bits.T))>=8) + if(((DisView->cpu->instruct_adr&0x0FFFFFFF)>>(2-DisView->cpu->CPSR.bits.T))<=0x3FFFFF7*(1+DisView->cpu->CPSR.bits.T)) + DisView->curr_ligne = ((DisView->cpu->instruct_adr&0x0FFFFFFF)>>(2-DisView->cpu->CPSR.bits.T))-8; + else + DisView->curr_ligne = 0x3FFFFEF*(1+DisView->cpu->CPSR.bits.T); + else + DisView->curr_ligne = 0; + SetScrollRange(GetDlgItem(DisView->hwnd, IDC_DES_BOX), SB_VERT, 0, 0x3FFFFF7*(1+DisView->cpu->CPSR.bits.T), TRUE); + SetScrollPos(GetDlgItem(DisView->hwnd, IDC_DES_BOX), SB_VERT, DisView->curr_ligne, TRUE); + InvalidateRect(DisView->hwnd, NULL, FALSE); +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/desmume/src/windows/disView.h b/desmume/src/windows/disView.h new file mode 100644 index 000000000..e62409571 --- /dev/null +++ b/desmume/src/windows/disView.h @@ -0,0 +1,49 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef DISVIEW_H +#define DISVIEW_H + +#include "../NDSSystem.h" +#include "../armcpu.h" + +#include "CWindow.h" + +typedef struct +{ + HWND hwnd; + BOOL autoup; + void *prev; + void *next; + void *first; + void (*Refresh)(void *win); + + u32 curr_ligne; + armcpu_t *cpu; + u16 mode; +} disview_struct; + +void InitDesViewBox(); +disview_struct *DisView_Init(HINSTANCE hInst, HWND parent, char *title, armcpu_t *CPU); +void DisView_Deinit(disview_struct *DisView); +void DisView_Refresh(disview_struct *DisView); + +#endif diff --git a/desmume/src/windows/ginfo.c b/desmume/src/windows/ginfo.c new file mode 100644 index 000000000..e548e3830 --- /dev/null +++ b/desmume/src/windows/ginfo.c @@ -0,0 +1,89 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "resource.h" +#include "../NDSSystem.h" +#include "../MMU.h" +#include +#include "CWindow.h" + +////////////////////////////////////////////////////////////////////////////// + +LRESULT Ginfo_OnPaint(HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + PAINTSTRUCT ps; + TCHAR text[80]; + NDS_header * header = NDS_getROMHeader(); + + hdc = BeginPaint(hwnd, &ps); + + //sprintf(text, "%08X", MMU::ARM9_MEM_MASK[0x80]); + // This needs to be done because some games use all 12 bytes for text + // without a 0x00 termination + memcpy(text, header->gameTile, 12); + text[12] = 0x00; + SetWindowText(GetDlgItem(hwnd, IDC_NOM_JEU), text); + SetWindowText(GetDlgItem(hwnd, IDC_CDE), header->gameCode); + sprintf(text, "%d", header->makerCode); + SetWindowText(GetDlgItem(hwnd, IDC_FAB), text); + sprintf(text, "%d", header->cardSize); + SetWindowText(GetDlgItem(hwnd, IDC_TAILLE), text); + sprintf(text, "%d", (int)header->ARM9binSize); + SetWindowText(GetDlgItem(hwnd, IDC_ARM9_T), text); + sprintf(text, "%d", (int)header->ARM7binSize); + SetWindowText(GetDlgItem(hwnd, IDC_ARM7_T), text); + sprintf(text, "%d", (int)(header->ARM7binSize + header->ARM7src)); + SetWindowText(GetDlgItem(hwnd, IDC_DATA), text); + + EndPaint(hwnd, &ps); + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +BOOL CALLBACK GinfoView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + return 1; + case WM_CLOSE : + EndDialog(hwnd, 0); + return 1; + case WM_PAINT: + Ginfo_OnPaint(hwnd, wParam, lParam); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_FERMER : + EndDialog(hwnd, 0); + return 1; + } + return 0; + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/desmume/src/windows/ginfo.h b/desmume/src/windows/ginfo.h new file mode 100644 index 000000000..46ce36613 --- /dev/null +++ b/desmume/src/windows/ginfo.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef GINFO_H +#define GINFO_H + +BOOL CALLBACK GinfoView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +#endif + diff --git a/desmume/src/windows/main.c b/desmume/src/windows/main.c new file mode 100644 index 000000000..4ed799f8a --- /dev/null +++ b/desmume/src/windows/main.c @@ -0,0 +1,831 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//#define RENDER3D + +#include +#include +#include "CWindow.h" +#include "../MMU.h" +#include "../armcpu.h" +#include "../NDSSystem.h" +#include "resource.h" +#include "memView.h" +#include "disView.h" +#include "ginfo.h" +#include "IORegView.h" +#include "palView.h" +#include "tileView.h" +#include "oamView.h" +#include "../debug.h" +#include "mapview.h" +#include "../saves.h" +#include "cflash.h" +#include "ConfigKeys.h" + +#ifdef RENDER3D + #include "OGLRender.h" +#endif + +/* Declare Windows procedure */ +LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); + +/* Make the class name into a global variable */ +char SavName[MAX_PATH] = ""; +char SavName2[MAX_PATH] = ""; +char szClassName[ ] = "DeSmuME"; +int romnum = 0; + +DWORD threadID; + +HWND hwnd; +HDC hdc; +HINSTANCE hAppInst; + +BOOL execute = FALSE; +u32 glock = 0; + +BOOL click = FALSE; + +BOOL finished = FALSE; + +HMENU menu; + +const DWORD tabkey[48]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,VK_SPACE,VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT,VK_TAB,VK_SHIFT,VK_DELETE,VK_INSERT,VK_HOME,VK_END,0x0d}; +DWORD ds_up,ds_down,ds_left,ds_right,ds_a,ds_b,ds_x,ds_y,ds_l,ds_r,ds_select,ds_start,ds_debug; + +DWORD WINAPI run( LPVOID lpParameter) +{ + u64 count; + u64 freq; + u64 nextcount=0; + u32 nbframe = 0; + char txt[80]; + BITMAPV4HEADER bmi; + u32 cycles = 0; + int wait=0; + + //CreateBitmapIndirect(&bmi); + memset(&bmi, 0, sizeof(bmi)); + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB|BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + bmi.bV4Width = 256; + bmi.bV4Height = -192; + + #ifdef RENDER3D + OGLRender::init(&hdc); + #endif + QueryPerformanceFrequency((LARGE_INTEGER *)&freq); + QueryPerformanceCounter((LARGE_INTEGER *)&count); + nextcount = count + freq; + + while(!finished) + { + while(execute) + { + cycles = NDS_exec((560190<<1)-cycles,FALSE); + ++nbframe; + QueryPerformanceCounter((LARGE_INTEGER *)&count); + if(nextcount<=count) + { + if(wait>0) + Sleep(wait); + sprintf(txt,"DeSmuME %d", (int)nbframe); + if(nbframe>60) + wait += (nbframe-60)*2; + else if(nbframe<60 && wait>0) + wait -= (60-nbframe); + SetWindowText(hwnd, txt); + nbframe = 0; + nextcount += freq; + } + #ifndef RENDER3D + SetDIBitsToDevice(hdc, 0, 0, 256, 192*2, 0, 0, 0, 192*2, GPU_screen, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + //SetDIBitsToDevice(hdc, 0, 192, 256, 192*2, 0, 0, 192, 192*2, GPU_screen, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + #else + SetDIBitsToDevice(hdc, 0, 0, 256, 192*2, 0, 0, 192, 192*2, GPU_screen, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + //SetDIBitsToDevice(hdc, 0, 0, 256, 192, 0, 0, 0, 192, GPU_screen, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + #endif + CWindow_RefreshALL(); + Sleep(0); + //execute = FALSE; + } + Sleep(500); + } + return 1; +} + +BOOL LoadROM(char * filename) +{ + HANDLE File; + u32 FileSize; + u32 nblu = 0; + u32 mask; + u8 *ROM; + + if(!strlen(filename)) return FALSE; + + if((*filename)=='\"') + { + ++filename; + filename[strlen(filename)-1] = '\0'; + } + + if(strncmp(filename + strlen(filename)-3, "nds", 3)) + { + MessageBox(hwnd,"Error, not a nds file","Error",MB_OK); + return FALSE; + } + + File = CreateFile(filename, + GENERIC_READ | FILE_FLAG_OVERLAPPED, + FILE_SHARE_READ, + NULL,OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if(File == INVALID_HANDLE_VALUE) + { + MessageBox(hwnd,"Error opening the file","Error",MB_OK); + return FALSE; + } + + execute = FALSE; + + mask = FileSize = GetFileSize(File, NULL) - 1; + mask |= (mask >>1); + mask |= (mask >>2); + mask |= (mask >>4); + mask |= (mask >>8); + mask |= (mask >>16); + + if ((ROM = (u8 *)malloc((mask+1)*sizeof(u8))) == NULL) + { + CloseHandle(File); + return FALSE; + } + + ReadFile(File, ROM, FileSize, &nblu, NULL); + NDS_loadROM(ROM, mask); + CloseHandle(File); + return TRUE; +} + +int WriteBMP(const char *filename,u16 *bmp){ + BITMAPFILEHEADER fileheader; + BITMAPV4HEADER imageheader; + FILE *file; + int i,j,k; + + memset(&fileheader, 0, sizeof(fileheader)); + fileheader.bfType = 'B' | ('M' << 8); + fileheader.bfSize = sizeof(fileheader); + fileheader.bfOffBits = sizeof(fileheader)+sizeof(imageheader); + + memset(&imageheader, 0, sizeof(imageheader)); + imageheader.bV4Size = sizeof(imageheader); + imageheader.bV4Width = 256; + imageheader.bV4Height = 192*2; + imageheader.bV4Planes = 1; + imageheader.bV4BitCount = 24; + imageheader.bV4V4Compression = BI_RGB; + imageheader.bV4SizeImage = imageheader.bV4Width * imageheader.bV4Height * sizeof(RGBTRIPLE); + + if ((file = fopen(filename,"wb")) == NULL) + return 0; + + fwrite(&fileheader, 1, sizeof(fileheader), file); + fwrite(&imageheader, 1, sizeof(imageheader), file); + + for(j=0;j<192*2;j++) + { + for(i=0;i<256;i++) + { + u8 r,g,b; + u16 pixel = bmp[(192*2-j-1)*256+i]; + r = pixel>>10; + pixel-=r<<10; + g = pixel>>5; + pixel-=g<<5; + b = pixel; + r*=255/31; + g*=255/31; + b*=255/31; + fwrite(&r, 1, sizeof(u8), file); + fwrite(&g, 1, sizeof(u8), file); + fwrite(&b, 1, sizeof(u8), file); + } + } + fclose(file); + + return 1; +} +int WINAPI WinMain (HINSTANCE hThisInstance, + HINSTANCE hPrevInstance, + LPSTR lpszArgument, + int nFunsterStil) + +{ + MSG messages; /* Here messages to the application are saved */ + hAppInst=hThisInstance; + char text[80]; + cwindow_struct MainWindow; + + InitializeCriticalSection(§ion); + sprintf(text, "DeSmuME v%s", VERSION); + + if (CWindow_Init(&MainWindow, hThisInstance, szClassName, text, + WS_CAPTION| WS_SYSMENU |WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + 256, 384, WindowProcedure) != 0) + { + MessageBox(NULL,"Unable to create main window","Error",MB_OK); + return 0; + } + + hwnd = MainWindow.hwnd; + menu = LoadMenu(hThisInstance, "MENU_PRINCIPAL"); + SetMenu(hwnd, menu); + hdc = GetDC(hwnd); + DragAcceptFiles(hwnd, TRUE); + + /* Make the window visible on the screen */ + CWindow_Show(&MainWindow); + + InitMemViewBox(); + InitDesViewBox(); + InitTileViewBox(); + InitOAMViewBox(); + +#ifdef DEBUG + LogStart(); +#endif + + NDSInit(); + + //ARM7 BIOS IRQ HANDLER + MMU_writeWord(1, 0x00, 0xE25EF002); + MMU_writeWord(1, 0x04, 0xEAFFFFFE); + MMU_writeWord(1, 0x18, 0xEA000000); + MMU_writeWord(1, 0x20, 0xE92D500F); + MMU_writeWord(1, 0x24, 0xE3A00301); + MMU_writeWord(1, 0x28, 0xE28FE000); + MMU_writeWord(1, 0x2C, 0xE510F004); + MMU_writeWord(1, 0x30, 0xE8BD500F); + MMU_writeWord(1, 0x34, 0xE25EF004); + + //ARM9 BIOS IRQ HANDLER + MMU_writeWord(0, 0xFFF0018, 0xEA000000); + MMU_writeWord(0, 0xFFF0020, 0xE92D500F); + MMU_writeWord(0, 0xFFF0024, 0xEE190F11); + MMU_writeWord(0, 0xFFF0028, 0xE1A00620); + MMU_writeWord(0, 0xFFF002C, 0xE1A00600); + MMU_writeWord(0, 0xFFF0030, 0xE2800C40); + MMU_writeWord(0, 0xFFF0034, 0xE28FE000); + MMU_writeWord(0, 0xFFF0038, 0xE510F004); + MMU_writeWord(0, 0xFFF003C, 0xE8BD500F); + MMU_writeWord(0, 0xFFF0040, 0xE25EF004); + + MMU_writeWord(0, 0x0000004, 0xE3A0010E); + MMU_writeWord(0, 0x0000008, 0xE3A01020); +// MMU_writeWord(0, 0x000000C, 0xE1B02110); + MMU_writeWord(0, 0x000000C, 0xE1B02040); + MMU_writeWord(0, 0x0000010, 0xE3B02020); +// MMU_writeWord(0, 0x0000010, 0xE2100202); + + CreateThread(NULL, 0, run, NULL, 0, &threadID); + + if(LoadROM(lpszArgument)) execute = TRUE; + + while (GetMessage (&messages, NULL, 0, 0)) + { + // Translate virtual-key messages into character messages + TranslateMessage(&messages); + // Send message to WindowProcedure + DispatchMessage(&messages); + } + +#ifdef DEBUG + LogStop(); +#endif + /* The program return-value is 0 - The value that PostQuitMessage() gave */ + return messages.wParam; +} + +LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) // handle the messages + { + case WM_CREATE: + ReadConfig(); + return 0; + case WM_DESTROY: + execute = FALSE; + finished = TRUE; + PostQuitMessage (0); // send a WM_QUIT to the message queue + return 0; + case WM_CLOSE: + execute = FALSE; + finished = TRUE; + PostMessage(hwnd, WM_QUIT, 0, 0); + return 0; + case WM_DROPFILES: + { + char filename[MAX_PATH] = ""; + DragQueryFile((HDROP)wParam,0,filename,MAX_PATH); + DragFinish((HDROP)wParam); + if(LoadROM(filename)) execute = TRUE; + } + return 0; + case WM_KEYDOWN: + //if(wParam=='1'){PostMessage(hwnd, WM_DESTROY, 0, 0);return 0;} + + if(wParam==tabkey[ds_a]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFFFE; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFFFE; + return 0; } + if(wParam==tabkey[ds_b]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFFFD; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFFFD; + return 0; } + if(wParam==tabkey[ds_select]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFFFB; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFFFB; + return 0; } + if(wParam==tabkey[ds_start]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFFF7; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFFF7; + return 0; } + if(wParam==tabkey[ds_right]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFFEF; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFFEF; + return 0; } + if(wParam==tabkey[ds_left]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFFDF; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFFDF; + return 0; } + if(wParam==tabkey[ds_up]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFFBF; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFFBF; + return 0; } + if(wParam==tabkey[ds_down]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFF7F; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFF7F; + return 0; } + if(wParam==tabkey[ds_r]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFEFF; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFEFF; + return 0; } + if(wParam==tabkey[ds_l]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] &= 0xFDFF; + ((u16 *)MMU.ARM7_REG)[0x130>>1] &= 0xFDFF; + return 0; } + if(wParam==tabkey[ds_x]){ + ((u16 *)MMU.ARM7_REG)[0x136>>1] &= 0xFFFE; + return 0; } + if(wParam==tabkey[ds_y]){ + ((u16 *)MMU.ARM7_REG)[0x136>>1] &= 0xFFFD; + return 0; } + if(wParam==tabkey[ds_debug]){ + ((u16 *)MMU.ARM7_REG)[0x136>>1] &= 0xFFFB; + return 0; } + break; + /*case 0x1E : + MMU.ARM7_REG[0x136] &= 0xFE; + break; + case 0x1F : + MMU.ARM7_REG[0x136] &= 0xFD; + break; + case 0x21 : + NDS_ARM9.wIRQ = TRUE; + break; */ + case WM_KEYUP: + if(wParam==tabkey[ds_a]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x1; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x1; + return 0; } + if(wParam==tabkey[ds_b]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x2; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x2; + return 0; } + if(wParam==tabkey[ds_select]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x4; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x4; + return 0; } + if(wParam==tabkey[ds_start]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x8; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x8; + return 0; } + if(wParam==tabkey[ds_right]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x10; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x10; + return 0; } + if(wParam==tabkey[ds_left]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x20; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x20; + return 0; } + if(wParam==tabkey[ds_up]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x40; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x40; + return 0; } + if(wParam==tabkey[ds_down]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x80; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x80; + return 0; } + if(wParam==tabkey[ds_r]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x100; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x100; + return 0; } + if(wParam==tabkey[ds_l]){ + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] |= 0x200; + ((u16 *)MMU.ARM7_REG)[0x130>>1] |= 0x200; + return 0; } + if(wParam==tabkey[ds_x]){ + ((u16 *)MMU.ARM7_REG)[0x136>>1] |= 0x1; + return 0; } + if(wParam==tabkey[ds_y]){ + ((u16 *)MMU.ARM7_REG)[0x136>>1] |= 0x2; + return 0; } + if(wParam==tabkey[ds_debug]){ + ((u16 *)MMU.ARM7_REG)[0x136>>1] |= 0x4; + return 0; } + break; + + /*case 0x1E : + MMU.ARM7_REG[0x136] |= 1; + break; + case 0x1F : + MMU.ARM7_REG[0x136] |= 2; + break;*/ + /*case 0x21 : + MMU.REG_IME[0] = 1;*/ + case WM_MOUSEMOVE: + { + if (wParam & MK_LBUTTON) + { + s32 x = (s32)((s16)LOWORD(lParam)); + s32 y = (s32)((s16)HIWORD(lParam)) - 192; + if(x<0) x = 0; else if(x>255) x = 255; + if(y<0) y = 0; else if(y>192) y = 192; + NDS_setTouchPos(x, y); + return 0; + } + } + NDS_releasTouch(); + return 0; + case WM_LBUTTONDOWN: + if(HIWORD(lParam)>=192) + { + SetCapture(hwnd); + s32 x = LOWORD(lParam); + s32 y = HIWORD(lParam) - 192; + if(x<0) x = 0; else if(x>255) x = 255; + if(y<0) y = 0; else if(y>192) y = 192; + NDS_setTouchPos(x, y); + click = TRUE; + } + return 0; + case WM_LBUTTONUP: + if(click) + ReleaseCapture(); + NDS_releasTouch(); + return 0; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDM_OPEN: + { + OPENFILENAME ofn; + char filename[MAX_PATH] = ""; + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "Nds file (*.nds)\0*.nds\0Any file (*.*)\0*.*\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "nds"; + + if(!GetOpenFileName(&ofn)) + { + return 0; + } + + LOG("%s\r\n", filename); + + // Added for FAT generation + // Mic + if (ofn.nFileOffset>0) { + strncpy(szRomPath,filename,ofn.nFileOffset-1); + cflash_close(); + cflash_init(); + } + + strcpy(SavName,filename); + + romnum+=1; + + if(LoadROM(filename)) execute = FALSE; + } + return 0; + case IDM_PRINTSCREEN: + { + OPENFILENAME ofn; + char filename[MAX_PATH] = ""; + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "Bmp file (*.bmp)\0*.bmp\0Any file (*.*)\0*.*\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "bmp"; + ofn.Flags = OFN_OVERWRITEPROMPT; + GetSaveFileName(&ofn); + WriteBMP(filename,GPU_screen); + } + return 0; + case IDM_QUICK_PRINTSCREEN: + { + WriteBMP("./printscreen.bmp",GPU_screen); + } + return 0; + case IDM_STATE_LOAD: + { + execute = FALSE; + OPENFILENAME ofn; + //char nomFichier[MAX_PATH] = ""; + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "DeSmuME Savestate (*.dst)\0*.dst\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = SavName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "dst"; + + if(!GetOpenFileName(&ofn)) + { + return 0; + } + + //log::ajouter(SavName); + + savestate_load(SavName); + execute = TRUE; + } + return 0; + case IDM_STATE_SAVE: + { + execute = FALSE; + OPENFILENAME ofn; + //char nomFichier[MAX_PATH] = ""; + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "DeSmuME Savestate (*.dst)\0*.dst\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = SavName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "dst"; + + if(!GetSaveFileName(&ofn)) + { + return 0; + } + + //strncpy(SavName + "dst", FileName, strlen(FileName)-3); + //strcpy(SavName, SavName + "dst"); + //log = "sram saved to: "; + //strcat(log, (const char*)SavName); + //log::ajouter(log); + + //strncpy(SavName2, SavName, strlen(SavName)-3); + //strncat(SavName2, "dst", 3); + //strcpy(SavName, SavName + "dst"); + + savestate_save(SavName); + execute = TRUE; + } + return 0; + case IDM_GAME_INFO: + { + CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_GAME_INFO), hwnd, GinfoView_Proc); + } + return 0; + case IDM_PAL: + { + palview_struct *PalView; + + if ((PalView = PalView_Init(hAppInst, HWND_DESKTOP)) != NULL) + CWindow_Show(PalView); + } + return 0; + case IDM_TILE: + { + tileview_struct *TileView; + + if ((TileView = TileView_Init(hAppInst, HWND_DESKTOP)) != NULL) + CWindow_Show(TileView); + } + return 0; + case IDM_IOREG: + { + cwindow_struct IoregView; + + if (CWindow_Init2(&IoregView, hAppInst, HWND_DESKTOP, "IO REG VIEW", IDD_IO_REG, IoregView_Proc) == 0) + CWindow_Show(&IoregView); + } + return 0; + case IDM_QUIT: + PostMessage(hwnd, WM_QUIT, 0, 0); + return 0; + case IDM_MEMORY: + { + memview_struct *MemView; + + if ((MemView = MemView_Init(hAppInst, HWND_DESKTOP, "ARM7 memory viewer", 1)) != NULL) + CWindow_Show(MemView); + + if ((MemView = MemView_Init(hAppInst, HWND_DESKTOP, "ARM9 memory viewer", 0)) != NULL) + CWindow_Show(MemView); + } + return 0; + case IDM_DISASSEMBLER: + { + disview_struct *DisView; + + if ((DisView = DisView_Init(hAppInst, HWND_DESKTOP, "ARM7 Disassembler", &NDS_ARM7)) != NULL) + CWindow_Show(DisView); + + if ((DisView = DisView_Init(hAppInst, HWND_DESKTOP, "ARM9 Disassembler", &NDS_ARM9)) != NULL) + CWindow_Show(DisView); + } + return 0; + case IDM_MAP: + { + mapview_struct *MapView; + + if ((MapView = MapView_Init(hAppInst, HWND_DESKTOP)) != NULL) + { + CWindow_AddToRefreshList(MapView); + CWindow_Show(MapView); + } + } + return 0; + case IDM_OAM: + { + oamview_struct *OamView; + + if ((OamView = OamView_Init(hAppInst, HWND_DESKTOP)) != NULL) + { + CWindow_AddToRefreshList(OamView); + CWindow_Show(OamView); + } + } + return 0; + case IDM_MBG0 : + if(MainScreen.gpu->dispBG[0]) + { + GPU_remove(MainScreen.gpu, 0); + CheckMenuItem(menu, IDM_MBG0, MF_BYCOMMAND | MF_UNCHECKED); + } + else + { + GPU_addBack(MainScreen.gpu, 0); + CheckMenuItem(menu, IDM_MBG0, MF_BYCOMMAND | MF_CHECKED); + } + return 0; + case IDM_MBG1 : + if(MainScreen.gpu->dispBG[1]) + { + GPU_remove(MainScreen.gpu, 1); + CheckMenuItem(menu, IDM_MBG1, MF_BYCOMMAND | MF_UNCHECKED); + } + else + { + GPU_addBack(MainScreen.gpu, 1); + CheckMenuItem(menu, IDM_MBG1, MF_BYCOMMAND | MF_CHECKED); + } + return 0; + case IDM_MBG2 : + if(MainScreen.gpu->dispBG[2]) + { + GPU_remove(MainScreen.gpu, 2); + CheckMenuItem(menu, IDM_MBG2, MF_BYCOMMAND | MF_UNCHECKED); + } + else + { + GPU_addBack(MainScreen.gpu, 2); + CheckMenuItem(menu, IDM_MBG2, MF_BYCOMMAND | MF_CHECKED); + } + return 0; + case IDM_MBG3 : + if(MainScreen.gpu->dispBG[3]) + { + GPU_remove(MainScreen.gpu, 3); + CheckMenuItem(menu, IDM_MBG3, MF_BYCOMMAND | MF_UNCHECKED); + } + else + { + GPU_addBack(MainScreen.gpu, 3); + CheckMenuItem(menu, IDM_MBG3, MF_BYCOMMAND | MF_CHECKED); + } + return 0; + case IDM_SBG0 : + if(SubScreen.gpu->dispBG[0]) + { + GPU_remove(SubScreen.gpu, 0); + CheckMenuItem(menu, IDM_SBG0, MF_BYCOMMAND | MF_UNCHECKED); + } + else + { + GPU_addBack(SubScreen.gpu, 0); + CheckMenuItem(menu, IDM_SBG0, MF_BYCOMMAND | MF_CHECKED); + } + return 0; + case IDM_SBG1 : + if(SubScreen.gpu->dispBG[1]) + { + GPU_remove(SubScreen.gpu, 1); + CheckMenuItem(menu, IDM_SBG1, MF_BYCOMMAND | MF_UNCHECKED); + } + else + { + GPU_addBack(SubScreen.gpu, 1); + CheckMenuItem(menu, IDM_SBG1, MF_BYCOMMAND | MF_CHECKED); + } + return 0; + case IDM_SBG2 : + if(SubScreen.gpu->dispBG[2]) + { + GPU_remove(SubScreen.gpu, 2); + CheckMenuItem(menu, IDM_SBG2, MF_BYCOMMAND | MF_UNCHECKED); + } + else + { + GPU_addBack(SubScreen.gpu, 2); + CheckMenuItem(menu, IDM_SBG2, MF_BYCOMMAND | MF_CHECKED); + } + return 0; + case IDM_SBG3 : + if(SubScreen.gpu->dispBG[3]) + { + GPU_remove(SubScreen.gpu, 3); + CheckMenuItem(menu, IDM_SBG3, MF_BYCOMMAND | MF_UNCHECKED); + } + else + { + GPU_addBack(SubScreen.gpu, 3); + CheckMenuItem(menu, IDM_SBG3, MF_BYCOMMAND | MF_CHECKED); + } + return 0; + case IDM_EXEC: + execute = TRUE; + return 0; + case IDM_PAUSE: + execute = FALSE; + return 0; + case IDM_RESET: + return 0; + case IDM_CONFIG: + { + cwindow_struct ConfigView; + + if (CWindow_Init2(&ConfigView, hAppInst, HWND_DESKTOP, "Configure Controls", IDD_CONFIG, ConfigView_Proc) == 0) + CWindow_Show(&ConfigView); + + } + return 0; + } + return 0; + default: /* for messages that we don't deal with */ + return DefWindowProc (hwnd, message, wParam, lParam); + } + + NDSDeInit(); + + return 0; +} diff --git a/desmume/src/windows/mapView.c b/desmume/src/windows/mapView.c new file mode 100644 index 000000000..900bdec0f --- /dev/null +++ b/desmume/src/windows/mapView.c @@ -0,0 +1,223 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "mapview.h" +#include "resource.h" +#include "../MMU.h" +#include "../NDSSystem.h" + +#include + +////////////////////////////////////////////////////////////////////////////// + +LRESULT MapView_OnPaint(mapview_struct * win, HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + PAINTSTRUCT ps; + char text[80]; + u32 dispcnt = ((volatile u32 *)ARM9Mem.ARM9_REG)[(win->lcd*0x400)]; + u32 bgcnt = ((volatile u16 *)ARM9Mem.ARM9_REG)[(8 + (win->map<<1) + (win->lcd*0x1000))>>1]; + + + BITMAPV4HEADER bmi; + + //CreateBitmapIndirect(&bmi); + memset(&bmi, 0, sizeof(bmi)); + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB|BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + u16 lg; + u16 ht; + if(win->lcd) + { + lg = SubScreen.gpu->BGSize[win->map][0]; + ht = SubScreen.gpu->BGSize[win->map][1]; + } + else + { + lg = MainScreen.gpu->BGSize[win->map][0]; + ht = MainScreen.gpu->BGSize[win->map][1]; + } + bmi.bV4Width = lg; + bmi.bV4Height = -ht; + + hdc = BeginPaint(hwnd, &ps); + + sprintf(text, "%d %08X, %08X", (int)(dispcnt&7), (int)dispcnt, (int)bgcnt); + SetWindowText(GetDlgItem(hwnd, IDC_MODE), text); + + if(!(bgcnt&(1<<7))) + sprintf(text, "normale 16"); + else + if(!(dispcnt&(1<<30))) + sprintf(text, "normale 256"); + else + switch(win->map) + { + case 0 : + sprintf(text, "extended slot %d", (bgcnt&(1<<13))?2:0); + break; + case 1 : + sprintf(text, "extended slot %d", (bgcnt&(1<<13))?3:1); + break; + default : + sprintf(text, "extended slot %d", MainScreen.gpu->BGExtPalSlot[win->map]); + break; + } + SetWindowText(GetDlgItem(hwnd, IDC_PAL), text); + + sprintf(text, "%d", (int)(bgcnt&3)); + SetWindowText(GetDlgItem(hwnd, IDC_PRIO), text); + + sprintf(text, "0x%08X", (int)(0x6000000 + ((bgcnt>>2)&0xF)*0x4000 + win->lcd*0x200000 +((dispcnt>>24)&7)*0x10000)); + SetWindowText(GetDlgItem(hwnd, IDC_CHAR), text); + + sprintf(text, "0x%08X", (int)(0x6000000 + 0x800*((bgcnt>>8)&0x1F) + win->lcd*0x200000 + ((dispcnt>>27)&7)*0x10000)); + SetWindowText(GetDlgItem(hwnd, IDC_SCR), text); + + //sprintf(text, "%d x %d", MainScreen.gpu->BGPA[win->map], MainScreen.gpu->BGPB[win->map]); + sprintf(text, "%d x %d", (int)MainScreen.gpu->BGSize[win->map][0], (int)MainScreen.gpu->BGSize[win->map][1]); + SetWindowText(GetDlgItem(hwnd, IDC_MSIZE), text); + + sprintf(text, "%d x %d", MainScreen.gpu->BGPC[win->map], MainScreen.gpu->BGPD[win->map]); + SetWindowText(GetDlgItem(hwnd, IDC_SCROLL), text); + + if(win->lcd) + textBG(SubScreen.gpu, win->map, win->bitmap); + //rotBG(SubScreen.gpu, win->map, win->bitmap); + //extRotBG(SubScreen.gpu, win->map, win->bitmap); + else + textBG(MainScreen.gpu, win->map, win->bitmap); + //rotBG(MainScreen.gpu, win->map, win->bitmap); + //extRotBG(MainScreen.gpu, win->map, win->bitmap); + + SetDIBitsToDevice(hdc, 200, 4, lg, ht, 0, 0, 0, ht, win->bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + //SetDIBitsToDevice(hdc, 200, 4, 256, 192, 0, 0, 0, 192, win->bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + + EndPaint(hwnd, &ps); + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +BOOL CALLBACK MapView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + mapview_struct * win = (mapview_struct *)GetWindowLong(hwnd, DWL_USER); + switch (message) + { + case WM_INITDIALOG : + { + HWND combo = GetDlgItem(hwnd, IDC_BG_SELECT); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main BackGround 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main BackGround 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main BackGround 2"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main BackGround 3"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub BackGround 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub BackGround 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub BackGround 2"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub BackGround 3"); + SendMessage(combo, CB_SETCURSEL, 0, 0); + } + return 1; + case WM_CLOSE : + CWindow_RemoveFromRefreshList(win); + MapView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case WM_PAINT: + MapView_OnPaint(win, hwnd, wParam, lParam); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_FERMER : + CWindow_RemoveFromRefreshList(win); + MapView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case IDC_BG_SELECT : + switch(HIWORD(wParam)) + { + case CBN_CLOSEUP : + { + u32 sel= SendMessage(GetDlgItem(hwnd, IDC_BG_SELECT), CB_GETCURSEL, 0, 0); + switch(sel) + { + case 0 : + case 1 : + case 2 : + case 3 : + win->map = sel; + win->lcd = 0; + break; + case 4 : + case 5 : + case 6 : + case 7 : + win->map = sel-4; + win->lcd = 1; + break; + } + } + CWindow_Refresh(win); + return 1; + }//switch et case + }//switch + return 1; + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +mapview_struct *MapView_Init(HINSTANCE hInst, HWND parent) +{ + mapview_struct *MapView=NULL; + + if ((MapView = (mapview_struct *)malloc(sizeof(mapview_struct))) == NULL) + return MapView; + + if (CWindow_Init2(MapView, hInst, parent, "Map viewer", IDD_MAP, MapView_Proc) != 0) + { + free(MapView); + return NULL; + } + + MapView->map = 0; + MapView->lcd = 0; + + return MapView; +} + +////////////////////////////////////////////////////////////////////////////// + +void MapView_Deinit(mapview_struct *MapView) +{ + if (MapView) + free(MapView); +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/desmume/src/windows/mapView.h b/desmume/src/windows/mapView.h new file mode 100644 index 000000000..6151717c4 --- /dev/null +++ b/desmume/src/windows/mapView.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MAPVIEW_H +#define MAPVIEW_H + +#include +#include "CWindow.h" + +typedef struct +{ + HWND hwnd; + BOOL autoup; + void *prev; + void *next; + void *first; + void (*Refresh)(void *win); + + u16 map; + u16 lcd; + u16 bitmap[1024*1024]; +} mapview_struct; + +mapview_struct *MapView_Init(HINSTANCE hInst, HWND parent); +void MapView_Deinit(mapview_struct *MapView); + +#endif diff --git a/desmume/src/windows/memView.c b/desmume/src/windows/memView.c new file mode 100644 index 000000000..ef3d72ff7 --- /dev/null +++ b/desmume/src/windows/memView.c @@ -0,0 +1,570 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include "memView.h" +#include "../MMU.h" +#include "resource.h" + +LRESULT CALLBACK MemViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +void InitMemViewBox() +{ + WNDCLASSEX wc; + + wc.cbSize = sizeof(wc); + wc.lpszClassName = _T("MemViewBox"); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = MemViewBoxWndProc; + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hIcon = 0; + wc.lpszMenuName = 0; + wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE); + wc.style = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(cwindow_struct *); + wc.hIconSm = 0; + + RegisterClassEx(&wc); +} + +/* +LRESULT MemViewBox_OnPaint(CMemView * win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = GetDlgItem(win->hwnd, IDC_MEM_BOX); + HDC hdc; + PAINTSTRUCT ps; + SIZE fontsize; + TCHAR text[80]; + + RECT rect; + GetClientRect(hwnd, &rect); + int lg = rect.right - rect.left; + int ht = rect.bottom - rect.top; + + hdc = BeginPaint(hwnd, &ps); + + HDC mem_dc = CreateCompatibleDC(hdc); + HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, lg, ht); + SelectObject(mem_dc, mem_bmp); + + FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + SelectObject(mem_dc, GetStockObject(SYSTEM_FIXED_FONT)); + + GetTextExtentPoint32(mem_dc, "0", 1, &fontsize); + + int nbligne = ht/fontsize.cy; + + SetTextColor(mem_dc, RGB(0,0,0)); + + RECT r; + + r.top = 3; + r.left = 3; + r.bottom = r.top+fontsize.cy; + r.right = rect.right-3; + + u32 adr = win->curr_ligne*0x10; + + for(int i=0; i>16), (int)(adr&0xFFFF)); + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + r.left += 11*fontsize.cx; + int j; + + if(win->representation == 0) + for(j=0; j<16; ++j) + { + sprintf(text, "%02X", MMU_readByte(win->cpu, adr+j)); + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + r.left+=3*fontsize.cx; + } + else + if(win->representation == 1) + for(j=0; j<16; j+=2) + { + sprintf(text, "%04X", MMU_readHWord(win->cpu, adr+j)); + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + r.left+=5*fontsize.cx; + } + else + for(j=0; j<16; j+=4) + { + sprintf(text, "%08X", (int)MMU_readWord(win->cpu, adr+j)); + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + r.left+=9*fontsize.cx; + } + + r.left+=fontsize.cx; + + for(j=0; j<16; ++j) + { + u8 c = MMU_readByte(win->cpu, adr+j); + if(c >= 32 && c <= 127) { + text[j] = (char)c; + } + else + text[j] = '.'; + } + text[j] = '\0'; + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + + adr+=0x10; + r.top += fontsize.cy; + r.bottom += fontsize.cy; + r.left = 3; + } + + BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY); + + DeleteDC(mem_dc); + DeleteObject(mem_bmp); + + EndPaint(hwnd, &ps); + return 1; +} + +LRESULT CALLBACK MemViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CMemView * win = (CMemView *)GetWindowLong(hwnd, 0); + + switch(msg) + { + case WM_NCCREATE: + SetScrollRange(hwnd, SB_VERT, 0, 0x0FFFFFFF, TRUE); + SetScrollPos(hwnd, SB_VERT, 10, TRUE); + return 1; + + case WM_NCDESTROY: + return 1; + + case WM_PAINT: + MemViewBox_OnPaint(win, wParam, lParam); + return 1; + + case WM_ERASEBKGND: + return 1; + case WM_VSCROLL : + { + RECT rect; + SIZE fontsize; + GetClientRect(hwnd, &rect); + HDC dc = GetDC(hwnd); + HFONT old = (HFONT)SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT)); + GetTextExtentPoint32(dc, "0", 1, &fontsize); + + int nbligne = (rect.bottom - rect.top)/fontsize.cy; + + switch LOWORD(wParam) + { + case SB_LINEDOWN : + win->curr_ligne = min(0X0FFFFFFFF, win->curr_ligne+1); + break; + case SB_LINEUP : + win->curr_ligne = (u32)max(0, (s32)win->curr_ligne-1); + break; + case SB_PAGEDOWN : + win->curr_ligne = min(0X0FFFFFFFF, win->curr_ligne+nbligne); + break; + case SB_PAGEUP : + win->curr_ligne = (u32)max(0, (s32)win->curr_ligne-nbligne); + break; + } + + SelectObject(dc, old); + SetScrollPos(hwnd, SB_VERT, win->curr_ligne, TRUE); + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(hwnd); + } + return 1; + + default: + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + + +// MEM VIEWER +BOOL CALLBACK mem_view_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CMemView * win = (CMemView *)GetWindowLong(hwnd, DWL_USER); + switch (message) + { + case WM_INITDIALOG : + SendMessage(GetDlgItem(hwnd, IDC_8_BIT), BM_SETCHECK, TRUE, 0); + return 1; + case WM_CLOSE : + win->remove2RefreshList(); + delete win; + EndDialog(hwnd, 0); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_8_BIT : + win->representation = 0; + InvalidateRect(GetDlgItem(hwnd, IDC_MEM_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_MEM_BOX)); + return 1; + case IDC_16_BIT : + win->representation = 1; + InvalidateRect(GetDlgItem(hwnd, IDC_MEM_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_MEM_BOX)); + return 1; + case IDC_32_BIT : + win->representation = 2; + InvalidateRect(GetDlgItem(hwnd, IDC_MEM_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_MEM_BOX)); + return 1; + case IDC_AUTO_UPDATE : + if(win->autoup) + { + win->remove2RefreshList(); + win->autoup = FALSE; + return 1; + } + win->add2RefreshList(); + win->autoup = TRUE; + return 1; + case IDC_GO : + { + char tmp[8]; + int lg = GetDlgItemText(hwnd, IDC_GOTOMEM, tmp, 8); + u32 adr = 0; + for(u16 i = 0; i='A')&&(tmp[i]<='F')) + { + adr = adr*16 + (tmp[i]-'A'+10); + continue; + } + if((tmp[i]>='0')&&(tmp[i]<='9')) + { + adr = adr*16 + (tmp[i]-'0'); + continue; + } + } + win->curr_ligne = (adr>>4); + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(hwnd); + } + return 1; + case IDC_FERMER : + win->remove2RefreshList(); + delete win; + EndDialog(hwnd, 0); + return 1; + } + return 0; + } + return 0; +} + +CMemView::CMemView(HINSTANCE hInst, HWND parent, char * titre, u8 CPU) : + CWindow(hInst, parent, titre, IDD_MEM_VIEWER, mem_view_proc), cpu(CPU), curr_ligne(0), representation(0) +{ + SetWindowLong(GetDlgItem(hwnd, IDC_MEM_BOX), 0, (LONG)this); +} +*/ + +////////////////////////////////////////////////////////////////////////////// + +LRESULT MemViewBox_OnPaint(memview_struct * win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = GetDlgItem(win->hwnd, IDC_MEM_BOX); + HDC hdc; + PAINTSTRUCT ps; + SIZE fontsize; + TCHAR text[80]; + int i; + + RECT rect; + GetClientRect(hwnd, &rect); + int lg = rect.right - rect.left; + int ht = rect.bottom - rect.top; + + hdc = BeginPaint(hwnd, &ps); + + HDC mem_dc = CreateCompatibleDC(hdc); + HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, lg, ht); + SelectObject(mem_dc, mem_bmp); + + FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + SelectObject(mem_dc, GetStockObject(SYSTEM_FIXED_FONT)); + + GetTextExtentPoint32(mem_dc, "0", 1, &fontsize); + + int nbligne = ht/fontsize.cy; + + SetTextColor(mem_dc, RGB(0,0,0)); + + RECT r; + + r.top = 3; + r.left = 3; + r.bottom = r.top+fontsize.cy; + r.right = rect.right-3; + + u32 adr = win->curr_ligne*0x10; + + for(i=0; i>16), (int)(adr&0xFFFF)); + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + r.left += 11*fontsize.cx; + int j; + + if(win->representation == 0) + for(j=0; j<16; ++j) + { + sprintf(text, "%02X", MMU_readByte(win->cpu, adr+j)); + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + r.left+=3*fontsize.cx; + } + else + if(win->representation == 1) + for(j=0; j<16; j+=2) + { + sprintf(text, "%04X", MMU_readHWord(win->cpu, adr+j)); + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + r.left+=5*fontsize.cx; + } + else + for(j=0; j<16; j+=4) + { + sprintf(text, "%08X", (int)MMU_readWord(win->cpu, adr+j)); + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + r.left+=9*fontsize.cx; + } + + r.left+=fontsize.cx; + + for(j=0; j<16; ++j) + { + u8 c = MMU_readByte(win->cpu, adr+j); + if(c >= 32 && c <= 127) { + text[j] = (char)c; + } + else + text[j] = '.'; + } + text[j] = '\0'; + DrawText(mem_dc, text, -1, &r, DT_TOP | DT_LEFT | DT_NOPREFIX); + + adr+=0x10; + r.top += fontsize.cy; + r.bottom += fontsize.cy; + r.left = 3; + } + + BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY); + + DeleteDC(mem_dc); + DeleteObject(mem_bmp); + + EndPaint(hwnd, &ps); + return 1; +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK MemViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + memview_struct *win = (memview_struct *)GetWindowLong(hwnd, 0); + + switch(msg) + { + case WM_NCCREATE: + SetScrollRange(hwnd, SB_VERT, 0, 0x0FFFFFFF, TRUE); + SetScrollPos(hwnd, SB_VERT, 10, TRUE); + return 1; + + case WM_NCDESTROY: + return 1; + + case WM_PAINT: + MemViewBox_OnPaint(win, wParam, lParam); + return 1; + + case WM_ERASEBKGND: + return 1; + case WM_VSCROLL : + { + RECT rect; + SIZE fontsize; + GetClientRect(hwnd, &rect); + HDC dc = GetDC(hwnd); + HFONT old = (HFONT)SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT)); + GetTextExtentPoint32(dc, "0", 1, &fontsize); + + int nbligne = (rect.bottom - rect.top)/fontsize.cy; + + switch LOWORD(wParam) + { + case SB_LINEDOWN : + win->curr_ligne = min(0X0FFFFFFFF, win->curr_ligne+1); + break; + case SB_LINEUP : + win->curr_ligne = (u32)max(0, (s32)win->curr_ligne-1); + break; + case SB_PAGEDOWN : + win->curr_ligne = min(0X0FFFFFFFF, win->curr_ligne+nbligne); + break; + case SB_PAGEUP : + win->curr_ligne = (u32)max(0, (s32)win->curr_ligne-nbligne); + break; + } + + SelectObject(dc, old); + SetScrollPos(hwnd, SB_VERT, win->curr_ligne, TRUE); + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(hwnd); + } + return 1; + + default: + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +////////////////////////////////////////////////////////////////////////////// + +// MEM VIEWER +BOOL CALLBACK MemView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + memview_struct *win = (memview_struct *)GetWindowLong(hwnd, DWL_USER); + + switch (message) + { + case WM_INITDIALOG : + SendMessage(GetDlgItem(hwnd, IDC_8_BIT), BM_SETCHECK, TRUE, 0); + return 1; + case WM_CLOSE : + CWindow_RemoveFromRefreshList(win); + MemView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_8_BIT : + win->representation = 0; + InvalidateRect(GetDlgItem(hwnd, IDC_MEM_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_MEM_BOX)); + return 1; + case IDC_16_BIT : + win->representation = 1; + InvalidateRect(GetDlgItem(hwnd, IDC_MEM_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_MEM_BOX)); + return 1; + case IDC_32_BIT : + win->representation = 2; + InvalidateRect(GetDlgItem(hwnd, IDC_MEM_BOX), NULL, FALSE); + UpdateWindow(GetDlgItem(hwnd, IDC_MEM_BOX)); + return 1; + case IDC_AUTO_UPDATE : + if(win->autoup) + { + CWindow_RemoveFromRefreshList(win); + win->autoup = FALSE; + return 1; + } + CWindow_AddToRefreshList(win); + win->autoup = TRUE; + return 1; + case IDC_GO : + { + char tmp[8]; + int lg = GetDlgItemText(hwnd, IDC_GOTOMEM, tmp, 8); + u32 adr = 0; + u16 i; + + for(i = 0; i='A')&&(tmp[i]<='F')) + { + adr = adr*16 + (tmp[i]-'A'+10); + continue; + } + if((tmp[i]>='0')&&(tmp[i]<='9')) + { + adr = adr*16 + (tmp[i]-'0'); + continue; + } + } + win->curr_ligne = (adr>>4); + InvalidateRect(hwnd, NULL, FALSE); + UpdateWindow(hwnd); + } + return 1; + case IDC_FERMER : + CWindow_RemoveFromRefreshList(win); + MemView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + } + return 0; + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +memview_struct *MemView_Init(HINSTANCE hInst, HWND parent, char *title, u8 CPU) +{ + memview_struct *MemView = NULL; + + if ((MemView = (memview_struct *)malloc(sizeof(memview_struct))) == NULL) + return MemView; + + if (CWindow_Init2(MemView, hInst, parent, title, IDD_MEM_VIEWER, MemView_Proc) != 0) + { + free(MemView); + return NULL; + } + + MemView->cpu = CPU; + MemView->curr_ligne = 0; + MemView->representation = 0; + + SetWindowLong(GetDlgItem(MemView->hwnd, IDC_MEM_BOX), 0, (LONG)MemView); + + return MemView; +} + +////////////////////////////////////////////////////////////////////////////// + +void MemView_Deinit(memview_struct *MemView) +{ + if (MemView) + free(MemView); +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/desmume/src/windows/memView.h b/desmume/src/windows/memView.h new file mode 100644 index 000000000..a464755e0 --- /dev/null +++ b/desmume/src/windows/memView.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MEM_VIEW_H +#define MEM_VIEW_H + +#include "CWindow.h" + +/* +class CMemView : public CWindow +{ +public : + CMemView(HINSTANCE hInst, HWND parent, char * titre, u8 CPU); + + s8 cpu; + u32 curr_ligne; + u8 representation; +}; +*/ + +typedef struct +{ + HWND hwnd; + BOOL autoup; + void *prev; + void *next; + void *first; + void (*Refresh)(void *win); + + s8 cpu; + u32 curr_ligne; + u8 representation; +} memview_struct; + +void InitMemViewBox(); +memview_struct *MemView_Init(HINSTANCE hInst, HWND parent, char *title, u8 CPU); +void MemView_Deinit(memview_struct *MemView); + +#endif diff --git a/desmume/src/windows/oamView.c b/desmume/src/windows/oamView.c new file mode 100644 index 000000000..e409d95fd --- /dev/null +++ b/desmume/src/windows/oamView.c @@ -0,0 +1,334 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "resource.h" +#include "oamView.h" +#include "../arm9/GPU.h" + +#include "../MMU.h" + +#include "../NDSSystem.h" + +extern NDSSystem nds; + +const char dimm[4][4][8] = +{ + {"8 x 8", "16 x 8", "8 x 16", "- x -"}, + {"16 x 16", "32 x 8", "8 x 32", "- x -"}, + {"32 x 32", "32 x 16", "16 x 32", "- x -"}, + {"64 x 64", "64 x 32", "32 x 64", "- x -"}, +}; + +////////////////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK OAMViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +void InitOAMViewBox() +{ + WNDCLASSEX wc; + + wc.cbSize = sizeof(wc); + wc.lpszClassName = _T("OAMViewBox"); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = OAMViewBoxWndProc; + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hIcon = 0; + wc.lpszMenuName = 0; + wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE); + wc.style = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(cwindow_struct *); + wc.hIconSm = 0; + + RegisterClassEx(&wc); +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT OAMViewBox_OnPaint(oamview_struct * win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = GetDlgItem(win->hwnd, IDC_OAM_BOX); + HDC hdc; + PAINTSTRUCT ps; +// TCHAR text[80]; + + RECT rect; + GetClientRect(hwnd, &rect); + int lg = rect.right - rect.left; + int ht = rect.bottom - rect.top; + + hdc = BeginPaint(hwnd, &ps); + + HDC mem_dc = CreateCompatibleDC(hdc); + HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, lg, ht); + SelectObject(mem_dc, mem_bmp); + + FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY); + + DeleteDC(mem_dc); + DeleteObject(mem_bmp); + + EndPaint(hwnd, &ps); + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK OAMViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ +// oamView * win = (oamView *)GetWindowLong(hwnd, 0); + + switch(msg) + { + case WM_NCCREATE: + return 1; + case WM_NCDESTROY: + return 1; + /*case WM_PAINT: + OAMViewBox_OnPaint(win, wParam, lParam); + return 1;*/ + case WM_ERASEBKGND: + return 1; + default: + break; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT OamView_OnPaint(oamview_struct *win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = win->hwnd; + HDC hdc; + PAINTSTRUCT ps; + OAM * oam = &win->oam[win->num]; + char text[80]; + u16 bitmap[256*192]; + u8 prio[256*192]; + BITMAPV4HEADER bmi; + u16 i; + + //CreateBitmapIndirect(&bmi); + memset(&bmi, 0, sizeof(bmi)); + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB|BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + bmi.bV4Width = 256; + bmi.bV4Height = -192; + + for(i = 0; i < 256*192; ++i) + { + bitmap[i] = 0x7F0F; + prio[i] = 4; + } + + hdc = BeginPaint(hwnd, &ps); + + sprintf(text, "OAM : %d", win->num); + SetWindowText(GetDlgItem(hwnd, IDC_OAMNUM), text); + + switch(oam->attr0&(3<<10)) + { + case 0 : + SetWindowText(GetDlgItem(hwnd, IDC_MODE), "Normal"); + break; + case (1<<10) : + SetWindowText(GetDlgItem(hwnd, IDC_MODE), "Smi-transp"); + break; + case (2<<10) : + SetWindowText(GetDlgItem(hwnd, IDC_MODE), "OBJ Window"); + break; + case (3<<10) : + SetWindowText(GetDlgItem(hwnd, IDC_MODE), "Bitmap"); + } + + sprintf(text, "0x%08X", oam->attr0/*oam->attr2&0x3FF*/); + SetWindowText(GetDlgItem(hwnd, IDC_TILE), text); + + sprintf(text, "0x%08X", oam->attr1/*oam->attr2&0x3FF*/); + SetWindowText(GetDlgItem(hwnd, IDC_PAL), text); + + //SetWindowText(GetDlgItem(hwnd, IDC_PAL), (oam->attr0&(1<<13))?"256 couleurs": "16 couleurs"); + + sprintf(text, "%d 0x%08X", (oam->attr2>>10)&3, oam->attr2); + SetWindowText(GetDlgItem(hwnd, IDC_PRIO), text); + + signed short x = oam->attr1&0x1FF; + x = ((signed short)(x<<7)>>7); + sprintf(text, "%d x %d", x, oam->attr0&0xFF); + SetWindowText(GetDlgItem(hwnd, IDC_COOR), text); + + SetWindowText(GetDlgItem(hwnd, IDC_DIM), dimm[oam->attr1>>14][oam->attr0>>14]); + + SetWindowText(GetDlgItem(hwnd, IDC_ROT), oam->attr0&(1<<8)?"ON" : "OFF"); + + SetWindowText(GetDlgItem(hwnd, IDC_MOS), oam->attr0&(1<<12)?"ON" : "OFF"); + + if(oam->attr0&(1<<8)) + { + sprintf(text, "Rot param : %d", (oam->attr1>>9)&0x1F); + SetWindowText(GetDlgItem(hwnd, IDC_PROP0), text); + + SetWindowText(GetDlgItem(hwnd, IDC_PROP1), (oam->attr0&(1<<9))?"Double size": ""); + } + else + { + if(oam->attr0&(1<<9)) + sprintf(text, "INVISIBLE"); + else + sprintf(text, "%s %s", oam->attr0&(1<<12)?"H FLIP":"", oam->attr0&(1<<12)?"V FLIP":""); + + SetWindowText(GetDlgItem(hwnd, IDC_PROP0), text); + + SetWindowText(GetDlgItem(hwnd, IDC_PROP1), ""); + } + + for(i = 0; i < 192; ++i) + { + win->gpu->spriteRender(win->gpu, i, bitmap + i*256, prio + i*256); + } + + SetDIBitsToDevice(hdc, 180, 4, 256, 192, 0, 0, 0, 192, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + + EndPaint(hwnd, &ps); + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +BOOL CALLBACK OamView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + oamview_struct *win = (oamview_struct *)GetWindowLong(hwnd, DWL_USER); + switch (message) + { + case WM_INITDIALOG : + { + HWND combo = GetDlgItem(hwnd, IDC_SCR_SELECT); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen sprite"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen sprite"); + SendMessage(combo, CB_SETCURSEL, 0, 0); + } + return 1; + case WM_CLOSE : + CWindow_RemoveFromRefreshList(win); + OamView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case WM_PAINT: + OamView_OnPaint(win, wParam, lParam); + return 1; + case WM_HSCROLL : + switch LOWORD(wParam) + { + case SB_LINERIGHT : + ++(win->num); + if(win->num>127) + win->num = 127; + break; + case SB_LINELEFT : + --(win->num); + if(win->num<0) + win->num = 0; + break; + } + CWindow_Refresh(win); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_FERMER : + CWindow_RemoveFromRefreshList(win); + OamView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case IDC_SCR_SELECT : + switch(HIWORD(wParam)) + { + case CBN_CLOSEUP : + { + u32 sel = SendMessage(GetDlgItem(hwnd, IDC_SCR_SELECT), CB_GETCURSEL, 0, 0); + switch(sel) + { + case 0 : + win->oam = (OAM *)ARM9Mem.ARM9_OAM; + win->num = 0; + win->gpu = MainScreen.gpu; + break; + case 1 : + win->oam = (OAM *)(ARM9Mem.ARM9_OAM+0x400); + win->num = 0; + win->gpu = SubScreen.gpu; + break; + } + } + CWindow_Refresh(win); + return 1; + } + return 1; + } + return 0; + } + return 0; +} + + +////////////////////////////////////////////////////////////////////////////// + +oamview_struct *OamView_Init(HINSTANCE hInst, HWND parent) +{ + oamview_struct *OamView=NULL; + + if ((OamView = (oamview_struct *)malloc(sizeof(oamview_struct))) == NULL) + return OamView; + + if (CWindow_Init2(OamView, hInst, parent, "OAM Viewer", IDD_OAM, OamView_Proc) != 0) + { + free(OamView); + return NULL; + } + + OamView->oam = (OAM *)(ARM9Mem.ARM9_OAM); + OamView->num = 0; + OamView->gpu = MainScreen.gpu; + + return OamView; +} + +////////////////////////////////////////////////////////////////////////////// + +void OamView_Deinit(oamview_struct *OamView) +{ + if (OamView) + free(OamView); +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/desmume/src/windows/oamView.h b/desmume/src/windows/oamView.h new file mode 100644 index 000000000..5a2b2868f --- /dev/null +++ b/desmume/src/windows/oamView.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef OAMVIEW_H +#define OAMVIEW_H + +#include "CWindow.h" +#include "../arm9/GPU.h" + +typedef struct +{ + HWND hwnd; + BOOL autoup; + void *prev; + void *next; + void *first; + void (*Refresh)(void *win); + + s16 num; + OAM *oam; + GPU *gpu; +} oamview_struct; + +extern void InitOAMViewBox(); +oamview_struct *OamView_Init(HINSTANCE hInst, HWND parent); +void OamView_Deinit(oamview_struct *OamView); + +#endif diff --git a/desmume/src/windows/palView.c b/desmume/src/windows/palView.c new file mode 100644 index 000000000..c7133c934 --- /dev/null +++ b/desmume/src/windows/palView.c @@ -0,0 +1,272 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "resource.h" +#include "palView.h" +#include "../MMU.h" +#include + +////////////////////////////////////////////////////////////////////////////// + +LRESULT PalView_OnPaint(u16 * adr, u16 num, HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + PAINTSTRUCT ps; + RECT rect; + HBRUSH brush; + u16 c; + char tmp[80]; + + rect.left = 3; + rect.top = 55; + rect.right = 13; + rect.bottom = 65; + hdc = BeginPaint(hwnd, &ps); + + if(adr) + { + u32 y; + + for(y = 0; y < 16; ++y) + { + u32 x; + + for(x = 0; x < 16; ++x) + { + c = adr[(y<<4)+x+0x100*num]; + brush = CreateSolidBrush(RGB((c&0x1F)<<3, (c&0x3E0)>>2, (c&0x7C00)>>7)); + FillRect(hdc, &rect, brush); + DeleteObject(brush); + rect.left += 11; + rect.right += 11; + } + rect.top += 11; + rect.bottom += 11; + rect.left = 3; + rect.right = 13; + } + sprintf(tmp, "Pal : %d", num); + SetWindowText(GetDlgItem(hwnd, IDC_PALNUM), tmp); + } + else + TextOut(hdc, 3, 55, "Pas de palette", 14); + EndPaint(hwnd, &ps); + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +BOOL CALLBACK PalView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + //ATTENTION null Ela creation donc la boite ne doit pas être visible a la création + palview_struct *win = (palview_struct *)GetWindowLong(hwnd, DWL_USER); + + switch (message) + { + case WM_INITDIALOG : + { + HWND combo = GetDlgItem(hwnd, IDC_PAL_SELECT); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen BG PAL"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen BG PAL"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen SPR PAL"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen SPR PAL"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen ExtPAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen ExtPAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen ExtPAL 2"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen ExtPAL 3"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen ExtPAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen ExtPAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen ExtPAL 2"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen ExtPAL 3"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main spr ExtPAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main spr ExtPAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub spr ExtPAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub spr ExtPAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Texture pal 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Texture pal 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Texture pal 2"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Texture pal 3"); + SendMessage(combo, CB_SETCURSEL, 0, 0); + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_HIDE); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), FALSE); + } + return 1; + case WM_CLOSE : + CWindow_RemoveFromRefreshList(win); + PalView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case WM_PAINT: + PalView_OnPaint(win->adr, win->palnum, hwnd, wParam, lParam); + return 1; + case WM_HSCROLL : + switch LOWORD(wParam) + { + case SB_LINERIGHT : + ++(win->palnum); + if(win->palnum>15) + win->palnum = 15; + break; + case SB_LINELEFT : + --(win->palnum); + if(win->palnum<0) + win->palnum = 0; + break; + } + CWindow_Refresh(win); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_FERMER : + CWindow_RemoveFromRefreshList(win); + PalView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case IDC_AUTO_UPDATE : + if(win->autoup) + { + CWindow_RemoveFromRefreshList(win); + win->autoup = FALSE; + return 1; + } + CWindow_AddToRefreshList(win); + win->autoup = TRUE; + return 1; + case IDC_PAL_SELECT : + switch(HIWORD(wParam)) + { + case CBN_CLOSEUP : + { + u32 sel = SendMessage(GetDlgItem(hwnd, IDC_PAL_SELECT), CB_GETCURSEL, 0, 0); + switch(sel) + { + case 0 : + win->adr = (u16 *)ARM9Mem.ARM9_VMEM; + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_HIDE); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), FALSE); + break; + case 1 : + win->adr = ((u16 *)ARM9Mem.ARM9_VMEM) + 0x200; + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_HIDE); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), FALSE); + break; + case 2 : + win->adr = (u16 *)ARM9Mem.ARM9_VMEM + 0x100; + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_HIDE); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), FALSE); + break; + case 3 : + win->adr = ((u16 *)ARM9Mem.ARM9_VMEM) + 0x300; + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_HIDE); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), FALSE); + break; + case 4 : + case 5 : + case 6 : + case 7 : + win->adr = ((u16 *)(ARM9Mem.ExtPal[0][sel-4])); + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), TRUE); + break; + case 8 : + case 9 : + case 10 : + case 11 : + win->adr = ((u16 *)(ARM9Mem.ExtPal[1][sel-8])); + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), TRUE); + break; + case 12 : + case 13 : + win->adr = ((u16 *)(ARM9Mem.ObjExtPal[0][sel-12])); + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), TRUE); + break; + case 14 : + case 15 : + win->adr = ((u16 *)(ARM9Mem.ObjExtPal[1][sel-14])); + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), TRUE); + break; + case 16 : + case 17 : + case 18 : + case 19 : + win->adr = ((u16 *)(ARM9Mem.texPalSlot[sel-16])); + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), TRUE); + break; + default : + return 1; + } + CWindow_Refresh(win); + return 1; + } + } + return 1; + } + return 0; + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +palview_struct *PalView_Init(HINSTANCE hInst, HWND parent) +{ + palview_struct *PalView=NULL; + + if ((PalView = (palview_struct *)malloc(sizeof(palview_struct))) == NULL) + return PalView; + + if (CWindow_Init2(PalView, hInst, parent, "Palette viewer", IDD_PAL, PalView_Proc) != 0) + { + free(PalView); + return NULL; + } + + PalView->palnum = 0; + PalView->adr = (u16 *)ARM9Mem.ARM9_VMEM; + + return PalView; +} + +////////////////////////////////////////////////////////////////////////////// + +void PalView_Deinit(palview_struct *PalView) +{ + if (PalView) + free(PalView); +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/desmume/src/windows/palView.h b/desmume/src/windows/palView.h new file mode 100644 index 000000000..a0a3c4fea --- /dev/null +++ b/desmume/src/windows/palView.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef PALVIEW_H +#define PALVIEW_H + +#include "CWindow.h" + +typedef struct +{ + HWND hwnd; + BOOL autoup; + void *prev; + void *next; + void *first; + void (*Refresh)(void *win); + + u16 *adr; + s16 palnum; +} palview_struct; + +//BOOL CALLBACK palView_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +palview_struct *PalView_Init(HINSTANCE hInst, HWND parent); +void PalView_Deinit(palview_struct *PalView); + +#endif + diff --git a/desmume/src/windows/tileView.c b/desmume/src/windows/tileView.c new file mode 100644 index 000000000..34c5d86c1 --- /dev/null +++ b/desmume/src/windows/tileView.c @@ -0,0 +1,655 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include "tileView.h" +#include "resource.h" +#include "../MMU.h" + +LRESULT CALLBACK TileViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK MiniTileViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +////////////////////////////////////////////////////////////////////////////// + +void InitTileViewBox() +{ + WNDCLASSEX wc; + + wc.cbSize = sizeof(wc); + wc.lpszClassName = _T("TileViewBox"); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = TileViewBoxWndProc; + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hIcon = 0; + wc.lpszMenuName = 0; + wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE); + wc.style = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(cwindow_struct *); + wc.hIconSm = 0; + + RegisterClassEx(&wc); + + wc.cbSize = sizeof(wc); + wc.lpszClassName = _T("MiniTileViewBox"); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = MiniTileViewBoxWndProc; + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hIcon = 0; + wc.lpszMenuName = 0; + wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE); + wc.style = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(cwindow_struct *); + wc.hIconSm = 0; + + RegisterClassEx(&wc); +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT MiniTileViewBox_Paint(tileview_struct * win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd_dst = GetDlgItem(win->hwnd, IDC_MINI_TILE); + HWND hwnd_src = GetDlgItem(win->hwnd, IDC_Tile_BOX); + HDC hdc_src; + HDC hdc_dst; + char txt[80]; + + PAINTSTRUCT ps; + + hdc_dst = BeginPaint(hwnd_dst, &ps); + hdc_src = GetDC(hwnd_src); + StretchBlt(hdc_dst, 0, 0, 80, 80, hdc_src, win->x, win->y, 8, 8, SRCCOPY); + sprintf(txt, "Tile num : 0x%X", win->tilenum); + SetWindowText(GetDlgItem(win->hwnd, IDC_TILENUM), txt); + EndPaint(hwnd_dst, &ps); + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK MiniTileViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + tileview_struct * win = (tileview_struct *)GetWindowLong(hwnd, 0); + + switch(msg) + { + case WM_NCCREATE: + return 1; + case WM_NCDESTROY: + return 1; + case WM_PAINT : + MiniTileViewBox_Paint(win, wParam, lParam); + return 1; + case WM_ERASEBKGND: + return 1; + default: + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT TileViewBox_Direct(tileview_struct * win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = GetDlgItem(win->hwnd, IDC_Tile_BOX); + HDC hdc; + PAINTSTRUCT ps; +// SIZE fontsize; +// TCHAR text[80]; + BITMAPV4HEADER bmi; + + memset(&bmi, 0, sizeof(bmi)); + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB|BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + bmi.bV4Width = 256; + bmi.bV4Height = -256; + + RECT rect; + GetClientRect(hwnd, &rect); + int lg = rect.right - rect.left; + int ht = rect.bottom - rect.top; + + hdc = BeginPaint(hwnd, &ps); + + HDC mem_dc = CreateCompatibleDC(hdc); + HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, lg, ht); + SelectObject(mem_dc, mem_bmp); + + FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + SetDIBitsToDevice(mem_dc, 0, 0, 256, 256, 0, 0, 0, 256, win->mem, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + + BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY); + + DeleteDC(mem_dc); + DeleteObject(mem_bmp); + + EndPaint(hwnd, &ps); + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT TileViewBox_Pal256(tileview_struct * win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = GetDlgItem(win->hwnd, IDC_Tile_BOX); + HDC hdc; + PAINTSTRUCT ps; +// SIZE fontsize; + TCHAR text[80]; + u16 bitmap[256*256]; + u16 * pal = ((u16 *)win->pal) + win->palnum*256; + BITMAPV4HEADER bmi; + memset(&bmi, 0, sizeof(bmi)); + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB|BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + bmi.bV4Width = 256; + bmi.bV4Height = -256; + + RECT rect; + GetClientRect(hwnd, &rect); + int lg = rect.right - rect.left; + int ht = rect.bottom - rect.top; + + hdc = BeginPaint(hwnd, &ps); + + HDC mem_dc = CreateCompatibleDC(hdc); + HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, lg, ht); + SelectObject(mem_dc, mem_bmp); + + FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + if(win->pal) + { + u32 i, num2, num, y, x; + + //for(i = 0; i<256*256; ++i) + // bitmap[i] = pal[win->mem[i]]; + for(num2 = 0; num2<32; ++num2) + for(num = 0; num<32; ++num) + for(y = 0; y<8; ++y) + for(x = 0; x<8; ++x) + bitmap[x + (y*256) + (num*8) +(num2*256*8)] = pal[win->mem[x + (y*8) + (num*64) +(num2*2048)]]; + SetDIBitsToDevice(mem_dc, 0, 0, 256, 256, 0, 0, 0, 256, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + sprintf(text, "Pal : %d", win->palnum); + SetWindowText(GetDlgItem(win->hwnd, IDC_PALNUM), text); + } + else + TextOut(mem_dc, 3, 3, "Il n'y a pas de palette", 23); + + BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY); + + DeleteDC(mem_dc); + DeleteObject(mem_bmp); + + EndPaint(hwnd, &ps); + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT TileViewBox_Pal16(tileview_struct * win, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd = GetDlgItem(win->hwnd, IDC_Tile_BOX); + HDC hdc; + PAINTSTRUCT ps; +// SIZE fontsize; + TCHAR text[80]; + u16 bitmap[512*512]; + u16 * pal = ((u16 *)win->pal) + win->palnum*16; + BITMAPV4HEADER bmi; + memset(&bmi, 0, sizeof(bmi)); + bmi.bV4Size = sizeof(bmi); + bmi.bV4Planes = 1; + bmi.bV4BitCount = 16; + bmi.bV4V4Compression = BI_RGB|BI_BITFIELDS; + bmi.bV4RedMask = 0x001F; + bmi.bV4GreenMask = 0x03E0; + bmi.bV4BlueMask = 0x7C00; + bmi.bV4Width = 512; + bmi.bV4Height = -256; + + RECT rect; + GetClientRect(hwnd, &rect); + int lg = rect.right - rect.left; + int ht = rect.bottom - rect.top; + + hdc = BeginPaint(hwnd, &ps); + + HDC mem_dc = CreateCompatibleDC(hdc); + HBITMAP mem_bmp = CreateCompatibleBitmap(hdc, 512, 256); + SelectObject(mem_dc, mem_bmp); + + FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + if(win->pal) + { + u32 num2, num, y, x; + for(num2 = 0; num2<32; ++num2) + for(num = 0; num<64; ++num) + for(y = 0; y<8; ++y) + for(x = 0; x<4; ++x) + { + bitmap[(x<<1) + (y*512) + (num*8) +(num2*512*8)] = pal[win->mem[x + (y*4) + (num*32) +(num2*2048)]&0xF]; + bitmap[(x<<1)+1 + (y*512) + (num*8) +(num2*512*8)] = pal[win->mem[x + (y*4) + (num*32) +(num2*2048)]>>4]; + } + SetDIBitsToDevice(mem_dc, 0, 0, 512, 256, 0, 0, 0, 256, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS); + sprintf(text, "Pal : %d", win->palnum); + SetWindowText(GetDlgItem(win->hwnd, IDC_PALNUM), text); + } + else + TextOut(mem_dc, 3, 3, "Il n'y a pas de palette", 23); + + BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY); + + DeleteDC(mem_dc); + DeleteObject(mem_bmp); + + EndPaint(hwnd, &ps); + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK TileViewBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + tileview_struct * win = (tileview_struct *)GetWindowLong(hwnd, 0); + + switch(msg) + { + case WM_NCCREATE: + return 1; + case WM_NCDESTROY: + return 1; + case WM_PAINT: + switch(win->coul) + { + case 0 : + TileViewBox_Direct(win, wParam, lParam); + return 1; + case 1 : + TileViewBox_Pal256(win, wParam, lParam); + return 1; + case 2 : + TileViewBox_Pal16(win, wParam, lParam); + return 1; + } + return 1; + case WM_LBUTTONDOWN : + switch(win->coul) + { + case 0 : + case 1 : + if(LOWORD(lParam)<(32*8)) + { + win->x = ((LOWORD(lParam)>>3)<<3); + win->y = (HIWORD(lParam)>>3)<<3; + win->tilenum = (LOWORD(lParam)>>3) + (HIWORD(lParam)>>3)*32; + } + break; + case 2 : + win->x = ((LOWORD(lParam)>>3)<<3); + win->y = (HIWORD(lParam)>>3)<<3; + win->tilenum = (LOWORD(lParam)>>3) + (HIWORD(lParam)>>3)*64; + break; + } + InvalidateRect(GetDlgItem(win->hwnd, IDC_MINI_TILE), NULL, FALSE); + UpdateWindow(GetDlgItem(win->hwnd, IDC_MINI_TILE)); + //CWindow_Refresh(win); + return 1; + case WM_ERASEBKGND: + return 1; + default: + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +////////////////////////////////////////////////////////////////////////////// + +BOOL CALLBACK TileView_Proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + tileview_struct * win = (tileview_struct *)GetWindowLong(hwnd, DWL_USER); + switch (message) + { + case WM_INITDIALOG : + { + HWND combo = GetDlgItem(hwnd, IDC_PAL_SELECT); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen BG PAL"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen BG PAL"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen SPR PAL"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen SPR PAL"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen ExtPAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen ExtPAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen ExtPAL 2"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main screen ExtPAL 3"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen ExtPAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen ExtPAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen ExtPAL 2"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub screen ExtPAL 3"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main spr ExtPAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Main spr ExtPAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub spr ExtPAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Sub spr ExtPAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Texture PAL 0"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Texture PAL 1"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Texture PAL 2"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"Texture PAL 3"); + SendMessage(combo, CB_SETCURSEL, 0, 0); + + combo = GetDlgItem(hwnd, IDC_MEM_SELECT); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-BG - 0x6000000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-BG - 0x6010000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-BG - 0x6020000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-BG - 0x6030000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-BG - 0x6040000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-BG - 0x6050000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-BG - 0x6060000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-BG - 0x6070000"); + + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"B-BG - 0x6200000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"B-BG - 0x6210000"); + + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-OBJ- 0x6400000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-OBJ- 0x6410000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-OBJ- 0x6420000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"A-OBJ- 0x6430000"); + + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"B-OBJ- 0x6600000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"B-OBJ- 0x6610000"); + + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6800000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6810000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6820000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6830000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6840000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6850000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6860000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6870000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6880000"); + SendMessage(combo, CB_ADDSTRING, 0,(LPARAM)"LCD - 0x6890000"); + SendMessage(combo, CB_SETCURSEL, 0, 0); + SendMessage(GetDlgItem(hwnd, IDC_BITMAP), BM_SETCHECK, TRUE, 0); + } + return 1; + case WM_CLOSE : + CWindow_RemoveFromRefreshList(win); + TileView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case WM_HSCROLL : + switch LOWORD(wParam) + { + case SB_LINERIGHT : + ++(win->palnum); + if(win->palnum>15) + win->palnum = 15; + break; + case SB_LINELEFT : + --(win->palnum); + if(win->palnum<0) + win->palnum = 0; + break; + } + CWindow_Refresh(win); + return 1; + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDC_FERMER : + CWindow_RemoveFromRefreshList(win); + TileView_Deinit(win); + EndDialog(hwnd, 0); + return 1; + case IDC_AUTO_UPDATE : + if(win->autoup) + { + CWindow_RemoveFromRefreshList(win); + win->autoup = FALSE; + return 1; + } + CWindow_AddToRefreshList(win); + win->autoup = TRUE; + return 1; + case IDC_BITMAP : + win->coul = 0; + CWindow_Refresh(win); + return 1; + case IDC_256COUL : + win->coul = 1; + CWindow_Refresh(win); + return 1; + case IDC_16COUL : + win->coul = 2; + CWindow_Refresh(win); + return 1; + case IDC_MEM_SELECT : + switch(HIWORD(wParam)) + { + case CBN_CLOSEUP : + { + u32 sel = SendMessage(GetDlgItem(hwnd, IDC_MEM_SELECT), CB_GETCURSEL, 0, 0); + switch(sel) + { + case 0 : + case 1 : + case 2 : + case 3 : + case 4 : + case 5 : + case 6 : + case 7 : + win->mem = ARM9Mem.ARM9_ABG + 0x10000*sel; + break; + case 8 : + case 9 : + win->mem = ARM9Mem.ARM9_BBG + 0x10000*(sel-8); + break; + case 10 : + case 11 : + case 12 : + case 13 : + win->mem = ARM9Mem.ARM9_AOBJ + 0x10000*(sel-10); + break; + case 14 : + case 15 : + win->mem = ARM9Mem.ARM9_BOBJ + 0x10000*(sel-14); + break; + case 16 : + case 17 : + case 18 : + case 19 : + case 20 : + case 21 : + case 22 : + case 23 : + case 24 : + case 25 : + win->mem = ARM9Mem.ARM9_LCD + 0x10000*(sel-16); + break; + default : + return 1; + } + CWindow_Refresh(win); + return 1; + } + } + return 1; + case IDC_PAL_SELECT : + switch(HIWORD(wParam)) + { + case CBN_CLOSEUP : + { + u32 sel = SendMessage(GetDlgItem(hwnd, IDC_PAL_SELECT), CB_GETCURSEL, 0, 0); + switch(sel) + { + case 0 : + win->pal = (u16 *)ARM9Mem.ARM9_VMEM; + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_16COUL), TRUE); + break; + case 1 : + win->pal = ((u16 *)ARM9Mem.ARM9_VMEM) + 0x200; + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_16COUL), TRUE); + break; + case 2 : + win->pal = (u16 *)ARM9Mem.ARM9_VMEM + 0x100; + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_16COUL), TRUE); + break; + case 3 : + win->pal = ((u16 *)ARM9Mem.ARM9_VMEM) + 0x300; + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_16COUL), TRUE); + break; + case 4 : + case 5 : + case 6 : + case 7 : + win->pal = ((u16 *)(ARM9Mem.ExtPal[0][sel-4])); + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_HIDE); + EnableWindow(GetDlgItem(hwnd, IDC_16COUL), FALSE); + if(win->coul == 2) + { + SendMessage(GetDlgItem(hwnd, IDC_256COUL), BM_SETCHECK, TRUE, 0); + SendMessage(GetDlgItem(hwnd, IDC_16COUL), BM_SETCHECK, FALSE, 0); + win->coul = 1; + } + break; + case 8 : + case 9 : + case 10 : + case 11 : + win->pal = ((u16 *)(ARM9Mem.ExtPal[1][sel-8])); + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_HIDE); + EnableWindow(GetDlgItem(hwnd, IDC_16COUL), FALSE); + if(win->coul == 2) + { + SendMessage(GetDlgItem(hwnd, IDC_256COUL), BM_SETCHECK, TRUE, 0); + SendMessage(GetDlgItem(hwnd, IDC_16COUL), BM_SETCHECK, FALSE, 0); + win->coul = 1; + } + break; + case 12 : + case 13 : + win->pal = ((u16 *)(ARM9Mem.ObjExtPal[0][sel-12])); + win->palnum = 0; + if(win->coul == 2) + { + SendMessage(GetDlgItem(hwnd, IDC_256COUL), BM_SETCHECK, TRUE, 0); + SendMessage(GetDlgItem(hwnd, IDC_16COUL), BM_SETCHECK, FALSE, 0); + win->coul = 1; + } + break; + case 14 : + case 15 : + win->pal = ((u16 *)(ARM9Mem.ObjExtPal[1][sel-14])); + win->palnum = 0; + if(win->coul == 2) + { + SendMessage(GetDlgItem(hwnd, IDC_256COUL), BM_SETCHECK, TRUE, 0); + SendMessage(GetDlgItem(hwnd, IDC_16COUL), BM_SETCHECK, FALSE, 0); + win->coul = 1; + } + break; + case 16 : + case 17 : + case 18 : + case 19 : + win->pal = ((u16 *)(ARM9Mem.texPalSlot[sel-16])); + win->palnum = 0; + ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_SHOW); + EnableWindow(GetDlgItem(hwnd, IDC_16COUL), TRUE); + break; + default : + return 1; + } + CWindow_Refresh(win); + return 1; + } + } + } + return 0; + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + +tileview_struct *TileView_Init(HINSTANCE hInst, HWND parent) +{ + tileview_struct *TileView=NULL; + + if ((TileView = (tileview_struct *)malloc(sizeof(tileview_struct))) == NULL) + return TileView; + + if (CWindow_Init2(TileView, hInst, parent, "Tile viewer", IDD_TILE, TileView_Proc) != 0) + { + free(TileView); + return NULL; + } + + TileView->mem = ARM9Mem.ARM9_ABG; + TileView->pal = ((u16 *)ARM9Mem.ARM9_VMEM); + TileView->palnum = 0; + TileView->coul = 0; + TileView->x = 0; + TileView->y = 0; + + SetWindowLong(GetDlgItem(TileView->hwnd, IDC_Tile_BOX), 0, (LONG)TileView); + SetWindowLong(GetDlgItem(TileView->hwnd, IDC_MINI_TILE), 0, (LONG)TileView); + + return TileView; +} + +////////////////////////////////////////////////////////////////////////////// + +void TileView_Deinit(tileview_struct *TileView) +{ + if (TileView) + free(TileView); +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/desmume/src/windows/tileView.h b/desmume/src/windows/tileView.h new file mode 100644 index 000000000..b3deaa95b --- /dev/null +++ b/desmume/src/windows/tileView.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef TILEVIEW_H +#define TILEVIEW_H + +#include "CWindow.h" + +typedef struct +{ + HWND hwnd; + BOOL autoup; + void *prev; + void *next; + void *first; + void (*Refresh)(void *win); + + u8 * mem; + u16 * pal; + s16 palnum; + u16 tilenum; + u8 coul; + u32 x; + u32 y; +} tileview_struct; + + +void InitTileViewBox(); +tileview_struct *TileView_Init(HINSTANCE hInst, HWND parent); +void TileView_Deinit(tileview_struct *TileView); + +#endif diff --git a/desmume/src/windows/yopyop_private.h b/desmume/src/windows/yopyop_private.h new file mode 100644 index 000000000..190988a5a --- /dev/null +++ b/desmume/src/windows/yopyop_private.h @@ -0,0 +1,23 @@ +/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */ +/* DO NOT EDIT ! */ + +#ifndef YOPYOP_PRIVATE_H +#define YOPYOP_PRIVATE_H + +/* VERSION DEFINITIONS */ +#define VER_STRING "0.0.0.1" +#define VER_MAJOR 0 +#define VER_MINOR 0 +#define VER_RELEASE 0 +#define VER_BUILD 1 +#define COMPANY_NAME "yopyop" +#define FILE_VERSION "" +#define FILE_DESCRIPTION "NDS(tm) emulator" +#define INTERNAL_NAME "" +#define LEGAL_COPYRIGHT "" +#define LEGAL_TRADEMARKS "" +#define ORIGINAL_FILENAME "" +#define PRODUCT_NAME "DeSmuME" +#define PRODUCT_VERSION "" + +#endif /*YOPYOP_PRIVATE_H*/