1bb16d227Schristos /* int.c --- M32C interrupt handling. 2bb16d227Schristos 3*8b657b07Schristos Copyright (C) 2005-2023 Free Software Foundation, Inc. 4bb16d227Schristos Contributed by Red Hat, Inc. 5bb16d227Schristos 6bb16d227Schristos This file is part of the GNU simulators. 7bb16d227Schristos 8bb16d227Schristos This program is free software; you can redistribute it and/or modify 9bb16d227Schristos it under the terms of the GNU General Public License as published by 10bb16d227Schristos the Free Software Foundation; either version 3 of the License, or 11bb16d227Schristos (at your option) any later version. 12bb16d227Schristos 13bb16d227Schristos This program is distributed in the hope that it will be useful, 14bb16d227Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 15bb16d227Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16bb16d227Schristos GNU General Public License for more details. 17bb16d227Schristos 18bb16d227Schristos You should have received a copy of the GNU General Public License 19bb16d227Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20bb16d227Schristos 21*8b657b07Schristos /* This must come before any other includes. */ 22*8b657b07Schristos #include "defs.h" 23bb16d227Schristos 24bb16d227Schristos #include "int.h" 25bb16d227Schristos #include "cpu.h" 26bb16d227Schristos #include "mem.h" 27bb16d227Schristos 28bb16d227Schristos static void 29bb16d227Schristos trigger_interrupt (int addr, int clear_u) 30bb16d227Schristos { 31bb16d227Schristos int s = get_reg (sp); 32bb16d227Schristos int f = get_reg (flags); 33bb16d227Schristos int p = get_reg (pc); 34bb16d227Schristos 35bb16d227Schristos if (clear_u) 36bb16d227Schristos set_flags (FLAGBIT_U, 0); 37bb16d227Schristos set_flags (FLAGBIT_I | FLAGBIT_D, 0); 38bb16d227Schristos 39bb16d227Schristos if (A16) 40bb16d227Schristos { 41bb16d227Schristos s -= 4; 42bb16d227Schristos put_reg (sp, s); 43bb16d227Schristos mem_put_hi (s, p); 44bb16d227Schristos mem_put_qi (s + 2, f); 45bb16d227Schristos mem_put_qi (s + 3, ((f >> 4) & 0x0f) | (p >> 16)); 46bb16d227Schristos } 47bb16d227Schristos else 48bb16d227Schristos { 49bb16d227Schristos s -= 6; 50bb16d227Schristos put_reg (sp, s); 51bb16d227Schristos mem_put_si (s, p); 52bb16d227Schristos mem_put_hi (s + 4, f); 53bb16d227Schristos } 54bb16d227Schristos put_reg (pc, mem_get_psi (addr)); 55bb16d227Schristos } 56bb16d227Schristos 57bb16d227Schristos void 58bb16d227Schristos trigger_fixed_interrupt (int addr) 59bb16d227Schristos { 60bb16d227Schristos trigger_interrupt (addr, 1); 61bb16d227Schristos } 62bb16d227Schristos 63bb16d227Schristos void 64bb16d227Schristos trigger_based_interrupt (int vector) 65bb16d227Schristos { 66bb16d227Schristos int addr = get_reg (intb) + vector * 4; 67bb16d227Schristos trigger_interrupt (addr, vector <= 31); 68bb16d227Schristos } 69bb16d227Schristos 70bb16d227Schristos void 71bb16d227Schristos trigger_peripheral_interrupt (int vector, int icaddr) 72bb16d227Schristos { 73bb16d227Schristos unsigned char old_ic = mem_get_qi (icaddr); 74bb16d227Schristos int addr = get_reg (intb) + vector * 4; 75bb16d227Schristos trigger_interrupt (addr, 1); 76bb16d227Schristos put_reg (flags, (get_reg (flags) & 0x8fff) | ((old_ic & 7) << 12)); 77bb16d227Schristos mem_put_qi (icaddr, old_ic & ~ 0x08); 78bb16d227Schristos } 79