Annotation of hatari/src/uae-cpu/newcpu.h, revision 1.1.1.18

1.1       root        1:  /*
1.1.1.2   root        2:   * UAE - The Un*x Amiga Emulator - CPU core
1.1.1.6   root        3:   *
1.1       root        4:   * MC68000 emulation
                      5:   *
                      6:   * Copyright 1995 Bernd Schmidt
1.1.1.2   root        7:   *
                      8:   * Adaptation to Hatari by Thomas Huth
                      9:   *
1.1.1.14  root       10:   * This file is distributed under the GNU General Public License, version 2
                     11:   * or at your option any later version. Read the file gpl.txt for details.
1.1       root       12:   */
                     13: 
1.1.1.4   root       14: #ifndef UAE_NEWCPU_H
                     15: #define UAE_NEWCPU_H
1.1       root       16: 
                     17: #include "readcpu.h"
                     18: #include "m68k.h"
1.1.1.10  root       19: #include "memory.h"
1.1       root       20: 
                     21: 
1.1.1.11  root       22: /* Possible exceptions sources for M68000_Exception() and Exception() */
1.1.1.13  root       23: #define M68000_EXC_SRC_CPU         1  /* Direct CPU exception */
                     24: #define M68000_EXC_SRC_AUTOVEC  2  /* Auto-vector exception (e.g. VBL) */
                     25: #define M68000_EXC_SRC_INT_MFP 3  /* MFP interrupt exception */
                     26: #define M68000_EXC_SRC_INT_DSP  4  /* DSP interrupt exception */
1.1.1.11  root       27: 
                     28: 
1.1.1.7   root       29: /* Special flags */
1.1.1.12  root       30: #define SPCFLAG_DEBUGGER 1
1.1       root       31: #define SPCFLAG_STOP 2
1.1.1.6   root       32: #define SPCFLAG_BUSERROR 4
1.1       root       33: #define SPCFLAG_INT 8
1.1.1.6   root       34: #define SPCFLAG_BRK 0x10
                     35: #define SPCFLAG_EXTRA_CYCLES 0x20
                     36: #define SPCFLAG_TRACE 0x40
                     37: #define SPCFLAG_DOTRACE 0x80
                     38: #define SPCFLAG_DOINT 0x100
1.1.1.7   root       39: #define SPCFLAG_MFP 0x200
1.1.1.6   root       40: #define SPCFLAG_EXEC 0x400
                     41: #define SPCFLAG_MODE_CHANGE 0x800
1.1.1.14  root       42: #define SPCFLAG_DSP 0x1000
1.1       root       43: 
1.1.1.7   root       44: 
1.1       root       45: #ifndef SET_CFLG
                     46: 
                     47: #define SET_CFLG(x) (CFLG = (x))
                     48: #define SET_NFLG(x) (NFLG = (x))
                     49: #define SET_VFLG(x) (VFLG = (x))
                     50: #define SET_ZFLG(x) (ZFLG = (x))
                     51: #define SET_XFLG(x) (XFLG = (x))
                     52: 
                     53: #define GET_CFLG CFLG
                     54: #define GET_NFLG NFLG
                     55: #define GET_VFLG VFLG
                     56: #define GET_ZFLG ZFLG
                     57: #define GET_XFLG XFLG
                     58: 
                     59: #define CLEAR_CZNV do { \
                     60:  SET_CFLG (0); \
                     61:  SET_ZFLG (0); \
                     62:  SET_NFLG (0); \
                     63:  SET_VFLG (0); \
                     64: } while (0)
                     65: 
                     66: #define COPY_CARRY (SET_XFLG (GET_CFLG))
                     67: #endif
                     68: 
1.1.1.9   root       69: extern const int areg_byteinc[];
                     70: extern const int imm8_table[];
1.1       root       71: 
                     72: extern int movem_index1[256];
                     73: extern int movem_index2[256];
                     74: extern int movem_next[256];
                     75: 
                     76: extern int fpp_movem_index1[256];
                     77: extern int fpp_movem_index2[256];
                     78: extern int fpp_movem_next[256];
                     79: 
                     80: 
                     81: typedef unsigned long cpuop_func (uae_u32) REGPARAM;
                     82: 
                     83: struct cputbl {
                     84:     cpuop_func *handler;
                     85:     int specific;
                     86:     uae_u16 opcode;
                     87: };
                     88: 
                     89: extern unsigned long op_illg (uae_u32) REGPARAM;
                     90: 
                     91: typedef char flagtype;
                     92: 
1.1.1.5   root       93: /* You can set this to long double to be more accurate. However, the
                     94:    resulting alignment issues will cost a lot of performance in some
                     95:    apps */
                     96: #define USE_LONG_DOUBLE 0
                     97: 
                     98: #if USE_LONG_DOUBLE
                     99: typedef long double fptype;
                    100: #else
                    101: typedef double fptype;
                    102: #endif
                    103: 
1.1       root      104: extern struct regstruct
                    105: {
                    106:     uae_u32 regs[16];
                    107:     uaecptr  usp,isp,msp;
                    108:     uae_u16 sr;
                    109:     flagtype t1;
                    110:     flagtype t0;
                    111:     flagtype s;
                    112:     flagtype m;
                    113:     flagtype x;
                    114:     flagtype stopped;
                    115:     int intmask;
                    116: 
                    117:     uae_u32 pc;
                    118:     uae_u8 *pc_p;
                    119:     uae_u8 *pc_oldp;
1.1.1.16  root      120:     uae_u16 opcode;
                    121:     uae_u32 instruction_pc;
1.1       root      122: 
                    123:     uae_u32 vbr,sfc,dfc;
1.1.1.18! root      124:     uae_u32 caar, cacr;
1.1       root      125: 
1.1.1.5   root      126:     fptype fp[8];
                    127:     fptype fp_result;
                    128: 
1.1       root      129:     uae_u32 fpcr,fpsr,fpiar;
1.1.1.5   root      130:     uae_u32 fpsr_highbyte;
1.1       root      131: 
                    132:     uae_u32 spcflags;
                    133: 
1.1.1.5   root      134:     uae_u32 prefetch_pc;
1.1       root      135:     uae_u32 prefetch;
                    136: } regs, lastint_regs;
                    137: 
                    138: STATIC_INLINE void set_special (uae_u32 x)
                    139: {
                    140:     regs.spcflags |= x;
                    141: }
                    142: 
                    143: STATIC_INLINE void unset_special (uae_u32 x)
                    144: {
                    145:     regs.spcflags &= ~x;
                    146: }
                    147: 
                    148: #define m68k_dreg(r,num) ((r).regs[(num)])
                    149: #define m68k_areg(r,num) (((r).regs + 8)[(num)])
                    150: 
1.1.1.6   root      151: 
1.1.1.5   root      152: STATIC_INLINE void m68k_setpc (uaecptr newpc)
                    153: {
                    154:     regs.pc_p = regs.pc_oldp = get_real_address (newpc);
                    155:     regs.pc = newpc;
                    156: }
                    157: 
                    158: STATIC_INLINE uaecptr m68k_getpc (void)
                    159: {
                    160:     return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
                    161: }
                    162: 
                    163: STATIC_INLINE uaecptr m68k_getpc_p (uae_u8 *p)
                    164: {
                    165:     return regs.pc + ((char *)p - (char *)regs.pc_oldp);
                    166: }
                    167: 
1.1.1.18! root      168: #define M68K_GETPC m68k_getpc()
        !           169: 
1.1.1.8   root      170: #define get_ibyte(o) do_get_mem_byte(regs.pc_p + (o) + 1)
                    171: #define get_iword(o) do_get_mem_word(regs.pc_p + (o))
                    172: #define get_ilong(o) do_get_mem_long(regs.pc_p + (o))
1.1       root      173: 
1.1.1.5   root      174: STATIC_INLINE void refill_prefetch (uae_u32 currpc, uae_u32 offs)
1.1       root      175: {
1.1.1.6   root      176:     uae_u32 t = (currpc + offs) & ~1;
1.1.1.5   root      177:     uae_u32 r;
1.1.1.17  root      178: 
                    179: //fprintf ( stderr , "refill pc %x o %d old %x\n" , currpc,offs,regs.prefetch_pc );
1.1.1.5   root      180: #ifdef UNALIGNED_PROFITABLE
1.1.1.15  root      181:     if ( t - regs.prefetch_pc == 2 )                           /* keep 1 word and read 1 new word */
                    182:     {
                    183:         r = regs.prefetch;
                    184:         r <<= 16;
                    185:         r |= get_word (t+2);
                    186:     }
                    187:     else
                    188:     {
                    189:        /* [NP] FIXME : when we refill with 4 bytes, we should not read one long */
                    190:        /* but 2 words, else some bus errors are not detected if the address overlaps */
                    191:        /* on a bus error region (eg : get_long(t=213ffffe) doesn't give a bus error, */
                    192:        /* but it should. This should be better handled in memory.c */
                    193: //        r = get_long (t);                                    /* read 2 new words */
                    194:         r = get_word (t);
                    195:         r <<= 16;
                    196:         r |= get_word (t+2);
                    197:     }
1.1.1.5   root      198:     regs.prefetch = r;
                    199: #else
1.1.1.15  root      200:     if ( t - regs.prefetch_pc == 2 )                           /* keep 1 word and read 1 new word */
                    201:     {
                    202:         r = do_get_mem_word (((uae_u8 *)&regs.prefetch) + 2);
                    203:         r <<= 16;
                    204:         r |= get_word (t+2);
                    205:     }
                    206:     else
                    207:     {
                    208:        /* [NP] FIXME : when we refill with 4 bytes, we should not read one long */
                    209:        /* but 2 words, else some bus errors are not detected if the address overlaps */
                    210:        /* on a bus error region (eg : get_long(t=213ffffe) doesn't give a bus error, */
                    211:        /* but it should. This should be better handled in memory.c */
                    212: //        r = get_long (t);                                    /* read 2 new words */
                    213:         r = get_word (t);
                    214:         r <<= 16;
                    215:         r |= get_word (t+2);
                    216:     }
1.1.1.5   root      217:     do_put_mem_long (&regs.prefetch, r);
                    218: #endif
1.1.1.15  root      219: //fprintf (stderr,"PC %x PREFPC %x T %x R %x\n", currpc, regs.prefetch_pc, t, r);
1.1.1.5   root      220:     regs.prefetch_pc = t;
                    221: }
1.1       root      222: 
1.1.1.5   root      223: STATIC_INLINE uae_u32 get_ibyte_prefetch (uae_s32 o)
                    224: {
                    225:     uae_u32 currpc = m68k_getpc ();
                    226:     uae_u32 addr = currpc + o + 1;
                    227:     uae_u32 offs = addr - regs.prefetch_pc;
                    228:     uae_u32 v;
                    229:     if (offs > 3) {
                    230:        refill_prefetch (currpc, o + 1);
                    231:        offs = addr - regs.prefetch_pc;
                    232:     }
                    233:     v = do_get_mem_byte (((uae_u8 *)&regs.prefetch) + offs);
                    234:     if (offs >= 2)
1.1.1.6   root      235:        refill_prefetch (currpc, 2);
1.1.1.5   root      236:     /* printf ("get_ibyte PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */
                    237:     return v;
1.1       root      238: }
                    239: STATIC_INLINE uae_u32 get_iword_prefetch (uae_s32 o)
                    240: {
1.1.1.5   root      241:     uae_u32 currpc = m68k_getpc ();
                    242:     uae_u32 addr = currpc + o;
                    243:     uae_u32 offs = addr - regs.prefetch_pc;
                    244:     uae_u32 v;
1.1.1.15  root      245: //fprintf (stderr,"get_iword PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v);
1.1.1.5   root      246:     if (offs > 3) {
                    247:        refill_prefetch (currpc, o);
                    248:        offs = addr - regs.prefetch_pc;
                    249:     }
1.1.1.8   root      250:     v = do_get_mem_word (((uae_u8 *)&regs.prefetch) + offs);
1.1.1.5   root      251:     if (offs >= 2)
1.1.1.6   root      252:        refill_prefetch (currpc, 2);
1.1.1.15  root      253: //fprintf (stderr,"get_iword PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v);
1.1.1.5   root      254:     /* printf ("get_iword PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */
                    255:     return v;
1.1       root      256: }
                    257: STATIC_INLINE uae_u32 get_ilong_prefetch (uae_s32 o)
                    258: {
1.1.1.5   root      259:     uae_u32 v = get_iword_prefetch (o);
                    260:     v <<= 16;
                    261:     v |= get_iword_prefetch (o + 2);
                    262:     return v;
1.1       root      263: }
                    264: 
                    265: #define m68k_incpc(o) (regs.pc_p += (o))
                    266: 
                    267: STATIC_INLINE void fill_prefetch_0 (void)
                    268: {
                    269: }
                    270: 
                    271: #define fill_prefetch_2 fill_prefetch_0
                    272: 
                    273: /* These are only used by the 68020/68881 code, and therefore don't
                    274:  * need to handle prefetch.  */
                    275: STATIC_INLINE uae_u32 next_ibyte (void)
                    276: {
                    277:     uae_u32 r = get_ibyte (0);
                    278:     m68k_incpc (2);
                    279:     return r;
                    280: }
                    281: 
                    282: STATIC_INLINE uae_u32 next_iword (void)
                    283: {
                    284:     uae_u32 r = get_iword (0);
                    285:     m68k_incpc (2);
                    286:     return r;
                    287: }
                    288: 
                    289: STATIC_INLINE uae_u32 next_ilong (void)
                    290: {
                    291:     uae_u32 r = get_ilong (0);
                    292:     m68k_incpc (4);
                    293:     return r;
                    294: }
                    295: 
                    296: #define m68k_setpc_bcc  m68k_setpc
                    297: #define m68k_setpc_rte  m68k_setpc
                    298: 
                    299: STATIC_INLINE void m68k_setstopped (int stop)
                    300: {
                    301:     regs.stopped = stop;
1.1.1.5   root      302:     /* A traced STOP instruction drops through immediately without
                    303:        actually stopping.  */
                    304:     if (stop && (regs.spcflags & SPCFLAG_DOTRACE) == 0)
1.1       root      305:        regs.spcflags |= SPCFLAG_STOP;
                    306: }
                    307: 
1.1.1.6   root      308: /* m68k_do_rts, m68k_do_bsr and m68k_do_jsr were originally defined in
                    309:  * compiler.h, but since that header file has been removed from Hatari,
                    310:  * they are now defined here: */
                    311: STATIC_INLINE void m68k_do_rts(void)
                    312: {
                    313:     m68k_setpc(get_long(m68k_areg(regs, 7)));
                    314:     m68k_areg(regs, 7) += 4;
                    315: }
                    316: 
                    317: STATIC_INLINE void m68k_do_bsr(uaecptr oldpc, uae_s32 offset)
                    318: {
                    319:     m68k_areg(regs, 7) -= 4;
                    320:     put_long(m68k_areg(regs, 7), oldpc);
                    321:     m68k_incpc(offset);
                    322: }
                    323: 
                    324: STATIC_INLINE void m68k_do_jsr(uaecptr oldpc, uaecptr dest)
                    325: {
                    326:     m68k_areg(regs, 7) -= 4;
                    327:     put_long(m68k_areg(regs, 7), oldpc);
                    328:     m68k_setpc(dest);
                    329: }
                    330: 
                    331: 
1.1       root      332: extern uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp);
                    333: extern uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp);
                    334: 
                    335: extern uae_s32 ShowEA (FILE *, int reg, amodes mode, wordsizes size, char *buf);
                    336: 
                    337: extern void MakeSR (void);
                    338: extern void MakeFromSR (void);
1.1.1.11  root      339: extern void Exception (int, uaecptr, int);
1.1       root      340: extern void dump_counts (void);
                    341: extern int m68k_move2c (int, uae_u32 *);
                    342: extern int m68k_movec2 (int, uae_u32 *);
                    343: extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
                    344: extern void m68k_mull (uae_u32, uae_u32, uae_u16);
1.1.1.4   root      345: extern void build_cpufunctbl(void);
1.1       root      346: extern void init_m68k (void);
                    347: extern void m68k_go (int);
                    348: extern void m68k_dumpstate (FILE *, uaecptr *);
                    349: extern void m68k_disasm (FILE *, uaecptr, uaecptr *, int);
                    350: extern void m68k_reset (void);
                    351: 
                    352: extern void mmu_op (uae_u32, uae_u16);
                    353: 
                    354: extern void fpp_opp (uae_u32, uae_u16);
                    355: extern void fdbcc_opp (uae_u32, uae_u16);
                    356: extern void fscc_opp (uae_u32, uae_u16);
                    357: extern void ftrapcc_opp (uae_u32,uaecptr);
                    358: extern void fbcc_opp (uae_u32, uaecptr, uae_u32);
                    359: extern void fsave_opp (uae_u32);
                    360: extern void frestore_opp (uae_u32);
                    361: 
1.1.1.10  root      362: extern int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor);
                    363: extern int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor);
1.1.1.2   root      364: 
1.1       root      365: /* Opcode of faulting instruction */
                    366: extern uae_u16 last_op_for_exception_3;
                    367: /* PC at fault time */
                    368: extern uaecptr last_addr_for_exception_3;
                    369: /* Address that generated the exception */
                    370: extern uaecptr last_fault_for_exception_3;
1.1.1.16  root      371: /* read (0) or write (1) access */
                    372: extern int last_writeaccess_for_exception_3;
                    373: /* instruction (1) or data (0) access */
                    374: extern int last_instructionaccess_for_exception_3;
1.1       root      375: 
                    376: #define CPU_OP_NAME(a) op ## a
                    377: 
                    378: /* 68040 */
1.1.1.9   root      379: extern const struct cputbl op_smalltbl_0_ff[];
1.1       root      380: /* 68020 + 68881 */
1.1.1.9   root      381: extern const struct cputbl op_smalltbl_1_ff[];
1.1       root      382: /* 68020 */
1.1.1.9   root      383: extern const struct cputbl op_smalltbl_2_ff[];
1.1       root      384: /* 68010 */
1.1.1.9   root      385: extern const struct cputbl op_smalltbl_3_ff[];
1.1       root      386: /* 68000 */
1.1.1.9   root      387: extern const struct cputbl op_smalltbl_4_ff[];
1.1       root      388: /* 68000 slow but compatible.  */
1.1.1.9   root      389: extern const struct cputbl op_smalltbl_5_ff[];
1.1       root      390: 
1.1.1.2   root      391: extern cpuop_func *cpufunctbl[65536];
1.1       root      392: 
1.1.1.10  root      393: 
                    394: /* Family of the latest instruction executed (to check for pairing) */
                    395: extern int OpcodeFamily;                       /* see instrmnem in readcpu.h */
1.1.1.7   root      396: 
1.1.1.17  root      397: /* How many cycles to add to the current instruction in case a "misaligned" bus access is made */
1.1.1.13  root      398: /* (used when addressing mode is d8(an,ix)) */
                    399: extern int BusCyclePenalty;
                    400: 
1.1.1.4   root      401: #endif /* UAE_NEWCPU_H */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.