Annotation of tme/ic/m68k/m68k-misc.c, revision 1.1.1.1

1.1       root        1: /* m68k-misc.c - miscellaneous things for the m68k emulator: */
                      2: 
                      3: /* $Id: m68k-misc.c,v 1.11 2003/05/16 21:48:11 fredette Exp $ */
                      4: 
                      5: /* includes: */
                      6: #include "m68k-impl.h"
                      7: 
                      8: _TME_RCSID("$Id: m68k-misc.c,v 1.11 2003/05/16 21:48:11 fredette Exp $");
                      9: 
                     10: /* small immediates: */
                     11: const tme_uint32_t _tme_m68k_imm32[9] = {
                     12:   0, 1, 2, 3, 4, 5, 6, 7, 8
                     13: };
                     14: const tme_uint16_t _tme_m68k_imm16[9] = {
                     15:   0, 1, 2, 3, 4, 5, 6, 7, 8
                     16: };
                     17: const tme_uint8_t _tme_m68k_imm8[9] = {
                     18:   0, 1, 2, 3, 4, 5, 6, 7, 8
                     19: };
                     20: 
                     21: /* the memory buffer read and write functions: */
                     22: #if TME_M68K_SIZE_8 != 1
                     23: #error "TME_M68K_SIZE_8 must be 1"
                     24: #endif
                     25: #if TME_M68K_SIZE_16 != 2
                     26: #error "TME_M68K_SIZE_16 must be 2"
                     27: #endif
                     28: #if TME_M68K_SIZE_32 != 4
                     29: #error "TME_M68K_SIZE_32 must be 4"
                     30: #endif
                     31: const _tme_m68k_xfer_memx _tme_m68k_read_memx[5] = {
                     32:   NULL,
                     33:   tme_m68k_read_memx8,
                     34:   tme_m68k_read_memx16,
                     35:   NULL,
                     36:   tme_m68k_read_memx32
                     37: };
                     38: const _tme_m68k_xfer_memx _tme_m68k_write_memx[5] = {
                     39:   NULL,
                     40:   tme_m68k_write_memx8,
                     41:   tme_m68k_write_memx16,
                     42:   NULL,
                     43:   tme_m68k_write_memx32
                     44: };
                     45: const _tme_m68k_xfer_mem _tme_m68k_read_mem[5] = {
                     46:   NULL,
                     47:   tme_m68k_read_mem8,
                     48:   tme_m68k_read_mem16,
                     49:   NULL,
                     50:   tme_m68k_read_mem32
                     51: };
                     52: const _tme_m68k_xfer_mem _tme_m68k_write_mem[5] = {
                     53:   NULL,
                     54:   tme_m68k_write_mem8,
                     55:   tme_m68k_write_mem16,
                     56:   NULL,
                     57:   tme_m68k_write_mem32
                     58: };
                     59: 
                     60: /* our bus signal handler: */
                     61: static int
                     62: _tme_m68k_bus_signal(struct tme_bus_connection *conn_bus, unsigned int signal)
                     63: {
                     64:   struct tme_m68k *ic;
                     65:   unsigned int level_edge;
                     66: 
                     67:   /* recover our IC: */
                     68:   ic = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private;
                     69: 
                     70:   /* take out the level and edge: */
                     71:   level_edge = signal & (TME_BUS_SIGNAL_LEVEL_MASK
                     72:                         | TME_BUS_SIGNAL_EDGE);
                     73:   signal &= ~(TME_BUS_SIGNAL_LEVEL_MASK
                     74:              | TME_BUS_SIGNAL_EDGE);
                     75: 
                     76:   /* lock the external mutex: */
                     77:   tme_mutex_lock(&ic->tme_m68k_external_mutex);
                     78: 
                     79:   /* on the falling edge of HALT or RESET, halt the processor: */
                     80:   if (level_edge == (TME_BUS_SIGNAL_LEVEL_ASSERTED
                     81:                     | TME_BUS_SIGNAL_EDGE)
                     82:       && (signal == TME_BUS_SIGNAL_HALT
                     83:          || signal == TME_BUS_SIGNAL_RESET)) {
                     84:     ic->tme_m68k_external_halt = TRUE;
                     85:   }
                     86: 
                     87:   /* on the rising edge of RESET, reset the processor: */
                     88:   else if (signal == TME_BUS_SIGNAL_RESET
                     89:           && level_edge == (TME_BUS_SIGNAL_LEVEL_NEGATED
                     90:                             | TME_BUS_SIGNAL_EDGE)) {
                     91:     ic->tme_m68k_external_reset = TRUE;
                     92:   }
                     93: 
                     94:   /* on any other HALT or RESET, do nothing: */
                     95:   else if (signal == TME_BUS_SIGNAL_RESET
                     96:           || signal == TME_BUS_SIGNAL_HALT) {
                     97:     /* nothing */
                     98:   }
                     99: 
                    100:   /* anything else: */
                    101:   else {
                    102:     abort();
                    103:   }
                    104: 
                    105:   /* unlock the external mutex: */
                    106:   tme_mutex_unlock(&ic->tme_m68k_external_mutex);
                    107: 
                    108:   /* notify any threads waiting on the external condition: */
                    109:   tme_cond_notify(&ic->tme_m68k_external_cond, TRUE);
                    110:   return (TME_OK);
                    111: }
                    112: 
                    113: /* our interrupt handler: */
                    114: static int
                    115: _tme_m68k_bus_interrupt(struct tme_m68k_bus_connection *conn_m68k, unsigned int ipl)
                    116: {
                    117:   struct tme_m68k *ic;
                    118: 
                    119:   /* recover our IC: */
                    120:   ic = conn_m68k->tme_m68k_bus_connection.tme_bus_connection.tme_connection_element->tme_element_private;
                    121: 
                    122:   /* lock the external mutex: */
                    123:   tme_mutex_lock(&ic->tme_m68k_external_mutex);
                    124: 
                    125:   /* set the interrupt line: */
                    126:   ic->tme_m68k_external_ipl = ipl;
                    127: 
                    128:   /* unlock the external mutex: */
                    129:   tme_mutex_unlock(&ic->tme_m68k_external_mutex);
                    130: 
                    131:   /* notify any threads waiting on the external condition: */
                    132:   tme_cond_notify(&ic->tme_m68k_external_cond, TRUE);
                    133:   return (TME_OK);
                    134: }
                    135: 
                    136: /* this checks for external signals.  this must be called with the
                    137:    external mutex held: */
                    138: void
                    139: tme_m68k_external_check(struct tme_m68k *ic, tme_uint32_t internal_exceptions)
                    140: {
                    141:   unsigned int ipl;
                    142:   int vector;
                    143:   int rc;
                    144: 
                    145:   /* if an external reset has been requested, start reset exception
                    146:      processing: */
                    147:   if (ic->tme_m68k_external_reset) {
                    148:     ic->tme_m68k_external_reset = FALSE;
                    149:     tme_mutex_unlock(&ic->tme_m68k_external_mutex);
                    150:     tme_m68k_exception(ic, TME_M68K_EXCEPTION_GROUP0_RESET);
                    151:   }
                    152: 
                    153:   /* if an external halt has been requested, halt: */
                    154:   if (ic->tme_m68k_external_halt) {
                    155:     ic->tme_m68k_external_halt = FALSE;
                    156:     tme_mutex_unlock(&ic->tme_m68k_external_mutex);
                    157:     ic->_tme_m68k_mode = TME_M68K_MODE_HALT;
                    158:     TME_M68K_SEQUENCE_START;
                    159:     tme_m68k_redispatch(ic);
                    160:   }
                    161: 
                    162:   /* if we are not halted, and an interrupt can be serviced, start
                    163:      interrupt exception processing: */
                    164:   ipl = ic->tme_m68k_external_ipl;
                    165:   if (ic->_tme_m68k_mode != TME_M68K_MODE_HALT
                    166:       && ipl >= TME_M68K_IPL_MIN
                    167:       && ipl <= TME_M68K_IPL_MAX
                    168:       && (ipl == TME_M68K_IPL_NMI
                    169:          || ipl > TME_M68K_FLAG_IPM(ic->tme_m68k_ireg_sr))) {
                    170:     tme_mutex_unlock(&ic->tme_m68k_external_mutex);
                    171:     
                    172:     /* acknowledge the interrupt and get the vector: */
                    173:     rc = (*ic->_tme_m68k_bus_connection->tme_m68k_bus_connection.tme_bus_intack)
                    174:       (&ic->_tme_m68k_bus_connection->tme_m68k_bus_connection,
                    175:        ipl, &vector);
                    176:     if (rc == TME_EDEADLK) {
                    177:       abort();
                    178:     }
                    179: 
                    180:     /* if the interrupt acknowledge failed, this is a spurious interrupt: */
                    181:     if (rc == ENOENT) {
                    182:       vector = 24;
                    183:     }
                    184: 
                    185:     /* if no vector is given, use the autovector: */
                    186:     else if (vector == TME_BUS_INTERRUPT_VECTOR_UNDEF) {
                    187:       vector = 24 + ipl;
                    188:     }
                    189: 
                    190:     /* dispatch the exceptions: */
                    191:     tme_m68k_exception(ic, internal_exceptions | TME_M68K_EXCEPTION_GROUP1_INT(ipl, vector));
                    192:   }
                    193: 
                    194:   /* if there are internal exceptions to process, do so: */
                    195:   if (internal_exceptions != 0) {
                    196:     tme_mutex_unlock(&ic->tme_m68k_external_mutex);
                    197:     tme_m68k_exception(ic, internal_exceptions);
                    198:   }
                    199: 
                    200:   /* there are no exceptions to process: */
                    201: }
                    202: 
                    203: /* the idle function, used when the processor is halted or stopped: */
                    204: static void
                    205: tme_m68k_idle(struct tme_m68k *ic)
                    206: {  
                    207:   /* lock the external mutex: */
                    208:   tme_mutex_lock(&ic->tme_m68k_external_mutex);
                    209: 
                    210:   /* loop forever: */
                    211:   for (;;) {
                    212: 
                    213:     /* check for any external signal: */
                    214:     tme_m68k_external_check(ic, 0);
                    215: 
                    216:     /* await an external condition: */
                    217:     tme_cond_wait_yield(&ic->tme_m68k_external_cond, &ic->tme_m68k_external_mutex);
                    218:   }
                    219: }
                    220: 
                    221: /* the m68k thread: */
                    222: static void
                    223: tme_m68k_thread(struct tme_m68k *ic)
                    224: {
                    225: 
                    226:   /* we use longjmp to redispatch: */
                    227:   do { } while (setjmp(ic->_tme_m68k_dispatcher));
                    228: 
                    229:   /* dispatch on the current mode: */
                    230:   switch (ic->_tme_m68k_mode) {
                    231: 
                    232:   case TME_M68K_MODE_EXECUTION:
                    233:     (*ic->_tme_m68k_mode_execute)(ic);
                    234:     /* NOTREACHED */
                    235: 
                    236:   case TME_M68K_MODE_EXCEPTION:
                    237:     (*ic->_tme_m68k_mode_exception)(ic);
                    238:     /* NOTREACHED */
                    239: 
                    240:   case TME_M68K_MODE_RTE:
                    241:     (*ic->_tme_m68k_mode_rte)(ic);
                    242:     /* NOTREACHED */
                    243: 
                    244:   case TME_M68K_MODE_STOP:
                    245:   case TME_M68K_MODE_HALT:
                    246:     tme_m68k_idle(ic);
                    247:     /* NOTREACHED */
                    248: 
                    249:   default:
                    250:     abort();
                    251:   }
                    252:   /* NOTREACHED */
                    253: }
                    254: 
                    255: /* the TLB filler for when we are on a generic bus: */
                    256: static int
                    257: _tme_m68k_generic_tlb_fill(struct tme_m68k_bus_connection *conn_m68k, 
                    258:                           struct tme_m68k_tlb *tlb,
                    259:                           unsigned int function_code, 
                    260:                           tme_uint32_t external_address, 
                    261:                           unsigned int cycles)
                    262: {
                    263:   struct tme_m68k *ic;
                    264: 
                    265:   /* recover our IC: */
                    266:   ic = conn_m68k->tme_m68k_bus_connection.tme_bus_connection.tme_connection_element->tme_element_private;
                    267: 
                    268:   /* call the generic bus TLB filler: */
                    269:   (ic->_tme_m68k_bus_generic->tme_bus_tlb_fill)
                    270:     (ic->_tme_m68k_bus_generic,
                    271:      &tlb->tme_m68k_tlb_bus_tlb,
                    272:      external_address,
                    273:      cycles);
                    274:   
                    275:   /* when we're on a generic bus a TLB entry is valid for all function codes: */
                    276:   tlb->tme_m68k_tlb_function_codes_mask = -1;
                    277: 
                    278:   return (TME_OK);
                    279: }
                    280: 
                    281: /* the connection scorer: */
                    282: static int
                    283: _tme_m68k_connection_score(struct tme_connection *conn, unsigned int *_score)
                    284: {
                    285:   struct tme_m68k_bus_connection *conn_m68k;
                    286:   struct tme_bus_connection *conn_bus;
                    287:   unsigned int score;
                    288: 
                    289:   /* assume that this connection is useless: */
                    290:   score = 0;
                    291: 
                    292:   /* dispatch on the connection type: */
                    293:   conn_m68k = (struct tme_m68k_bus_connection *) conn->tme_connection_other;
                    294:   conn_bus = (struct tme_bus_connection *) conn->tme_connection_other;
                    295:   switch (conn->tme_connection_type) {
                    296: 
                    297:     /* this must be a bus, and not another m68k chip: */
                    298:   case TME_CONNECTION_BUS_M68K:
                    299:     if (conn_bus->tme_bus_tlb_set_allocate != NULL
                    300:        && conn_m68k->tme_m68k_bus_tlb_fill != NULL) {
                    301:       score = 10;
                    302:     }
                    303:     break;
                    304: 
                    305:     /* this must be a bus, and not another chip: */
                    306:   case TME_CONNECTION_BUS_GENERIC:
                    307:     if (conn_bus->tme_bus_tlb_set_allocate != NULL
                    308:        && conn_bus->tme_bus_tlb_fill != NULL) {
                    309:       score = 1;
                    310:     }
                    311:     break;
                    312: 
                    313:   default: abort();
                    314:   }
                    315: 
                    316:   *_score = score;
                    317:   return (TME_OK);
                    318: }
                    319: 
                    320: /* this makes a new connection: */
                    321: static int
                    322: _tme_m68k_connection_make(struct tme_connection *conn, unsigned int state)
                    323: {
                    324:   struct tme_m68k *ic;
                    325:   struct tme_m68k_bus_connection *conn_m68k;
                    326:   struct tme_bus_connection *conn_bus;
                    327:   struct tme_connection *conn_other;
                    328: 
                    329:   /* since the CPU is halted, it won't be making any connection calls,
                    330:      so we only have to do work when the connection is fully made: */
                    331:   if (state == TME_CONNECTION_FULL) {
                    332: 
                    333:     /* recover our IC: */
                    334:     ic = conn->tme_connection_element->tme_element_private;
                    335:     
                    336:     /* dispatch on the connection type: */
                    337:     conn_other = conn->tme_connection_other;
                    338:     conn_m68k = (struct tme_m68k_bus_connection *) conn_other;
                    339:     conn_bus = (struct tme_bus_connection *) conn_other;
                    340:     switch (conn->tme_connection_type) {
                    341:       
                    342:     case TME_CONNECTION_BUS_M68K:
                    343:       ic->_tme_m68k_bus_connection = conn_m68k;
                    344:       break;
                    345:       
                    346:       /* we need an adaptation layer: */
                    347:     case TME_CONNECTION_BUS_GENERIC:
                    348:       conn_m68k = tme_new0(struct tme_m68k_bus_connection, 1);
                    349:       conn_m68k->tme_m68k_bus_connection.tme_bus_connection.tme_connection_element = conn->tme_connection_element;
                    350:       conn_m68k->tme_m68k_bus_tlb_fill = _tme_m68k_generic_tlb_fill;
                    351:       ic->_tme_m68k_bus_connection = conn_m68k;
                    352:       ic->_tme_m68k_bus_generic = conn_bus;
                    353:       break;
                    354:       
                    355:     default: abort();
                    356:     }
                    357: 
                    358:     /* allocate the TLB hash set: */
                    359:     (*ic->_tme_m68k_bus_connection->tme_m68k_bus_connection.tme_bus_tlb_set_allocate)
                    360:       (&ic->_tme_m68k_bus_connection->tme_m68k_bus_connection, 
                    361:        _TME_M68K_TLB_HASH_SIZE, 
                    362:        sizeof(struct tme_m68k_tlb),
                    363:        TME_ATOMIC_POINTER((struct tme_bus_tlb **) &ic->_tme_m68k_tlb_array));
                    364: 
                    365:     /* allocate the ITLB set: */
                    366:     (*ic->_tme_m68k_bus_connection->tme_m68k_bus_connection.tme_bus_tlb_set_allocate)
                    367:       (&ic->_tme_m68k_bus_connection->tme_m68k_bus_connection, 
                    368:        1, 
                    369:        sizeof(struct tme_m68k_tlb),
                    370:        TME_ATOMIC_POINTER((struct tme_bus_tlb **) &ic->_tme_m68k_itlb));
                    371:   }
                    372: 
                    373:   /* NB: the machine needs to issue a reset to bring the CPU out of halt. */
                    374:   return (TME_OK);
                    375: }
                    376: 
                    377: /* this breaks a connection: */
                    378: static int 
                    379: _tme_m68k_connection_break(struct tme_connection *conn, unsigned int state)
                    380: {
                    381:   abort();
                    382: }
                    383: 
                    384: /* this makes new connection sides: */
                    385: static int
                    386: _tme_m68k_connections_new(struct tme_element *element, const char * const *args, struct tme_connection **_conns, char **_output)
                    387: {
                    388:   struct tme_m68k_bus_connection *conn_m68k;
                    389:   struct tme_bus_connection *conn_bus;
                    390:   struct tme_connection *conn;
                    391: 
                    392:   /* if we already have a bus connection, we can take no more connections: */
                    393:   if (((struct tme_m68k *) element->tme_element_private)->_tme_m68k_bus_connection != NULL) {
                    394:     return (TME_OK);
                    395:   }
                    396: 
                    397:   /* create our side of an m68k bus connection: */
                    398:   conn_m68k = tme_new0(struct tme_m68k_bus_connection, 1);
                    399:   conn_bus = &conn_m68k->tme_m68k_bus_connection;
                    400:   conn = &conn_bus->tme_bus_connection;
                    401: 
                    402:   /* fill in the generic connection: */
                    403:   conn->tme_connection_next = *_conns;
                    404:   conn->tme_connection_type = TME_CONNECTION_BUS_M68K;
                    405:   conn->tme_connection_score = _tme_m68k_connection_score;
                    406:   conn->tme_connection_make = _tme_m68k_connection_make;
                    407:   conn->tme_connection_break = _tme_m68k_connection_break;
                    408: 
                    409:   /* fill in the generic bus connection: */
                    410:   conn_bus->tme_bus_signal = _tme_m68k_bus_signal;
                    411:   conn_bus->tme_bus_tlb_set_allocate = NULL;
                    412: 
                    413:   /* full in the m68k bus connection: */
                    414:   conn_m68k->tme_m68k_bus_interrupt = _tme_m68k_bus_interrupt;
                    415:   conn_m68k->tme_m68k_bus_tlb_fill = NULL;
                    416: 
                    417:   /* add this connection to the set of possibilities: */
                    418:   *_conns = conn;
                    419: 
                    420:   /* create our side of a generic bus connection: */
                    421:   conn_bus = tme_new0(struct tme_bus_connection, 1);
                    422:   conn = &conn_bus->tme_bus_connection;
                    423: 
                    424:   /* fill in the generic connection: */
                    425:   conn->tme_connection_next = *_conns;
                    426:   conn->tme_connection_type = TME_CONNECTION_BUS_GENERIC;
                    427:   conn->tme_connection_score = _tme_m68k_connection_score;
                    428:   conn->tme_connection_make = _tme_m68k_connection_make;
                    429:   conn->tme_connection_break = _tme_m68k_connection_break;
                    430: 
                    431:   /* fill in the generic bus connection: */
                    432:   conn_bus->tme_bus_signal = _tme_m68k_bus_signal;
                    433:   conn_bus->tme_bus_tlb_set_allocate = NULL;
                    434:   conn_bus->tme_bus_tlb_fill = NULL;
                    435: 
                    436:   /* add this connection to the set of possibilities: */
                    437:   *_conns = conn;
                    438: 
                    439:   /* done: */
                    440:   return (TME_OK);
                    441: }
                    442: 
                    443: /* the common m68k new function: */
                    444: int
                    445: tme_m68k_new(struct tme_m68k *ic, const char * const *args, const void *extra, char **_output)
                    446: {
                    447:   struct tme_element *element;
                    448: 
                    449:   /* we take no arguments: */
                    450:   if (args[1] != NULL) {
                    451:     tme_output_append_error(_output,
                    452:                            "%s %s, %s %s",
                    453:                            args[1],
                    454:                            _("unexpected"),
                    455:                            _("usage:"),
                    456:                            args[0]);
                    457:     tme_free(ic);
                    458:     return (EINVAL);
                    459:   }
                    460: 
                    461:   /* initialize the verifier: */
                    462:   tme_m68k_verify_init();
                    463: 
                    464:   /* dispatch on the type: */
                    465:   switch (ic->tme_m68k_type) {
                    466:   case TME_M68K_M68000:
                    467:     ic->_tme_m68k_bus_16bit = TRUE;
                    468:     break;
                    469:   case TME_M68K_M68010:
                    470:     ic->_tme_m68k_bus_16bit = TRUE;
                    471:     break;
                    472:   case TME_M68K_M68020:
                    473:     ic->_tme_m68k_bus_16bit = FALSE;
                    474:     break;
                    475:   default:
                    476:     abort();
                    477:   }
                    478: 
                    479:   /* we have no bus connection yet: */
                    480:   ic->_tme_m68k_bus_connection = NULL;
                    481: 
                    482:   /* fill the element: */
                    483:   element = ic->tme_m68k_element;
                    484:   element->tme_element_private = ic;
                    485:   element->tme_element_connections_new = _tme_m68k_connections_new;
                    486: 
                    487:   /* calculate the instruction burst size: */
                    488:   /* XXX TBD: */
                    489:   ic->_tme_m68k_instruction_burst = 20;
                    490: 
                    491:   /* force the processor to be halted: */
                    492:   ic->_tme_m68k_mode = TME_M68K_MODE_HALT;
                    493:   TME_M68K_SEQUENCE_START;
                    494: 
                    495:   /* start the m68k thread: */
                    496:   tme_thread_create((tme_thread_t) tme_m68k_thread, ic);
                    497: 
                    498:   return (TME_OK);
                    499: }  
                    500: 
                    501: /* the common m68k reset function: */
                    502: void
                    503: tme_m68k_do_reset(struct tme_m68k *ic)
                    504: {
                    505:   
                    506:   /* force the VBR to zero: */
                    507:   ic->tme_m68k_ireg_vbr = 0;
                    508: 
                    509:   /* force supervisor mode, interrupts disabled: */
                    510:   tme_m68k_change_sr(ic, TME_M68K_FLAG_S | (7 << 8));
                    511: 
                    512:   /* load the initial SSP and PC: */
                    513:   ic->_tme_m68k_ea_function_code = TME_M68K_FC_SD;
                    514:   ic->_tme_m68k_ea_address = 0;
                    515:   tme_m68k_read_mem32(ic, TME_M68K_IREG_A7);
                    516:   ic->_tme_m68k_ea_address += sizeof(ic->tme_m68k_ireg_a7);
                    517:   tme_m68k_read_mem32(ic, TME_M68K_IREG_PC);
                    518: 
                    519:   /* clear all exceptions: */
                    520:   ic->_tme_m68k_exceptions = 0;
                    521: 
                    522:   /* start execution: */
                    523:   ic->_tme_m68k_mode = TME_M68K_MODE_EXECUTION;
                    524:   TME_M68K_SEQUENCE_START;
                    525:   tme_m68k_redispatch(ic);
                    526: }
                    527: 
                    528: /* this returns nonzero iff the slow instruction executor must be
                    529:    used: */
                    530: int
                    531: tme_m68k_go_slow(const struct tme_m68k *ic)
                    532: {
                    533:   struct tme_m68k_tlb *tlb;
                    534:   tme_uint32_t linear_pc;
                    535: 
                    536:   tlb = TME_ATOMIC_READ(struct tme_m68k_tlb *, ic->_tme_m68k_itlb);
                    537:   linear_pc = ic->tme_m68k_ireg_pc;
                    538:   return (
                    539:          
                    540:          /* the ITLB entry must support reads from emulator memory: */
                    541:          !TME_M68K_TLB_OK_FAST_READ(tlb, 
                    542:                                     TME_M68K_FUNCTION_CODE_PROGRAM(ic),
                    543:                                     linear_pc,
                    544:                                     linear_pc)
                    545: 
                    546:          /* the ITLB emulator memory must be 32-bit aligned for the
                    547:             benefit of the fast instruction word fetch macros, so
                    548:             that emulator address alignment goes with linear address
                    549:             alignment: */
                    550:          || (((unsigned long) tlb->tme_m68k_tlb_emulator_off_read)
                    551:              & (sizeof(tme_uint32_t) - 1))
                    552: 
                    553:          /* the linear PC must be 16-bit aligned: */
                    554:          || (linear_pc & 1)
                    555: 
                    556:          /* there must be no tracing: */
                    557:          || TME_M68K_FLAG_T(ic->tme_m68k_ireg_sr) != 0);
                    558: }
                    559: 
                    560: /* this redispatches: */
                    561: void
                    562: tme_m68k_redispatch(struct tme_m68k *ic)
                    563: {
                    564:   longjmp(ic->_tme_m68k_dispatcher, 1);
                    565: }
                    566: 
                    567: /* this fills a TLB entry: */
                    568: void
                    569: tme_m68k_tlb_fill(struct tme_m68k *ic, struct tme_m68k_tlb *tlb, 
                    570:                  unsigned int function_code, 
                    571:                  tme_uint32_t linear_address, 
                    572:                  unsigned int cycles)
                    573: {
                    574:   tme_uint32_t external_address;
                    575:   struct tme_bus_tlb tlb_internal;
                    576:   
                    577:   /* when emulating a CPU with a 16-bit bus, only 24 bits of address
                    578:      are external: */
                    579:   external_address = linear_address;
                    580:   if (ic->_tme_m68k_bus_16bit) {
                    581:     external_address &= 0x00ffffff;
                    582:   }
                    583: 
                    584:   /* fill the TLB entry: */
                    585:   (*ic->_tme_m68k_bus_connection->tme_m68k_bus_tlb_fill)
                    586:     (ic->_tme_m68k_bus_connection, tlb,
                    587:      function_code,
                    588:      external_address,
                    589:      cycles);
                    590: 
                    591:   /* if this code isn't 32-bit clean, we have to deal: */
                    592:   if (external_address != linear_address) {
                    593:     TME_ATOMIC_WRITE(tme_bus_addr_t, tlb_internal.tme_bus_tlb_addr_first,
                    594:                     TME_ATOMIC_READ(tme_bus_addr_t, tlb->tme_m68k_tlb_linear_first)
                    595:                     | (linear_address ^ external_address));
                    596:     TME_ATOMIC_WRITE(tme_bus_addr_t, tlb_internal.tme_bus_tlb_addr_last,
                    597:                     TME_ATOMIC_READ(tme_bus_addr_t, tlb->tme_m68k_tlb_linear_last)
                    598:                     | (linear_address ^ external_address));
                    599:     tlb_internal.tme_bus_tlb_cycles_ok = tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycles_ok;
                    600:     tme_bus_tlb_map(&tlb->tme_m68k_tlb_bus_tlb, external_address,
                    601:                    &tlb_internal, linear_address);
                    602:   }
                    603: }
                    604: 
                    605: /* this triggers exception processing: */
                    606: void
                    607: tme_m68k_exception(struct tme_m68k *ic, tme_uint32_t new_exceptions)
                    608: {
                    609:   assert(new_exceptions != 0);
                    610: 
                    611:   /* if the set of new exceptions includes a group zero exception: */
                    612:   if (new_exceptions & 
                    613:       (TME_M68K_EXCEPTION_GROUP0_RESET
                    614:        | TME_M68K_EXCEPTION_GROUP0_AERR
                    615:        | TME_M68K_EXCEPTION_GROUP0_BERR)) {
                    616:     
                    617:     /* there must be only one exception - you cannot trigger a group 0
                    618:        exception simultaneously with any other group 0, 1, or 2
                    619:        exception: */
                    620:     assert((new_exceptions & (new_exceptions - 1)) == 0);
                    621:     
                    622:     /* if this is a reset exception, it clears all other exceptions: */
                    623:     if (new_exceptions == TME_M68K_EXCEPTION_GROUP0_RESET) {
                    624:       ic->_tme_m68k_exceptions = 0;
                    625:     }
                    626: 
                    627:     /* otherwise, this is an address error or a bus error.  if we were
                    628:        already processing a group 0 exception, this is a
                    629:        double fault, and the processor enters the halted state: */
                    630:     else if (ic->_tme_m68k_exceptions &
                    631:             (TME_M68K_EXCEPTION_GROUP0_RESET
                    632:              | TME_M68K_EXCEPTION_GROUP0_AERR
                    633:              | TME_M68K_EXCEPTION_GROUP0_BERR)) {
                    634:       ic->_tme_m68k_mode = TME_M68K_MODE_HALT;
                    635:       TME_M68K_SEQUENCE_START;
                    636:       tme_m68k_redispatch(ic);
                    637:     }
                    638:   }
                    639: 
                    640:   /* otherwise, exception processing must not already be happening: */
                    641:   else {
                    642:     assert(ic->_tme_m68k_exceptions == 0);
                    643:   }
                    644: 
                    645:   /* begin exception processing: */
                    646:   ic->_tme_m68k_exceptions |= new_exceptions;
                    647:   ic->_tme_m68k_mode = TME_M68K_MODE_EXCEPTION;
                    648:   TME_M68K_SEQUENCE_START;
                    649:   tme_m68k_redispatch(ic);
                    650: }
                    651: 
                    652: /* this changes SR, and swaps %a7 as needed: */
                    653: void
                    654: tme_m68k_change_sr(struct tme_m68k *ic, tme_uint16_t sr)
                    655: {
                    656:   
                    657:   /* save %a7 in the proper stack pointer control register: */
                    658:   switch (ic->tme_m68k_ireg_sr & (TME_M68K_FLAG_S | TME_M68K_FLAG_M)) {
                    659:   case 0:
                    660:   case TME_M68K_FLAG_M:
                    661:     ic->tme_m68k_ireg_usp = ic->tme_m68k_ireg_a7;
                    662:     break;
                    663:   case TME_M68K_FLAG_S:
                    664:     ic->tme_m68k_ireg_msp = ic->tme_m68k_ireg_a7;
                    665:     break;
                    666:   case (TME_M68K_FLAG_S | TME_M68K_FLAG_M):
                    667:     ic->tme_m68k_ireg_isp = ic->tme_m68k_ireg_a7;
                    668:     break;
                    669:   }
                    670: 
                    671:   /* load %a7 from the proper stack pointer control register: */
                    672:   ic->tme_m68k_ireg_sr = sr;
                    673:   switch (ic->tme_m68k_ireg_sr & (TME_M68K_FLAG_S | TME_M68K_FLAG_M)) {
                    674:   case 0:
                    675:   case TME_M68K_FLAG_M:
                    676:     ic->tme_m68k_ireg_a7 = ic->tme_m68k_ireg_usp;
                    677:     break;
                    678:   case TME_M68K_FLAG_S:
                    679:     ic->tme_m68k_ireg_a7 = ic->tme_m68k_ireg_msp;
                    680:     break;
                    681:   case (TME_M68K_FLAG_S | TME_M68K_FLAG_M):
                    682:     ic->tme_m68k_ireg_a7 = ic->tme_m68k_ireg_isp;
                    683:     break;
                    684:   }
                    685: }
                    686: 
                    687: /* this starts processing an m68k exception: */
                    688: void
                    689: tme_m68k_exception_process_start(struct tme_m68k *ic, unsigned int ipl)
                    690: {
                    691:   tme_uint16_t sr;
                    692: 
                    693:   /* make an internal copy of the status register, then set S, clear
                    694:      T, and update I: */
                    695:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                    696:     ic->tme_m68k_ireg_shadow_sr = ic->tme_m68k_ireg_sr;
                    697:     sr = (ic->tme_m68k_ireg_sr | TME_M68K_FLAG_S) ^ TME_M68K_FLAG_T(ic->tme_m68k_ireg_sr);
                    698:     if (ipl > TME_M68K_IPL_NONE) {
                    699:       assert(ipl == TME_M68K_IPL_NMI
                    700:             || ipl > TME_M68K_FLAG_IPM(sr));
                    701:       sr = (sr & ~(TME_M68K_IPL_MAX << 8)) | (ipl << 8);
                    702:     }
                    703:     tme_m68k_change_sr(ic, sr);
                    704:   }
                    705: }
                    706: 
                    707: /* this finishes processing an m68k exception: */
                    708: void
                    709: tme_m68k_exception_process_finish(struct tme_m68k *ic, tme_uint8_t format, tme_uint8_t vector)
                    710: {
                    711:   tme_uint16_t vector_offset;
                    712: 
                    713:   /* stack the frame format and vector offset, unless this is a 68000: */
                    714:   vector_offset = ((tme_uint16_t) vector) << 2;
                    715:   if (ic->tme_m68k_type != TME_M68K_M68000) {
                    716:     tme_m68k_push16(ic, (((tme_uint16_t) format) << 12) | vector_offset);
                    717:   }
                    718: 
                    719:   /* stack the program counter: */
                    720:   tme_m68k_push32(ic, ic->tme_m68k_ireg_pc);
                    721:   
                    722:   /* stack the internal copy of the status register: */
                    723:   tme_m68k_push16(ic, ic->tme_m68k_ireg_shadow_sr);
                    724: 
                    725:   /* do a bus cycle to read the vector into the program counter: */
                    726:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                    727:     ic->_tme_m68k_ea_function_code = TME_M68K_FC_SD; /* XXX is this right? */
                    728:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_vbr + vector_offset;
                    729:   }
                    730:   tme_m68k_read_mem32(ic, TME_M68K_IREG_PC);
                    731: }
                    732: 
                    733: /* common m68k exception processing: */
                    734: void
                    735: tme_m68k_exception_process(struct tme_m68k *ic)
                    736: {
                    737:   tme_uint32_t exceptions;
                    738: 
                    739:   /* get the set of exceptions.  we must have no group 0 exceptions: */
                    740:   exceptions = ic->_tme_m68k_exceptions;
                    741:   assert((exceptions & (TME_M68K_EXCEPTION_GROUP0_RESET
                    742:                        | TME_M68K_EXCEPTION_GROUP0_AERR
                    743:                        | TME_M68K_EXCEPTION_GROUP0_BERR)) == 0);
                    744: 
                    745:   /* these if statements are ordered to implement the priority
                    746:      relationship between the different exceptions as outlined in 
                    747:      the 68000 user's manual (pp 93 in my copy): */
                    748:   
                    749:   if (TME_M68K_EXCEPTION_IS_GROUP2(exceptions)) {
                    750:     tme_m68k_exception_process_start(ic, 0);
                    751:     tme_m68k_exception_process_finish(ic, TME_M68K_FORMAT_0, TME_M68K_EXCEPTION_IS_GROUP2(exceptions));
                    752:   }
                    753:   
                    754:   if (exceptions & TME_M68K_EXCEPTION_GROUP1_TRACE) {
                    755:     tme_m68k_exception_process_start(ic, 0);
                    756:     tme_m68k_exception_process_finish(ic, TME_M68K_FORMAT_0, 0x09);
                    757:   }
                    758:   
                    759:   if (TME_M68K_EXCEPTION_IS_GROUP1_INT(exceptions)) {
                    760:     tme_m68k_exception_process_start(ic, TME_M68K_EXCEPTION_IS_GROUP1_INT(exceptions));
                    761:     tme_m68k_exception_process_finish(ic, TME_M68K_FORMAT_0, TME_M68K_EXCEPTION_GROUP1_INT_VEC(exceptions));
                    762:   }
                    763:   
                    764:   if (exceptions & TME_M68K_EXCEPTION_GROUP1_ILL) {
                    765:     tme_m68k_exception_process_start(ic, 0);
                    766:     tme_m68k_exception_process_finish(ic, TME_M68K_FORMAT_0, 0x04);
                    767:   }
                    768:   
                    769:   if (exceptions & TME_M68K_EXCEPTION_GROUP1_PRIV) {
                    770:     tme_m68k_exception_process_start(ic, 0);
                    771:     tme_m68k_exception_process_finish(ic, TME_M68K_FORMAT_0, 0x08);
                    772:   }
                    773:   
                    774:   /* we have processed all exceptions - resume execution: */
                    775:   ic->_tme_m68k_exceptions = 0;
                    776:   ic->_tme_m68k_mode = TME_M68K_MODE_EXECUTION;
                    777:   TME_M68K_SEQUENCE_START;
                    778:   tme_m68k_redispatch(ic);
                    779: }
                    780: 
                    781: /* this starts an m68k RTE: */
                    782: tme_uint16_t
                    783: tme_m68k_rte_start(struct tme_m68k *ic)
                    784: {
                    785: 
                    786:   /* set up to read from the stack frame: */
                    787:   ic->_tme_m68k_ea_function_code = TME_M68K_FC_SD;
                    788:   ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_a7;
                    789: 
                    790:   /* read the stacked status register: */
                    791:   tme_m68k_read_mem16(ic, TME_M68K_IREG_SHADOW_SR);
                    792:   ic->_tme_m68k_ea_address += sizeof(ic->tme_m68k_ireg_shadow_sr);
                    793: 
                    794:   /* read the stacked PC: */
                    795:   tme_m68k_read_mem32(ic, TME_M68K_IREG_PC_NEXT);
                    796:   ic->_tme_m68k_ea_address += sizeof(ic->tme_m68k_ireg_pc_next);
                    797: 
                    798:   /* read the stacked format/offset word, unless this is a 68000: */
                    799:   if (ic->tme_m68k_type != TME_M68K_M68000) {
                    800:     tme_m68k_read_mem16(ic, TME_M68K_IREG_FORMAT_OFFSET);
                    801:     ic->_tme_m68k_ea_address += sizeof(ic->tme_m68k_ireg_format_offset);
                    802:   }
                    803:   else {
                    804:     ic->tme_m68k_ireg_format_offset = 0;
                    805:   }
                    806: 
                    807:   /* return the frame format: */
                    808:   return (ic->tme_m68k_ireg_format_offset >> 12);
                    809: }
                    810: 
                    811: /* this finishes an m68k RTE: */
                    812: void
                    813: tme_m68k_rte_finish(struct tme_m68k *ic, tme_uint32_t format_extra)
                    814: {
                    815:   tme_uint32_t frame_size;
                    816: 
                    817:   /* calculate the total frame size.  the 68000 doesn't have a
                    818:      format/status word: */
                    819:   frame_size = (sizeof(ic->tme_m68k_ireg_shadow_sr)
                    820:                + sizeof(ic->tme_m68k_ireg_pc_next)
                    821:                + (ic->tme_m68k_type != TME_M68K_M68000
                    822:                   ? sizeof(ic->tme_m68k_ireg_format_offset)
                    823:                   : 0)
                    824:                + format_extra);
                    825:   assert((frame_size & 1) == 0);
                    826: 
                    827:   /* adjust the stack: */
                    828:   ic->tme_m68k_ireg_a7 += frame_size;
                    829:   
                    830:   /* set the status register: */
                    831:   tme_m68k_change_sr(ic, ic->tme_m68k_ireg_shadow_sr);
                    832:                     
                    833:   /* set the PC: */
                    834:   ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
                    835:   
                    836:   /* redispatch: */
                    837:   tme_m68k_redispatch(ic);
                    838: }
                    839: 
                    840: /* this stores the group 0 sequence into a region of host memory.
                    841:    this is used when preparing the state information to be stored
                    842:    on the stack for a bus or address error: */
                    843: int
                    844: tme_m68k_sequence_empty(const struct tme_m68k *ic, tme_uint8_t *raw, unsigned int raw_avail)
                    845: {
                    846:   const struct _tme_m68k_sequence *sequence;
                    847:   unsigned int raw_used;
                    848:   
                    849:   /* get the group 0 sequence: */
                    850:   sequence = &ic->_tme_m68k_group0_sequence;
                    851:   raw_used = 0;
                    852: 
                    853:   /* we use 8 bits for the mode (2 bits) and flags (6 bits): */
                    854:   raw_used += sizeof(tme_uint8_t);
                    855:   assert(raw_avail >= raw_used);
                    856:   assert(sequence->_tme_m68k_sequence_mode < TME_BIT(2));
                    857:   assert(sequence->_tme_m68k_sequence_mode_flags < TME_BIT(6));
                    858:   *(raw++) = ((sequence->_tme_m68k_sequence_mode << 6)
                    859:              | sequence->_tme_m68k_sequence_mode_flags);
                    860:   
                    861: 
                    862:   /* we use 16 bits for the faulted memory transfer ordinal
                    863:      (12 bits) and already-transferred byte count (4 bits): */
                    864:   raw_used += sizeof(tme_uint16_t);
                    865:   assert(raw_avail >= raw_used);
                    866:   assert(sequence->_tme_m68k_sequence_transfer_faulted < TME_BIT(12));
                    867:   assert(sequence->_tme_m68k_sequence_transfer_faulted_after < TME_BIT(4));
                    868:   *(raw++) = sequence->_tme_m68k_sequence_transfer_faulted >> 4;
                    869:   *(raw++) = ((sequence->_tme_m68k_sequence_transfer_faulted << 4)
                    870:              | sequence->_tme_m68k_sequence_transfer_faulted_after);
                    871: 
                    872: #ifdef _TME_M68K_VERIFY
                    873:   /* we use sizeof(_tme_m68k_sequence_uid) bytes for the sequence UID: */
                    874:   raw_used += sizeof(sequence->_tme_m68k_sequence_uid);
                    875:   assert(raw_avail >= raw_used);
                    876:   memcpy(raw,
                    877:         &sequence->_tme_m68k_sequence_uid,
                    878:         sizeof(sequence->_tme_m68k_sequence_uid));
                    879:   raw += sizeof(sequence->_tme_m68k_sequence_uid);
                    880: #endif /* _TME_M68K_VERIFY */
                    881: 
                    882:   /* done: */
                    883:   return (raw_used);
                    884: }
                    885: 
                    886: /* this restores the group 0 sequence from a region of host memory.
                    887:    this is used when reading the state information stored on the
                    888:    stack for a bus or address error: */
                    889: int
                    890: tme_m68k_sequence_fill(struct tme_m68k *ic, const tme_uint8_t *raw, unsigned int raw_avail)
                    891: {
                    892:   struct _tme_m68k_sequence *sequence;
                    893:   unsigned int raw_used;
                    894:   
                    895:   /* get the group 0 sequence: */
                    896:   sequence = &ic->_tme_m68k_group0_sequence;
                    897:   raw_used = 0;
                    898: 
                    899:   /* we used 8 bits for the mode (2 bits) and flags (6 bits): */
                    900:   raw_used += sizeof(tme_uint8_t);
                    901:   if (raw_avail < raw_used) {
                    902:     return (-1);
                    903:   }
                    904:   sequence->_tme_m68k_sequence_mode = *raw >> 6;
                    905:   sequence->_tme_m68k_sequence_mode_flags = (*(raw++) & (TME_BIT(6) - 1));
                    906: 
                    907:   /* we used 16 bits for the faulted memory transfer ordinal
                    908:      (12 bits) and already-transferred byte count (4 bits): */
                    909:   raw_used += sizeof(tme_uint16_t);
                    910:   if (raw_avail < raw_used) {
                    911:     return (-1);
                    912:   }
                    913:   sequence->_tme_m68k_sequence_transfer_faulted = 
                    914:     (((tme_uint16_t) raw[0]) << 4)
                    915:     | (raw[1] >> 4);
                    916:   sequence->_tme_m68k_sequence_transfer_faulted_after = raw[1] & (TME_BIT(4) - 1);
                    917:   raw += sizeof(tme_uint16_t);
                    918: 
                    919: #ifdef _TME_M68K_VERIFY
                    920:   /* we used sizeof(_tme_m68k_sequence_uid) bytes for the sequence UID: */
                    921:   raw_used += sizeof(sequence->_tme_m68k_sequence_uid);
                    922:   if (raw_avail < raw_used) {
                    923:     return (-1);
                    924:   }
                    925:   memcpy(&sequence->_tme_m68k_sequence_uid,
                    926:         raw,
                    927:         sizeof(sequence->_tme_m68k_sequence_uid));
                    928:   raw += sizeof(sequence->_tme_m68k_sequence_uid);
                    929: #endif /* _TME_M68K_VERIFY */
                    930: 
                    931:   /* initialize this to one: */
                    932:   sequence->_tme_m68k_sequence_transfer_next = 1;
                    933: 
                    934:   /* done: */
                    935:   return (raw_used);
                    936: }
                    937: 
                    938: /* this transfers the instruction buffer to or from a region of host
                    939:    memory.  unlike the raw region in host memory, where the 16- and
                    940:    32-bit parts of the instruction are contiguous and therefore
                    941:    potentially misaligned, in the instruction buffer these instruction
                    942:    parts are all properly aligned.  given the instruction buffer, a
                    943:    contiguous host memory buffer, a count of instruction bytes and the
                    944:    sizes of the instruction fetches, this transfers from one buffer to
                    945:    the other.
                    946: 
                    947:    this is used to fill the instruction buffer when we're restoring
                    948:    our state from an exception stack or when we fault anywhere inside
                    949:    the fast executor, and it's used to empty the instruction buffer
                    950:    into an exception stack when we fault: */
                    951: int
                    952: tme_m68k_insn_buffer_xfer(struct tme_m68k *ic, tme_uint8_t *raw, unsigned int raw_avail, int what)
                    953: {
                    954:   int fill, sanity_assert;
                    955:   tme_uint16_t fetch_total;
                    956:   tme_uint16_t fetch_sizes;
                    957:   unsigned int fetch_sizes_bits;
                    958:   unsigned int insn_buffer_off, fetch_off, fetch_size, resid;
                    959: #define _FETCH_SIZES_BITS (8 * sizeof(ic->_tme_m68k_insn_buffer_fetch_sizes))
                    960: #define _FETCH_SIZE_BIT (1 << (_FETCH_SIZES_BITS - 1))
                    961: #define _FETCH_SANITY(e) \
                    962: do { \
                    963:   if (sanity_assert) \
                    964:     assert(e); \
                    965:   else if (!(e)) \
                    966:     return (-1); \
                    967: } while (/* CONSTCOND */ 0)
                    968:   
                    969:   /* if what is zero, we faulted somewhere inside the fast executor
                    970:      and we need to fill the instruction buffer from raw host memory: */
                    971:   if (what == 0) {
                    972:     fill = TRUE;
                    973:     sanity_assert = TRUE;
                    974: 
                    975:     /* the fetch total and sizes are in the state: */
                    976:     fetch_total = ic->_tme_m68k_insn_buffer_fetch_total;
                    977:     fetch_sizes = ic->_tme_m68k_insn_buffer_fetch_sizes;
                    978:     raw_avail = fetch_total;
                    979:   }
                    980: 
                    981:   /* else, if what is one, we're emptying the instruction buffer into
                    982:      an exception frame: */
                    983:   else if (what == 1) {
                    984:     fill = FALSE;
                    985:     sanity_assert = TRUE;
                    986: 
                    987:     /* the fetch total and sizes are in the state: */
                    988:     fetch_total = ic->_tme_m68k_insn_buffer_fetch_total;
                    989:     fetch_sizes = ic->_tme_m68k_insn_buffer_fetch_sizes;
                    990: 
                    991:     /* the first word we place into the exception frame is
                    992:        (fetch_sizes << 4) | (fetch_total >> 1): */
                    993:     _FETCH_SANITY(raw_avail >= sizeof(tme_uint16_t));
                    994:     raw[1] = (fetch_sizes << 4) | (fetch_total >> 1);
                    995:     raw[0] = (fetch_sizes >> 4);
                    996:     raw += sizeof(tme_uint16_t);
                    997:     raw_avail -= sizeof(tme_uint16_t);
                    998:   }
                    999: 
                   1000:   /* otherwise, we're filling the instruction buffer from an exception
                   1001:      frame: */
                   1002:   else {
                   1003:     fill = TRUE;
                   1004:     sanity_assert = FALSE;
                   1005: 
                   1006:     /* this function previously emptied the instruction buffer into
                   1007:        this exception frame, and the first big-endian word placed
                   1008:        there is (fetch_sizes << 4) | (fetch_total >> 1): */
                   1009:     _FETCH_SANITY(raw_avail >= sizeof(tme_uint16_t));
                   1010:     fetch_total = (raw[1] & 0x0f) << 1;
                   1011:     fetch_sizes = (raw[0] << 4) | (raw[1] >> 4);
                   1012:     raw += sizeof(tme_uint16_t);
                   1013:     raw_avail -= sizeof(tme_uint16_t);
                   1014:   }
                   1015: 
                   1016:   /* fetch_total must be even, because we only fetch some multiple of
                   1017:      16-bit words: */
                   1018:   _FETCH_SANITY((fetch_total & (sizeof(tme_uint16_t) - 1)) == 0);
                   1019: 
                   1020:   /* fetch_sizes is a bitmask, with a one bit representing a 32-bit
                   1021:      fetch and a zero bit representing a 16-bit fetch, and the least
                   1022:      significant bit is the *last* fetch performed.  count the number
                   1023:      of significant bits in fetch_sizes and confirm that it makes
                   1024:      sense with fetch_total: */
                   1025:   fetch_sizes_bits = 0;
                   1026:   for (fetch_off = 0; fetch_off < fetch_total; ) {
                   1027:     _FETCH_SANITY(fetch_sizes_bits < _FETCH_SIZES_BITS);
                   1028:     fetch_off += ((fetch_sizes & (1 << fetch_sizes_bits))
                   1029:                  /* a 32-bit fetch: */
                   1030:                  ? sizeof(tme_uint32_t)
                   1031:                  /* a 16-bit fetch: */
                   1032:                  : sizeof(tme_uint16_t));
                   1033:     fetch_sizes_bits++;
                   1034:   }
                   1035:   _FETCH_SANITY(fetch_off == fetch_total);
                   1036: 
                   1037:   /* we must have enough raw space available: */
                   1038:   _FETCH_SANITY(raw_avail >= fetch_total);
                   1039: 
                   1040:   /* shift fetch_sizes up so the bit for the first transfer
                   1041:      is the most significant bit: */
                   1042:   fetch_sizes <<= (_FETCH_SIZES_BITS - fetch_sizes_bits);
                   1043: 
                   1044:   /* now fill or empty the instruction buffer: */
                   1045:   insn_buffer_off = 0;
                   1046:   for (fetch_off = 0; fetch_off < fetch_total; ) {
                   1047: 
                   1048:     /* get the size of this fetch: */
                   1049:     fetch_size = ((fetch_sizes & _FETCH_SIZE_BIT)
                   1050:                  /* a 32-bit fetch: */
                   1051:                  ? sizeof(tme_uint32_t)
                   1052:                  /* a 16-bit fetch: */
                   1053:                  : sizeof(tme_uint16_t));
                   1054:     fetch_sizes <<= 1;
                   1055: 
                   1056:     /* do one transfer.  the insn buffer is kept in host byte
                   1057:        order, like the internal registers are: */
                   1058:     insn_buffer_off = TME_ALIGN(insn_buffer_off, fetch_size);
                   1059:     if (fill) {
                   1060:       for (resid = fetch_size; resid-- > 0; ) {
                   1061:        ic->_tme_m68k_insn_buffer[(insn_buffer_off
                   1062:                                   + (resid
                   1063: #ifndef WORDS_BIGENDIAN
                   1064:                                      ^ (fetch_size - 1)
                   1065: #endif /* !WORDS_BIGENDIAN */
                   1066:                                      ))] 
                   1067:          = raw[fetch_off + resid];
                   1068:       }
                   1069:     }
                   1070:     else {
                   1071:       for (resid = fetch_size; resid-- > 0; ) {
                   1072:        raw[fetch_off + resid] = 
                   1073:          ic->_tme_m68k_insn_buffer[(insn_buffer_off
                   1074:                                     + (resid
                   1075: #ifndef WORDS_BIGENDIAN
                   1076:                                        ^ (fetch_size - 1)
                   1077: #endif /* !WORDS_BIGENDIAN */
                   1078:                                        ))];
                   1079:       }
                   1080:     }
                   1081:     insn_buffer_off += fetch_size;
                   1082:     fetch_off += fetch_size;
                   1083: 
                   1084:     /* if we faulted somewhere in the fast executor, we need to
                   1085:        account for the instruction fetches in the group0 sequence: */
                   1086:     if (what == 0) {
                   1087:       ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_next++;
                   1088:     }
                   1089:   }
                   1090: 
                   1091:   /* NB: for total consistency we might want to store the fetch total
                   1092:      and sizes into the state when we're filling the instruction
                   1093:      buffer from an execution frame.  however this isn't really needed
                   1094:      because the fetch pattern from the restarting slow executor
                   1095:      should be exactly the same and it doesn't care anyways. 
                   1096:      if the user bashes the exception frame all bets are off. */
                   1097: 
                   1098:   /* return the number of bytes we put in an exception frame: */
                   1099:   return (sizeof(tme_uint16_t) + fetch_total);
                   1100: }
                   1101: 
                   1102: /* this is the group 0 fault hook for the fast executor: */
                   1103: void
                   1104: tme_m68k_group0_hook_fast(struct tme_m68k *ic)
                   1105: {
                   1106:   struct tme_m68k_tlb *tlb;
                   1107:   tme_uint8_t *raw;
                   1108: 
                   1109:   /* fill the instruction buffer and increase the transfer count
                   1110:      as if the slow executor had been doing the fetching: */
                   1111:   tlb = TME_ATOMIC_READ(struct tme_m68k_tlb *, ic->_tme_m68k_itlb);
                   1112:   raw = tlb->tme_m68k_tlb_emulator_off_read + ic->tme_m68k_ireg_pc;
                   1113:   tme_m68k_insn_buffer_xfer(ic, raw, 0, 0);
                   1114: }
                   1115: 
                   1116: /* this starts a read/modify/write cycle.  this works in conjunction
                   1117:    with the tme_m68k_readSIZE() and tme_m68k_writeSIZE() functions to
                   1118:    aggregate many bus transactions into a larger transaction: */
                   1119: struct tme_m68k_tlb *
                   1120: tme_m68k_rmw_start(struct tme_m68k *ic)
                   1121: {
                   1122:   struct tme_m68k_tlb *tlb;
                   1123: 
                   1124:   /* if the user reran the cycle, do nothing: */
                   1125:   if (TME_M68K_SEQUENCE_RESTARTING
                   1126:       && (ic->_tme_m68k_group0_buffer_read_softrr > 0
                   1127:          || ic->_tme_m68k_group0_buffer_write_softrr > 0)) {
                   1128:     return (NULL);
                   1129:   }
                   1130: 
                   1131:   /* we always rerun read/modify/write cycles in their entirety: */
                   1132:   ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted
                   1133:     = ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next - 1;
                   1134: 
                   1135:   /* get an applicable TLB entry: */
                   1136:   tlb = TME_M68K_TLB_ENTRY(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address);
                   1137: 
                   1138:   /* we *must* guarantee that a read/modify/write cycle be atomic.
                   1139:      unfortunately, the only way we can really do that is to acquire a
                   1140:      single lock, now, that somehow protects all of the things we want
                   1141:      to do, and hold that lock for the duration.
                   1142: 
                   1143:      the only way we can do this is to require that read/modify/write
                   1144:      cycles always involve TLB entries that allow fast reads and
                   1145:      writes.  this gives us a single rwlock that we can lock for
                   1146:      writing now and hold until we're done: */
                   1147: 
                   1148:   /* we invalidate the TLB entry so we can set the TLB rwlock to NULL,
                   1149:      which is seen by the first tme_m68k_readSIZE (or
                   1150:      tme_m68k_writeSIZE, in the bizarre case that that's called first)
                   1151:      as a signal that, after it reloads the TLB entry, it has to lock
                   1152:      the rwlock: */
                   1153:   tme_bus_tlb_invalidate(&tlb->tme_m68k_tlb_bus_tlb);
                   1154:   tlb->tme_m68k_tlb_bus_rwlock = NULL;
                   1155: 
                   1156:   return (tlb);
                   1157: }
                   1158: 
                   1159: /* this finishes a read/modify/write cycle.  this works in conjunction
                   1160:    with the tme_m68k_readSIZE() and tme_m68k_writeSIZE() functions to
                   1161:    aggregate many bus transactions into a larger transaction: */
                   1162: void
                   1163: tme_m68k_rmw_finish(struct tme_m68k *ic, struct tme_m68k_tlb *tlb)
                   1164: {
                   1165:   
                   1166:   /* if we didn't acquire the rwlock, something is wrong: */
                   1167:   assert(tlb->tme_m68k_tlb_bus_rwlock != NULL);
                   1168:   
                   1169:   /* unlock the lock: */
                   1170:   tme_rwlock_unlock(tlb->tme_m68k_tlb_bus_rwlock);
                   1171: }
                   1172: 
                   1173: /* this handles a bitfield offset.  if the bitfield is in memory,
                   1174:    and it hasn't already been done, this adjusts the effective
                   1175:    address to point to the beginning of the bitfield.  this always
                   1176:    returns a nonnegative bitfield offset: */
                   1177: unsigned int
                   1178: tme_m68k_bitfield_offset(struct tme_m68k *ic, int adjust)
                   1179: {
                   1180:   tme_int16_t specop;
                   1181:   tme_int32_t bf_offset;
                   1182:   tme_int32_t bf_ea_offset;
                   1183:     
                   1184:   /* get the bitfield offset from a data register or as an immediate: */
                   1185:   specop = ic->_tme_m68k_insn_specop;
                   1186:   bf_offset = ((specop & TME_BIT(11))
                   1187:               ? ic->tme_m68k_ireg_int32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specop, 6, 3))
                   1188:               : (tme_int32_t) TME_FIELD_EXTRACTU(specop, 6, 5));
                   1189: 
                   1190:   /* if this bitfield is in a register (EA mode field is zero): */
                   1191:   if (TME_FIELD_EXTRACTU(ic->_tme_m68k_insn_opcode, 3, 3) == 0) {
                   1192: 
                   1193:     /* adjust the bitfield offset to be nonnegative: */
                   1194:     bf_offset &= 31;
                   1195:   }
                   1196: 
                   1197:   /* otherwise, this bitfield is in memory: */
                   1198:   else {
                   1199: 
                   1200:     /* calculate the effective address offset and adjust the bitfield
                   1201:        offset to be nonnegative: */
                   1202:     bf_ea_offset = ((bf_offset < 0)
                   1203:                    ? ((bf_offset + 1) / 8) - 1
                   1204:                    : bf_offset / 8);
                   1205:     bf_offset &= 7;
                   1206: 
                   1207:     /* if this is our first call to this function for this instruction
                   1208:        and we're not restarting, adjust the effective address: */
                   1209:     if (adjust
                   1210:        && !TME_M68K_SEQUENCE_RESTARTING) {
                   1211:       ic->_tme_m68k_ea_address += bf_ea_offset;
                   1212:     }
                   1213:   }
                   1214: 
                   1215:   /* return the nonnegative bitfield offset: */
                   1216:   return ((unsigned int) bf_offset);
                   1217: }
                   1218: 
                   1219: /* this returns a bitfield width: */
                   1220: unsigned int
                   1221: tme_m68k_bitfield_width(struct tme_m68k *ic)
                   1222: {
                   1223:   unsigned int bf_width;
                   1224:   tme_int16_t specop;
                   1225: 
                   1226:   /* get the bitfield width from a register or as an immediate: */
                   1227:   specop = ic->_tme_m68k_insn_specop;
                   1228:   if (specop & TME_BIT(5)) {
                   1229:     bf_width = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specop, 0, 3));
                   1230:   }
                   1231:   else {
                   1232:     bf_width = TME_FIELD_EXTRACTU(specop, 0, 5);
                   1233:   }
                   1234:   bf_width &= 31;
                   1235:   if (bf_width == 0) bf_width = 32;
                   1236:   return (bf_width);
                   1237: }
                   1238: 
                   1239: /* this reads a bitfield: */
                   1240: tme_uint32_t
                   1241: _tme_m68k_bitfield_read(struct tme_m68k *ic, int is_signed)
                   1242: {
                   1243:   unsigned int bf_offset, bf_width;
                   1244:   unsigned int shift;
                   1245:   tme_uint8_t *bf_bytes;
                   1246:   tme_uint32_t bf_value;
                   1247:   int ireg;
                   1248: 
                   1249:   /* get the bitfield offset and width: */
                   1250:   bf_offset = tme_m68k_bitfield_offset(ic, TRUE);
                   1251:   bf_width = tme_m68k_bitfield_width(ic);
                   1252: 
                   1253:   /* if this expression is > 32, in a register this means the bitfield
                   1254:      wraps, and in memory this means the bitfield is 5-bytes wide: */
                   1255:   shift = (bf_offset + bf_width);
                   1256: 
                   1257:   /* if this bitfield is in a register (EA mode field is zero): */
                   1258:   if (TME_FIELD_EXTRACTU(ic->_tme_m68k_insn_opcode, 3, 3) == 0) {
                   1259:     ireg = (TME_M68K_IREG_D0
                   1260:            + TME_FIELD_EXTRACTU(ic->_tme_m68k_insn_opcode, 0, 3));
                   1261: 
                   1262:     /* get the raw 32-bit word containing the bitfield: */
                   1263:     bf_value = ic->tme_m68k_ireg_uint32(ireg);
                   1264: 
                   1265:     /* if this bitfield wraps the register, shift in the wrapped part
                   1266:        on the right: */
                   1267:     if (shift > 32) {
                   1268:       shift -= 32;
                   1269:       bf_value = (bf_value << shift) | (bf_value >> (32 - shift));
                   1270:       bf_offset -= shift;
                   1271:     }
                   1272:   }
                   1273: 
                   1274:   /* otherwise, this bitfield is in memory: */
                   1275:   else {
                   1276: 
                   1277:     /* read in the bytes covering the bitfield: */
                   1278:     bf_bytes = (tme_uint8_t *) &ic->tme_m68k_ireg_memx32;
                   1279:     tme_m68k_read_mem(ic, bf_bytes, (bf_offset + bf_width + 7) >> 3);
                   1280: 
                   1281:     /* get the raw 32-bit word containing the bitfield: */
                   1282:     bf_value = tme_betoh_u32(ic->tme_m68k_ireg_memx32);
                   1283: 
                   1284:     /* if this bitfield is 5 bytes wide, shift in the part from the fifth byte
                   1285:        (actually in memy32!) on the right: */
                   1286:     if (shift > 32) {
                   1287:       shift -= 32;
                   1288:       bf_value = (bf_value << shift) | (bf_bytes[4] >> (8 - shift));
                   1289:       bf_offset -= shift;
                   1290:     }
                   1291:   }
                   1292:   
                   1293:   /* shift the value: */
                   1294:   shift = (32 - (bf_offset + bf_width));
                   1295:   bf_value >>= shift;
                   1296: 
                   1297:   /* mask the value: */
                   1298:   bf_value &= TME_BIT(bf_width) - 1;
                   1299: 
                   1300:   /* if this is a signed value, sign-extend it: */
                   1301:   if (is_signed
                   1302:       && (bf_value & TME_BIT(bf_width - 1))) {
                   1303:     bf_value |= (0xffffffff ^ (TME_BIT(bf_width) - 1));
                   1304:   }
                   1305: 
                   1306:   /* all bitfield instructions that read the bitfield set the flags: */
                   1307:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1308:     ic->tme_m68k_ireg_ccr = ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X)
                   1309:                             | ((bf_value & TME_BIT(bf_width - 1))
                   1310:                                ? TME_M68K_FLAG_N
                   1311:                                : 0)
                   1312:                             | (bf_value
                   1313:                                ? 0
                   1314:                                : TME_M68K_FLAG_Z));
                   1315:   }
                   1316: 
                   1317:   /* return the bitfield value: */
                   1318:   return (bf_value);
                   1319: }
                   1320: 
                   1321: /* this writes a bitfield to memory: */
                   1322: void
                   1323: tme_m68k_bitfield_write_unsigned(struct tme_m68k *ic, tme_uint32_t bf_value, int set_flags)
                   1324: {
                   1325:   unsigned int bf_offset, bf_width;
                   1326:   unsigned int shift;
                   1327:   tme_uint8_t *bf_bytes;
                   1328:   unsigned int count;
                   1329:   int ireg;
                   1330: 
                   1331:   /* for bitfields in memory, we want to know if the memory covering
                   1332:      the bitfield is already in our memory buffer, so we can avoid
                   1333:      reading that memory again.  all bitfield instructions set flags
                   1334:      based on a bitfield value; if set_flags is FALSE our caller
                   1335:      must have tested the old bitfield value, and so the bitfield
                   1336:      memory must be in our buffer, otherwise assume that this is our
                   1337:      first access to the bitfield memory: */
                   1338: #define first_memory set_flags
                   1339:   
                   1340:   /* get the bitfield offset and width: */
                   1341:   bf_offset = tme_m68k_bitfield_offset(ic, first_memory);
                   1342:   bf_width = tme_m68k_bitfield_width(ic);
                   1343: 
                   1344:   /* if this expression is > 32, in a register this means the bitfield
                   1345:      wraps, and in memory this means the bitfield is 5-bytes wide: */
                   1346:   shift = (bf_offset + bf_width);
                   1347: 
                   1348:   /* if we're supposed to, set the flags: */
                   1349:   if (set_flags
                   1350:       && !TME_M68K_SEQUENCE_RESTARTING) {
                   1351:     ic->tme_m68k_ireg_ccr = ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X)
                   1352:                             | ((bf_value & TME_BIT(bf_width - 1))
                   1353:                                ? TME_M68K_FLAG_N
                   1354:                                : 0)
                   1355:                             | (bf_value
                   1356:                                ? 0
                   1357:                                : TME_M68K_FLAG_Z));
                   1358:   }
                   1359: 
                   1360:   /* mask the value: */
                   1361:   bf_value &= TME_BIT(bf_width) - 1;
                   1362: 
                   1363:   /* if this bitfield is in a register (EA mode field is zero): */
                   1364:   if (TME_FIELD_EXTRACTU(ic->_tme_m68k_insn_opcode, 3, 3) == 0) {
                   1365:     ireg = (TME_M68K_IREG_D0
                   1366:            + TME_FIELD_EXTRACTU(ic->_tme_m68k_insn_opcode, 0, 3));
                   1367:     
                   1368:     /* if this bitfield wraps the register, put the wrapped
                   1369:        part in the left: */
                   1370:     if (shift > 32) {
                   1371:       shift -= 32;
                   1372:       ic->tme_m68k_ireg_uint32(ireg) = ((ic->tme_m68k_ireg_uint32(ireg)
                   1373:                                         & (0xffffffffUL >> shift))
                   1374:                                        | (bf_value << (32 - shift)));
                   1375:       bf_value >>= shift;
                   1376:       bf_width -= shift;
                   1377:     }
                   1378:     
                   1379:     /* update the register: */
                   1380:     shift = (32 - (bf_offset + bf_width));
                   1381:     ic->tme_m68k_ireg_uint32(ireg) = ((ic->tme_m68k_ireg_uint32(ireg)
                   1382:                                       & ((TME_BIT(bf_width) - 1) << shift))
                   1383:                                      | (bf_value << shift));
                   1384:   }
                   1385: 
                   1386:   /* otherwise, this bitfield is in memory: */
                   1387:   else {
                   1388: 
                   1389:     /* read in the bytes covering the bitfield if we haven't yet: */
                   1390:     bf_bytes = (tme_uint8_t *) &ic->tme_m68k_ireg_memx32;
                   1391:     count = (bf_offset + bf_width + 7) >> 3;
                   1392:     if (first_memory) {
                   1393:       tme_m68k_read_mem(ic, bf_bytes, count);
                   1394:     }
                   1395: 
                   1396:     /* if this bitfield is 5 bytes wide, put the part for the fifth
                   1397:        byte (actually in memy32!) in on the left: */
                   1398:     if (shift > 32) {
                   1399:       shift -= 32;
                   1400:       if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1401:        bf_bytes[4] = ((bf_bytes[4]
                   1402:                        & (0xff >> shift))
                   1403:                       | ((bf_value & 0xff) << (8 - shift)));
                   1404:       }
                   1405:       bf_value >>= shift;
                   1406:       bf_width -= shift;
                   1407:     }
                   1408: 
                   1409:     /* update the memory buffer: */
                   1410:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1411:       shift = (32 - (bf_offset + bf_width));
                   1412:       ic->tme_m68k_ireg_memx32 =
                   1413:        tme_htobe_u32((tme_betoh_u32(ic->tme_m68k_ireg_memx32)
                   1414:                       & ((TME_BIT(bf_width) - 1) << shift))
                   1415:                      | (bf_value << shift));
                   1416:     }
                   1417: 
                   1418:     /* write out the bytes covering bitfield to memory: */
                   1419:     tme_m68k_write_mem(ic, bf_bytes, count);
                   1420:   }
                   1421: #undef first_memory
                   1422: }
                   1423: 
                   1424: #ifdef _TME_M68K_VERIFY
                   1425: /* our global verify hook function: */
                   1426: void
                   1427: tme_m68k_verify_hook(void)
                   1428: {
                   1429: }
                   1430: #endif /* _TME_M68K_VERIFY */
                   1431: 
                   1432: #if 1
                   1433: #include <stdio.h>
                   1434: 
                   1435: /* this dumps out the m68k state: */
                   1436: void
                   1437: tme_m68k_dump(struct tme_m68k *ic)
                   1438: {
                   1439:   int ireg;
                   1440:   int count;
                   1441: 
                   1442:   /* dump out the integer registers: */
                   1443:   count = 0;
                   1444:   for (ireg = TME_M68K_IREG_D0;
                   1445:        ireg <= TME_M68K_IREG_A7;
                   1446:        ireg++) {
                   1447:     fprintf(stderr,
                   1448:            "%%%c%d[%p] = 0x%08x",
                   1449:            (ireg < TME_M68K_IREG_A0
                   1450:             ? 'd'
                   1451:             : 'a'),
                   1452:            ireg - (ireg < TME_M68K_IREG_A0
                   1453:                    ? TME_M68K_IREG_D0
                   1454:                    : TME_M68K_IREG_A0),
                   1455:            &ic->tme_m68k_ireg_uint32(ireg),
                   1456:            ic->tme_m68k_ireg_uint32(ireg));
                   1457:     if (++count == 2) {
                   1458:       fprintf(stderr, "\n");
                   1459:       count = 0;
                   1460:     }
                   1461:     else {
                   1462:       fprintf(stderr, "  ");
                   1463:     }
                   1464:   }
                   1465: 
                   1466:   /* dump out the PC and next PC: */
                   1467:   fprintf(stderr, "%%pc = 0x%08x  %%pc_next = 0x%08x\n",
                   1468:          ic->tme_m68k_ireg_pc,
                   1469:          ic->tme_m68k_ireg_pc_next);
                   1470: 
                   1471:   /* dump out the status register: */
                   1472:   fprintf(stderr, "%%sr = 0x%04x", ic->tme_m68k_ireg_sr);
                   1473:   fprintf(stderr, "  flags:");
                   1474:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) {
                   1475:     fprintf(stderr, " X");
                   1476:   }
                   1477:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_N) {
                   1478:     fprintf(stderr, " N");
                   1479:   }
                   1480:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
                   1481:     fprintf(stderr, " Z");
                   1482:   }
                   1483:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_V) {
                   1484:     fprintf(stderr, " V");
                   1485:   }
                   1486:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_C) {
                   1487:     fprintf(stderr, " C");
                   1488:   }
                   1489:   fprintf(stderr, "\n");
                   1490: 
                   1491:   /* dump out the effective address and memory buffers: */
                   1492:   fprintf(stderr, "\n");
                   1493:   fprintf(stderr, "EA = %d:0x%08x\n",
                   1494:          ic->_tme_m68k_ea_function_code,
                   1495:          ic->_tme_m68k_ea_address);
                   1496:   fprintf(stderr, "%%memx[%p] = 0x%08x  %%memy[%p] = 0x%08x\n",
                   1497:          &ic->tme_m68k_ireg_memx32,
                   1498:          ic->tme_m68k_ireg_memx32,
                   1499:          &ic->tme_m68k_ireg_memy32,
                   1500:          ic->tme_m68k_ireg_memy32);
                   1501: 
                   1502:   /* dump out the control registers: */
                   1503:   fprintf(stderr, "\n");
                   1504:   fprintf(stderr, "%%usp = 0x%08x\n", ic->tme_m68k_ireg_usp);
                   1505:   fprintf(stderr, "%%isp = 0x%08x\n", ic->tme_m68k_ireg_isp);
                   1506:   fprintf(stderr, "%%msp = 0x%08x\n", ic->tme_m68k_ireg_msp);
                   1507:   fprintf(stderr, "%%sfc = 0x%08x\n", ic->tme_m68k_ireg_sfc);
                   1508:   fprintf(stderr, "%%dfc = 0x%08x\n", ic->tme_m68k_ireg_dfc);
                   1509:   fprintf(stderr, "%%vbr = 0x%08x\n", ic->tme_m68k_ireg_vbr);
                   1510:   
                   1511:   /* dump out instruction decoding information: */
                   1512:   fprintf(stderr, "\n");
                   1513:   fprintf(stderr, "opcode = 0x%04x  specop = 0x%04x  specop2 = 0x%04x\n",
                   1514:          ic->_tme_m68k_insn_opcode,
                   1515:          ic->_tme_m68k_insn_specop,
                   1516:          ic->_tme_m68k_insn_specop2);
                   1517: }
                   1518: #endif /* 1 */

unix.superglobalmegacorp.com

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