/* Hey EMACS -*- linux-c -*- */ /* $Id$ */ /* TiEmu - an TI emulator * * Copyright (c) 2000-2001, Thomas Corvazier, Romain Lievin * Copyright (c) 2001-2003, Romain Lievin * Copyright (c) 2003, Julien Blache * Copyright (c) 2004, Romain Liévin * Copyright (c) 2005, Romain Liévin, Kevin Kofler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* Registers access/manipulation */ #ifdef HAVE_CONFIG_H # include #endif #include #include "libuae.h" #include "ti68k_int.h" #include "ti68k_def.h" #include "bits.h" /* Flushes GDB's register cache */ extern void registers_changed(void); /* Flushes GDB's frame cache */ extern void reinit_frame_cache(void); /* Refreshes Insight */ extern void gdbtk_update(void); // SR bits set/get modifiers #define SR_get_T(sr) bit_get(sr, 15) #define SR_get_S(sr) bit_get(sr, 13) #define SR_get_I(sr) (((sr) >> 8) & 7) #define SR_get_X(sr) bit_get(sr, 4) #define SR_get_N(sr) bit_get(sr, 3) #define SR_get_Z(sr) bit_get(sr, 2) #define SR_get_V(sr) bit_get(sr, 1) #define SR_get_C(sr) bit_get(sr, 0) #define SR_chg_T(sr, s) bit_chg(sr, 15, s); #define SR_chg_S(sr, s) bit_chg(sr, 13, s) #define SR_chg_I(sr, v) { sr &= ~(7 << 8); sr |= (v << 8); } #define SR_chg_X(sr, s) bit_chg(sr, 4, s) #define SR_chg_N(sr, s) bit_chg(sr, 3, s) #define SR_chg_Z(sr, s) bit_chg(sr, 2, s) #define SR_chg_V(sr, s) bit_chg(sr, 1, s) #define SR_chg_C(sr, s) bit_chg(sr, 0, s) // Previous state to detect change static uint32_t old_d[8]; static uint32_t old_a[8]; static uint32_t old_sp, old_usp, old_ssp; static uint32_t old_pc; static uint16_t old_sr; static char old_sf[32]; static char old_uf[32]; void ti68k_register_set_data(int n, uint32_t val) { if (n>=0 && n<8) m68k_dreg(regs,n) = val; #ifndef NO_GDB registers_changed (); gdbtk_update(); #endif } void ti68k_register_set_addr(int n, uint32_t val) { if (n>=0 && n<8) m68k_areg(regs,n) = val; #ifndef NO_GDB registers_changed (); gdbtk_update(); #endif } void ti68k_register_set_sp(uint32_t val) { m68k_areg(regs,7) = val; #ifndef NO_GDB registers_changed (); reinit_frame_cache (); gdbtk_update(); #endif } void ti68k_register_set_usp(uint32_t val) { if(!regs.s) m68k_areg(regs,7) = val; else regs.usp = val; #ifndef NO_GDB registers_changed (); reinit_frame_cache (); gdbtk_update(); #endif } void ti68k_register_set_ssp(uint32_t val) { if(regs.s) m68k_areg(regs,7) = val; else regs.isp = val; #ifndef NO_GDB registers_changed (); reinit_frame_cache (); gdbtk_update(); #endif } void ti68k_register_set_pc(uint32_t val) { m68k_setpc(val); fill_prefetch_slow (); /* Force reloading the prefetch. */ #ifndef NO_GDB registers_changed (); reinit_frame_cache (); gdbtk_update(); #endif } void ti68k_register_set_sr(uint32_t val) { regs.sr = (int)val; MakeFromSR(); #ifndef NO_GDB registers_changed (); gdbtk_update(); #endif } void ti68k_register_set_flag(uint8_t flag) { //TODO /* T 0 S 0 0 I2 I1 I0 0 0 0 X N Z V C */ #ifndef NO_GDB registers_changed (); gdbtk_update(); #endif } int ti68k_register_set_flags(const char *sf, const char *uf) { /* SR: T 0 S 0 0 I2 I1 I0 0 0 0 X N Z V C */ int t, s, i, x, n, z, v, c; int nargs; MakeSR(); if(sf != NULL) { nargs = sscanf(sf, "T=%d S=%d I=%d", &t, &s, &i); if(nargs < 3) return 0; if((i < 0) || (i > 7)) return 0; SR_chg_T(regs.sr, 1); SR_chg_T(regs.sr, t); SR_chg_S(regs.sr, s); SR_chg_I(regs.sr, i); } if(uf != NULL) { nargs = sscanf(uf, "X=%d N=%d \nZ=%d V=%d C=%d", &x, &n, &z, &v, &c); if(nargs < 5) return 0; SR_chg_X(regs.sr, x); SR_chg_N(regs.sr, n); SR_chg_Z(regs.sr, z); SR_chg_V(regs.sr, v); SR_chg_C(regs.sr, c); } MakeFromSR(); #ifndef NO_GDB registers_changed (); gdbtk_update(); #endif return !0; } int ti68k_register_get_data(int n, uint32_t *val) { int c = 0; if (n>=0 && n<8) *val = m68k_dreg(regs,n); if(m68k_dreg(regs,n) != old_d[n]) c = !0; old_d[n] = m68k_dreg(regs,n); return c; } int ti68k_register_get_addr(int n, uint32_t *val) { int c = 0; if (n>=0 && n<8) *val = m68k_areg(regs,n); if(m68k_areg(regs,n) != old_a[n]) c = !0; old_a[n] = m68k_areg(regs,n); return c; } int ti68k_register_get_sp(uint32_t *val) { int c = 0; *val = m68k_areg(regs,7); if(m68k_areg(regs,7) != old_sp) c = !0; old_sp = m68k_areg(regs,7); return c; } int ti68k_register_get_usp(uint32_t *val) { int c = 0; uae_u32 *reg; if(!regs.s) reg = &m68k_areg(regs,7); else reg = ®s.usp; *val = *reg; if(*reg != old_usp) c = !0; old_usp = *reg; return c; } int ti68k_register_get_ssp(uint32_t *val) { int c = 0; uae_u32 *reg; if(regs.s) reg = &m68k_areg(regs,7); else reg = ®s.isp; *val = *reg; if(*reg != old_ssp) c = !0; old_ssp = *reg; return c; } int ti68k_register_get_pc(uint32_t *val) { int c = 0; *val = m68k_getpc(); if(*val != old_pc) c = !0; old_pc = regs.pc; return c; } int ti68k_register_get_sr(uint32_t *val) { int c =0; MakeSR(); *val = regs.sr; if(regs.sr != old_sr) c = !0; old_sr = regs.sr; return c; } const char *ti68k_register_get_flag(void) { static char str[64]; /* T 0 S 0 0 I2 I1 I0 0 0 0 X N Z V C */ MakeSR(); printf("T=%d S=%d I=%d | X=%d N=%d\nZ=%d V=%d C=%d\n", SR_get_T(regs.sr), SR_get_S(regs.sr), SR_get_I(regs.sr), SR_get_X(regs.sr), SR_get_N(regs.sr), SR_get_Z(regs.sr), SR_get_V(regs.sr), SR_get_C(regs.sr) ); return str; } int ti68k_register_get_flags(char *sf, char *uf) { int c =0; /* SR: T 0 S 0 0 I2 I1 I0 0 0 0 X N Z V C */ MakeSR(); sprintf(sf, "T=%d S=%d I=%d", SR_get_T(regs.sr), SR_get_S(regs.sr), SR_get_I(regs.sr)); sprintf(uf, "X=%d N=%d \nZ=%d V=%d C=%d", /* %dSPC\n: SPC is important ! */ SR_get_X(regs.sr), SR_get_N(regs.sr), SR_get_Z(regs.sr), SR_get_V(regs.sr), SR_get_C(regs.sr)); if(strcmp(sf, old_sf) || strcmp(uf, old_uf)) c = !0; strcpy(old_sf, sf); strcpy(old_uf, uf); return c; } int ti68k_debug_is_supervisor(void) { return regs.s; }