/* Copyright (c) 2013-2014 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef ARM_H #define ARM_H #include "common.h" CXX_GUARD_START // #include enum { ARM_SP = 13, ARM_LR = 14, ARM_PC = 15 }; enum PrivilegeMode { MODE_USER = 0x10, MODE_FIQ = 0x11, MODE_IRQ = 0x12, MODE_SUPERVISOR = 0x13, MODE_ABORT = 0x17, MODE_UNDEFINED = 0x1B, MODE_SYSTEM = 0x1F }; enum ExecutionVector { BASE_RESET = 0x00000000, BASE_UNDEF = 0x00000004, BASE_SWI = 0x00000008, BASE_PABT = 0x0000000C, BASE_DABT = 0x00000010, BASE_IRQ = 0x00000018, BASE_FIQ = 0x0000001C }; enum RegisterBank { BANK_NONE = 0, BANK_FIQ = 1, BANK_IRQ = 2, BANK_SUPERVISOR = 3, BANK_ABORT = 4, BANK_UNDEFINED = 5 }; enum LSMDirection { LSM_B = 1, LSM_D = 2, LSM_IA = 0, LSM_IB = 1, LSM_DA = 2, LSM_DB = 3 }; struct ARMCore; union PSR { struct { #if defined(__POWERPC__) || defined(__PPC__) unsigned n : 1; unsigned z : 1; unsigned c : 1; unsigned v : 1; unsigned unused : 20; unsigned i : 1; unsigned f : 1; unsigned t : 1; unsigned priv : 5; #else unsigned priv : 5; unsigned t : 1; unsigned f : 1; unsigned i : 1; unsigned unused : 20; unsigned v : 1; unsigned c : 1; unsigned z : 1; unsigned n : 1; #endif }; struct { #if defined(__BIG_ENDIAN__) uint8_t flags; uint8_t status; uint8_t extension; uint8_t control; #else uint8_t control; uint8_t extension; uint8_t status; uint8_t flags; #endif }; int32_t packed; }; struct ARMMemory { uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter); uint32_t (*load16)(struct ARMCore*, uint32_t address, int* cycleCounter); uint32_t (*load8)(struct ARMCore*, uint32_t address, int* cycleCounter); void (*store32)(struct ARMCore*, uint32_t address, int32_t value, int* cycleCounter); void (*store16)(struct ARMCore*, uint32_t address, int16_t value, int* cycleCounter); void (*store8)(struct ARMCore*, uint32_t address, int8_t value, int* cycleCounter); uint32_t (*loadMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction, int* cycleCounter); uint32_t (*storeMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction, int* cycleCounter); uint32_t activeSeqCycles32; // uint32_t activeSeqCycles16; uint32_t activeNonseqCycles32; // uint32_t activeNonseqCycles16; int32_t (*stall)(struct ARMCore*, int32_t wait); }; struct ARMInterruptHandler { void (*reset)(struct ARMCore* cpu); void (*processEvents)(struct ARMCore* cpu); // void (*swi16)(struct ARMCore* cpu, int immediate); void (*swi32)(struct ARMCore* cpu, int immediate); void (*hitIllegal)(struct ARMCore* cpu, uint32_t opcode); // void (*bkpt16)(struct ARMCore* cpu, int immediate); void (*bkpt32)(struct ARMCore* cpu, int immediate); void (*readCPSR)(struct ARMCore* cpu); void (*hitStub)(struct ARMCore* cpu, uint32_t opcode); }; struct ARMCore { int32_t gprs[16]; union PSR cpsr; union PSR spsr; int64_t cycles; int64_t nextEvent; int halted; int32_t bankedRegisters[6][7]; int32_t bankedSPSRs[6]; int32_t shifterOperand; int32_t shifterCarryOut; uint32_t prefetch[2]; enum PrivilegeMode privilegeMode; struct ARMMemory memory; struct ARMInterruptHandler irqh; void *owner; }; void ARMReset(struct ARMCore* cpu); void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode); void ARMRaiseIRQ(struct ARMCore*); void ARMRaiseFIQ(struct ARMCore*); void ARMRaiseSWI(struct ARMCore*); void ARMRaiseUndefined(struct ARMCore*); void ARMRun(struct ARMCore* cpu); void ARMRunLoop(struct ARMCore* cpu); void ARMRunFake(struct ARMCore* cpu, uint32_t opcode); CXX_GUARD_END #endif