Annotation of tme/ic/m68k/m68k-insns-auto.c, revision 1.1.1.6

1.1       root        1: /* automatically generated by m68k-insns-auto.sh, do not edit! */
1.1.1.5   root        2: _TME_RCSID("$Id: m68k-insns-auto.sh,v 1.26 2009/08/29 19:38:23 fredette Exp $");
1.1       root        3: 
                      4: #include "m68k-impl.h"
                      5: 
                      6: 
                      7: /* this does a 8-bit "add SRC, DST": */
                      8: TME_M68K_INSN(tme_m68k_add8)
                      9: {
                     10:   tme_uint8_t res, op0, op1;
                     11:   tme_uint8_t flags;
                     12: 
                     13:   /* load the operand(s): */
                     14:   op0 = *((tme_uint8_t *) _op0);
                     15:   op1 = *((tme_uint8_t *) _op1);
                     16: 
                     17:   /* perform the operation: */
                     18:   res = op1 + op0;
                     19: 
                     20:   /* store the result: */
                     21:   *((tme_uint8_t *) _op1) = res;
                     22: 
                     23:   /* set the flags: */
                     24:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                     25:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                     26:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xff) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
                     27:   if (op0 > (op1 ^ 0xff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                     28:   ic->tme_m68k_ireg_ccr = flags;
                     29: 
                     30:   TME_M68K_INSN_OK;
                     31: }
                     32: 
                     33: /* this does a 8-bit "sub SRC, DST": */
                     34: TME_M68K_INSN(tme_m68k_sub8)
                     35: {
                     36:   tme_uint8_t res, op0, op1;
                     37:   tme_uint8_t flags;
                     38: 
                     39:   /* load the operand(s): */
                     40:   op0 = *((tme_uint8_t *) _op0);
                     41:   op1 = *((tme_uint8_t *) _op1);
                     42: 
                     43:   /* perform the operation: */
                     44:   res = op1 - op0;
                     45: 
                     46:   /* store the result: */
                     47:   *((tme_uint8_t *) _op1) = res;
                     48: 
                     49:   /* set the flags: */
                     50:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                     51:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                     52:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
                     53:   if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                     54:   ic->tme_m68k_ireg_ccr = flags;
                     55: 
                     56:   TME_M68K_INSN_OK;
                     57: }
                     58: 
                     59: /* this does a 8-bit "cmp SRC, DST": */
                     60: TME_M68K_INSN(tme_m68k_cmp8)
                     61: {
                     62:   tme_uint8_t res, op0, op1;
                     63:   tme_uint8_t flags;
                     64: 
                     65:   /* load the operand(s): */
                     66:   op0 = *((tme_uint8_t *) _op0);
                     67:   op1 = *((tme_uint8_t *) _op1);
                     68: 
                     69:   /* perform the operation: */
                     70:   res = op1 - op0;
                     71: 
                     72:   /* set the flags: */
                     73:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                     74:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                     75:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
                     76:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
                     77:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                     78:   ic->tme_m68k_ireg_ccr = flags;
                     79: 
                     80:   TME_M68K_INSN_OK;
                     81: }
                     82: 
                     83: /* this does a 8-bit "neg DST": */
                     84: TME_M68K_INSN(tme_m68k_neg8)
                     85: {
                     86:   tme_uint8_t res, op1;
                     87:   tme_uint8_t flags;
                     88: 
                     89:   /* load the operand(s): */
                     90:   op1 = *((tme_uint8_t *) _op1);
                     91: 
                     92:   /* perform the operation: */
                     93:   res = 0 - op1;
                     94: 
                     95:   /* store the result: */
                     96:   *((tme_uint8_t *) _op1) = res;
                     97: 
                     98:   /* set the flags: */
                     99:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    100:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    101:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
                    102:   if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                    103:   ic->tme_m68k_ireg_ccr = flags;
                    104: 
                    105:   TME_M68K_INSN_OK;
                    106: }
                    107: 
                    108: /* this does a 8-bit "or SRC, DST": */
                    109: TME_M68K_INSN(tme_m68k_or8)
                    110: {
                    111:   tme_uint8_t res, op0, op1;
                    112:   tme_uint8_t flags;
                    113: 
                    114:   /* load the operand(s): */
                    115:   op0 = *((tme_uint8_t *) _op0);
                    116:   op1 = *((tme_uint8_t *) _op1);
                    117: 
                    118:   /* perform the operation: */
                    119:   res = op1 | op0;
                    120: 
                    121:   /* store the result: */
                    122:   *((tme_uint8_t *) _op1) = res;
                    123: 
                    124:   /* set the flags: */
                    125:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    126:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    127:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    128:   ic->tme_m68k_ireg_ccr = flags;
                    129: 
                    130:   TME_M68K_INSN_OK;
                    131: }
                    132: 
                    133: /* this does a 8-bit "and SRC, DST": */
                    134: TME_M68K_INSN(tme_m68k_and8)
                    135: {
                    136:   tme_uint8_t res, op0, op1;
                    137:   tme_uint8_t flags;
                    138: 
                    139:   /* load the operand(s): */
                    140:   op0 = *((tme_uint8_t *) _op0);
                    141:   op1 = *((tme_uint8_t *) _op1);
                    142: 
                    143:   /* perform the operation: */
                    144:   res = op1 & op0;
                    145: 
                    146:   /* store the result: */
                    147:   *((tme_uint8_t *) _op1) = res;
                    148: 
                    149:   /* set the flags: */
                    150:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    151:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    152:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    153:   ic->tme_m68k_ireg_ccr = flags;
                    154: 
                    155:   TME_M68K_INSN_OK;
                    156: }
                    157: 
                    158: /* this does a 8-bit "eor SRC, DST": */
                    159: TME_M68K_INSN(tme_m68k_eor8)
                    160: {
                    161:   tme_uint8_t res, op0, op1;
                    162:   tme_uint8_t flags;
                    163: 
                    164:   /* load the operand(s): */
                    165:   op0 = *((tme_uint8_t *) _op0);
                    166:   op1 = *((tme_uint8_t *) _op1);
                    167: 
                    168:   /* perform the operation: */
                    169:   res = op1 ^ op0;
                    170: 
                    171:   /* store the result: */
                    172:   *((tme_uint8_t *) _op1) = res;
                    173: 
                    174:   /* set the flags: */
                    175:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    176:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    177:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    178:   ic->tme_m68k_ireg_ccr = flags;
                    179: 
                    180:   TME_M68K_INSN_OK;
                    181: }
                    182: 
                    183: /* this does a 8-bit "not DST": */
                    184: TME_M68K_INSN(tme_m68k_not8)
                    185: {
                    186:   tme_uint8_t res, op1;
                    187:   tme_uint8_t flags;
                    188: 
                    189:   /* load the operand(s): */
                    190:   op1 = *((tme_uint8_t *) _op1);
                    191: 
                    192:   /* perform the operation: */
                    193:   res = ~ op1;
                    194: 
                    195:   /* store the result: */
                    196:   *((tme_uint8_t *) _op1) = res;
                    197: 
                    198:   /* set the flags: */
                    199:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    200:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    201:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    202:   ic->tme_m68k_ireg_ccr = flags;
                    203: 
                    204:   TME_M68K_INSN_OK;
                    205: }
                    206: 
                    207: /* this does a 8-bit "tst DST": */
                    208: TME_M68K_INSN(tme_m68k_tst8)
                    209: {
                    210:   tme_uint8_t res, op1;
                    211:   tme_uint8_t flags;
                    212: 
                    213:   /* load the operand(s): */
                    214:   op1 = *((tme_uint8_t *) _op1);
                    215: 
                    216:   /* perform the operation: */
                    217:   res = op1;
                    218: 
                    219:   /* set the flags: */
                    220:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    221:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    222:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    223:   ic->tme_m68k_ireg_ccr = flags;
                    224: 
                    225:   TME_M68K_INSN_OK;
                    226: }
                    227: 
                    228: /* this does a 8-bit "move DST": */
                    229: TME_M68K_INSN(tme_m68k_move8)
                    230: {
                    231:   tme_uint8_t res, op1;
                    232:   tme_uint8_t flags;
                    233: 
                    234:   /* load the operand(s): */
                    235:   op1 = *((tme_uint8_t *) _op1);
                    236: 
                    237:   /* perform the operation: */
                    238:   res = op1;
                    239: 
                    240:   /* store the result: */
                    241:   *((tme_uint8_t *) _op0) = res;
                    242: 
                    243:   /* set the flags: */
                    244:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    245:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    246:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    247:   ic->tme_m68k_ireg_ccr = flags;
                    248: 
                    249:   TME_M68K_INSN_OK;
                    250: }
                    251: 
                    252: /* this does a 8-bit "clr DST": */
                    253: TME_M68K_INSN(tme_m68k_clr8)
                    254: {
                    255:   tme_uint8_t res;
                    256:   tme_uint8_t flags;
                    257: 
                    258:   /* load the operand(s): */
                    259: 
                    260:   /* perform the operation: */
                    261:   res = 0;
                    262: 
                    263:   /* store the result: */
                    264:   *((tme_uint8_t *) _op1) = res;
                    265: 
                    266:   /* set the flags: */
                    267:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    268:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    269:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    270:   ic->tme_m68k_ireg_ccr = flags;
                    271: 
                    272:   TME_M68K_INSN_OK;
                    273: }
                    274: 
                    275: /* this does a 8-bit "negx DST": */
                    276: TME_M68K_INSN(tme_m68k_negx8)
                    277: {
                    278:   tme_uint8_t res, op1;
                    279:   tme_uint8_t flags;
                    280: 
                    281:   /* load the operand(s): */
                    282:   op1 = *((tme_uint8_t *) _op1);
                    283: 
                    284:   /* perform the operation: */
                    285:   res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                    286: 
                    287:   /* store the result: */
                    288:   *((tme_uint8_t *) _op1) = res;
                    289: 
                    290:   /* set the flags: */
                    291:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    292:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                    293:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
                    294:   if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                    295:   ic->tme_m68k_ireg_ccr = flags;
                    296: 
                    297:   TME_M68K_INSN_OK;
                    298: }
                    299: 
                    300: /* this does a 8-bit "addx SRC, DST": */
                    301: TME_M68K_INSN(tme_m68k_addx8)
                    302: {
                    303:   tme_uint8_t res, op0, op1;
                    304:   tme_uint8_t flags;
                    305: 
                    306:   /* load the operand(s): */
                    307:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    308:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                    309:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                    310:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3);
                    311:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3);
                    312:   tme_uint16_t memory;
                    313: 
                    314:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
                    315:   if (memory) {
                    316:     TME_M68K_INSN_CANFAULT;
                    317:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    318:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
                    319:       ic->_tme_m68k_ea_function_code = function_code;
                    320:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                    321:     }
                    322:     tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8);
1.1.1.4   root      323:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    324:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
                    325:       ic->_tme_m68k_ea_function_code = function_code;
                    326:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                    327:     }
                    328:     tme_m68k_read_memx8(ic);
1.1       root      329:     op1 = ic->tme_m68k_ireg_memx8;
                    330:     op0 = ic->tme_m68k_ireg_memy8;
                    331:   }
                    332:   else {
                    333:     op0 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_src) << 2);
                    334:     op1 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2);
                    335:   }
                    336: 
                    337:   /* perform the operation: */
                    338:   res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                    339: 
                    340:   /* store the result: */
                    341:   if (memory) {
                    342:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    343:       ic->tme_m68k_ireg_memx8 = res;
                    344:       ic->_tme_m68k_ea_function_code = function_code;
                    345:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                    346:     }
                    347:     tme_m68k_write_memx8(ic);
                    348:   }
                    349:   else {
                    350:     ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2) = res;
                    351:   }
                    352: 
                    353:   /* set the flags: */
                    354:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    355:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                    356:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xff) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
                    357:   if (op0 > (op1 ^ 0xff) || (op0 == (op1 ^ 0xff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                    358:   ic->tme_m68k_ireg_ccr = flags;
                    359: 
                    360:   TME_M68K_INSN_OK;
                    361: }
                    362: 
                    363: /* this does a 8-bit "subx SRC, DST": */
                    364: TME_M68K_INSN(tme_m68k_subx8)
                    365: {
                    366:   tme_uint8_t res, op0, op1;
                    367:   tme_uint8_t flags;
                    368: 
                    369:   /* load the operand(s): */
                    370:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    371:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                    372:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                    373:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3);
                    374:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3);
                    375:   tme_uint16_t memory;
                    376: 
                    377:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
                    378:   if (memory) {
                    379:     TME_M68K_INSN_CANFAULT;
                    380:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    381:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
                    382:       ic->_tme_m68k_ea_function_code = function_code;
                    383:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                    384:     }
                    385:     tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8);
1.1.1.4   root      386:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    387:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
                    388:       ic->_tme_m68k_ea_function_code = function_code;
                    389:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                    390:     }
                    391:     tme_m68k_read_memx8(ic);
1.1       root      392:     op1 = ic->tme_m68k_ireg_memx8;
                    393:     op0 = ic->tme_m68k_ireg_memy8;
                    394:   }
                    395:   else {
                    396:     op0 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_src) << 2);
                    397:     op1 = ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2);
                    398:   }
                    399: 
                    400:   /* perform the operation: */
                    401:   res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                    402: 
                    403:   /* store the result: */
                    404:   if (memory) {
                    405:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                    406:       ic->tme_m68k_ireg_memx8 = res;
                    407:       ic->_tme_m68k_ea_function_code = function_code;
                    408:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                    409:     }
                    410:     tme_m68k_write_memx8(ic);
                    411:   }
                    412:   else {
                    413:     ic->tme_m68k_ireg_uint8((TME_M68K_IREG_D0 + ireg_dst) << 2) = res;
                    414:   }
                    415: 
                    416:   /* set the flags: */
                    417:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    418:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                    419:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
                    420:   if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                    421:   ic->tme_m68k_ireg_ccr = flags;
                    422: 
                    423:   TME_M68K_INSN_OK;
                    424: }
                    425: 
                    426: /* this does a 8-bit "cmpm SRC, DST": */
                    427: TME_M68K_INSN(tme_m68k_cmpm8)
                    428: {
                    429:   tme_uint8_t res, op0, op1;
                    430:   tme_uint8_t flags;
                    431: 
                    432:   /* load the operand(s): */
                    433:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                    434:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                    435:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                    436:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint8_t) + ((ireg_src + 1) >> 3);
                    437:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint8_t) + ((ireg_dst + 1) >> 3);
                    438: 
                    439:   TME_M68K_INSN_CANFAULT;
                    440: 
                    441:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                    442:     ic->_tme_m68k_ea_function_code = function_code;
                    443:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                    444:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust;
                    445:   }
                    446:   tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY8);
1.1.1.4   root      447:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                    448:     ic->_tme_m68k_ea_function_code = function_code;
                    449:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                    450:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust;
                    451:   }
                    452:   tme_m68k_read_memx8(ic);
1.1       root      453:   op1 = ic->tme_m68k_ireg_memx8;
                    454:   op0 = ic->tme_m68k_ireg_memy8;
                    455: 
                    456:   /* perform the operation: */
                    457:   res = op1 - op0;
                    458: 
                    459:   /* set the flags: */
                    460:   flags = ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    461:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    462:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (8 - 1))) * TME_M68K_FLAG_V;
                    463:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
                    464:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                    465:   ic->tme_m68k_ireg_ccr = flags;
                    466: 
                    467:   TME_M68K_INSN_OK;
                    468: }
                    469: 
                    470: /* the btst function on a 8-byte EA: */
                    471: TME_M68K_INSN(tme_m68k_btst8)
                    472: {
                    473:   tme_uint8_t value, bit;
                    474:   bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1));
                    475:   value = TME_M68K_INSN_OP1(tme_uint8_t);
                    476:   if (value & bit) {
                    477:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
                    478:   }
                    479:   else {
                    480:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                    481:   }
                    482:   TME_M68K_INSN_OK;
                    483: }
                    484: 
                    485: /* the bchg function on a 8-byte EA: */
                    486: TME_M68K_INSN(tme_m68k_bchg8)
                    487: {
                    488:   tme_uint8_t value, bit;
                    489:   bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1));
                    490:   value = TME_M68K_INSN_OP1(tme_uint8_t);
                    491:   if (value & bit) {
                    492:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
                    493:   }
                    494:   else {
                    495:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                    496:   }
                    497:   TME_M68K_INSN_OP1(tme_uint8_t) = value ^ bit;
                    498:   TME_M68K_INSN_OK;
                    499: }
                    500: 
                    501: /* the bclr function on a 8-byte EA: */
                    502: TME_M68K_INSN(tme_m68k_bclr8)
                    503: {
                    504:   tme_uint8_t value, bit;
                    505:   bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1));
                    506:   value = TME_M68K_INSN_OP1(tme_uint8_t);
                    507:   if (value & bit) {
                    508:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
                    509:   }
                    510:   else {
                    511:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                    512:   }
                    513:   TME_M68K_INSN_OP1(tme_uint8_t) = value & ~bit;
                    514:   TME_M68K_INSN_OK;
                    515: }
                    516: 
                    517: /* the bset function on a 8-byte EA: */
                    518: TME_M68K_INSN(tme_m68k_bset8)
                    519: {
                    520:   tme_uint8_t value, bit;
                    521:   bit = _TME_BIT(tme_uint8_t, TME_M68K_INSN_OP0(tme_uint8_t) & (8 - 1));
                    522:   value = TME_M68K_INSN_OP1(tme_uint8_t);
                    523:   if (value & bit) {
                    524:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
                    525:   }
                    526:   else {
                    527:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                    528:   }
                    529:   TME_M68K_INSN_OP1(tme_uint8_t) = value | bit;
                    530:   TME_M68K_INSN_OK;
                    531: }
                    532: 
                    533: /* the asl function on a 8-byte EA: */
                    534: TME_M68K_INSN(tme_m68k_asl8)
                    535: {
                    536:   unsigned int count;
1.1.1.2   root      537:   tme_uint8_t sign_bits, sign_bits_mask;
1.1       root      538:   tme_uint8_t res;
                    539:   tme_uint8_t flags;
                    540: 
                    541:   /* get the count and operand: */
                    542:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                    543:   res = TME_M68K_INSN_OP1(tme_uint8_t);
                    544: 
                    545:   /* generate the X, V, and C flags assuming the count is zero: */
                    546:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    547: 
                    548:   /* if the count is nonzero, update the result and
                    549:      generate the X, V, and C flags: */
                    550:   if (count > 0) {
                    551: 
                    552:     /* we need to see how the sign of the result will change during
                    553:        shifting in order to generate V.
                    554: 
                    555:        in general, the idea is to get all of the bits that will ever
1.1.1.2   root      556:        appear in the sign position into sign_bits, with a mask in
                    557:        sign_bits_mask.  if (sign_bits & sign_bits_mask) is zero or
                    558:        sign_bits_mask, clear V, else set V.
1.1       root      559: 
1.1.1.2   root      560:        start by loading the operand into sign_bits and setting
                    561:        sign_bits_mask to all-bits-one.
1.1       root      562: 
                    563:        if the shift count is exactly 8 - 1, then all of the bits
                    564:        of the operand will appear in the sign position.
                    565: 
                    566:        if the shift count is less than 8 - 1, then some of the
                    567:        less significant bits of the operand will never appear in the
1.1.1.2   root      568:        sign position, so we can shift sign_bits_mask to ignore them.
1.1       root      569: 
                    570:        if the shift count is greater than 8 - 1, then all of the
                    571:        bits in the operand, plus at least one zero bit, will appear in
                    572:        the sign position.  the only way that the sign bit will never
                    573:        change during the shift is if the operand was zero to begin with.
1.1.1.2   root      574:        without any changes to sign_bits or sign_bits_mask, the final
                    575:        test will always work, except when sign_bits is all-bits-one.
                    576:        the magic below clears the least-significant bit of sign_bits
                    577:        iff sign_bits is all-bits-one: */
1.1       root      578:     sign_bits = res;
                    579:     if (63 > SHIFTMAX_INT8_T
                    580:         && count > 8) {
                    581:       res = 0;
                    582:     }
                    583:     res <<= (count - 1);
                    584:     flags = (res >> (8 - 1));
                    585:     flags *= TME_M68K_FLAG_C;
                    586:     flags |= (flags * TME_M68K_FLAG_X);
                    587:     res <<= 1;
1.1.1.2   root      588:     sign_bits_mask = (tme_uint8_t) -1;
1.1       root      589:     if (count != 8 - 1) {
                    590:       if (count < 8) {
1.1.1.2   root      591:         sign_bits_mask <<= ((8 - 1) - count);
1.1       root      592:       }
                    593:       else {
1.1.1.2   root      594:         sign_bits ^= !(sign_bits + 1);
1.1       root      595:       }
                    596:     }
1.1.1.2   root      597:     sign_bits &= sign_bits_mask;
                    598:     if (sign_bits != 0 && sign_bits != sign_bits_mask) {
1.1       root      599:       flags |= TME_M68K_FLAG_V;
                    600:     }
                    601:   }
                    602: 
                    603:   /* store the result: */
                    604:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
                    605: 
                    606:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                    607:      know the bit we want is within the range of the type, to try
                    608:      to affect the generated assembly: */
                    609:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    610: 
                    611:   /* generate the Z flag: */
                    612:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    613: 
                    614:   /* store the flags: */
                    615:   ic->tme_m68k_ireg_ccr = flags;
                    616:   TME_M68K_INSN_OK;
                    617: }
                    618: 
                    619: /* the asr function on a 8-byte EA: */
                    620: TME_M68K_INSN(tme_m68k_asr8)
                    621: {
                    622:   unsigned int count;
                    623:   tme_int8_t res;
                    624:   tme_uint8_t flags;
                    625: 
                    626:   /* get the count and operand: */
                    627:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                    628:   res = TME_M68K_INSN_OP1(tme_int8_t);
                    629: 
                    630:   /* generate the X, V, and C flags assuming the count is zero: */
                    631:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    632: 
                    633:   /* if the count is nonzero, update the result and
                    634:      generate the X, V, and C flags: */
                    635:   if (count > 0) {
                    636:     if (63 > SHIFTMAX_INT8_T
                    637:         && count > 8) {
1.1.1.3   root      638:       res = 0 - (res < 0);
1.1       root      639:     }
1.1.1.3   root      640: #ifdef SHIFTSIGNED_INT8_T
1.1       root      641:     res >>= (count - 1);
1.1.1.3   root      642: #else  /* !SHIFTSIGNED_INT8_T */
                    643:     for (; --count > 0; ) {
                    644:       res = (res & ~((tme_int8_t) 1)) / 2;
                    645:     }
                    646: #endif /* !SHIFTSIGNED_INT8_T */
1.1       root      647:     flags = (res & 1);
                    648:     flags *= TME_M68K_FLAG_C;
                    649:     flags |= (flags * TME_M68K_FLAG_X);
1.1.1.3   root      650: #ifdef SHIFTSIGNED_INT8_T
1.1       root      651:     res >>= 1;
1.1.1.3   root      652: #else  /* !SHIFTSIGNED_INT8_T */
                    653:     res = (res & ~((tme_int8_t) 1)) / 2;
                    654: #endif /* !SHIFTSIGNED_INT8_T */
1.1       root      655:   }
                    656: 
                    657:   /* store the result: */
                    658:   TME_M68K_INSN_OP1(tme_int8_t) = res;
                    659: 
                    660:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                    661:      know the bit we want is within the range of the type, to try
                    662:      to affect the generated assembly: */
                    663:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    664: 
                    665:   /* generate the Z flag: */
                    666:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    667: 
                    668:   /* store the flags: */
                    669:   ic->tme_m68k_ireg_ccr = flags;
                    670:   TME_M68K_INSN_OK;
                    671: }
                    672: 
                    673: /* the lsl function on a 8-byte EA: */
                    674: TME_M68K_INSN(tme_m68k_lsl8)
                    675: {
                    676:   unsigned int count;
                    677:   tme_uint8_t res;
                    678:   tme_uint8_t flags;
                    679: 
                    680:   /* get the count and operand: */
                    681:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                    682:   res = TME_M68K_INSN_OP1(tme_uint8_t);
                    683: 
                    684:   /* generate the X, V, and C flags assuming the count is zero: */
                    685:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    686: 
                    687:   /* if the count is nonzero, update the result and
                    688:      generate the X, V, and C flags: */
                    689:   if (count > 0) {
                    690:     if (63 > SHIFTMAX_INT8_T
                    691:         && count > 8) {
                    692:       res = 0;
                    693:     }
                    694:     res <<= (count - 1);
                    695:     flags = (res >> (8 - 1));
                    696:     flags *= TME_M68K_FLAG_C;
                    697:     flags |= (flags * TME_M68K_FLAG_X);
                    698:     res <<= 1;
                    699:   }
                    700: 
                    701:   /* store the result: */
                    702:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
                    703: 
                    704:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                    705:      know the bit we want is within the range of the type, to try
                    706:      to affect the generated assembly: */
                    707:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    708: 
                    709:   /* generate the Z flag: */
                    710:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    711: 
                    712:   /* store the flags: */
                    713:   ic->tme_m68k_ireg_ccr = flags;
                    714:   TME_M68K_INSN_OK;
                    715: }
                    716: 
                    717: /* the lsr function on a 8-byte EA: */
                    718: TME_M68K_INSN(tme_m68k_lsr8)
                    719: {
                    720:   unsigned int count;
                    721:   tme_uint8_t res;
                    722:   tme_uint8_t flags;
                    723: 
                    724:   /* get the count and operand: */
                    725:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                    726:   res = TME_M68K_INSN_OP1(tme_uint8_t);
                    727: 
                    728:   /* generate the X, V, and C flags assuming the count is zero: */
                    729:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    730: 
                    731:   /* if the count is nonzero, update the result and
                    732:      generate the X, V, and C flags: */
                    733:   if (count > 0) {
                    734:     if (63 > SHIFTMAX_INT8_T
                    735:         && count > 8) {
                    736:       res = 0;
                    737:     }
                    738:     res >>= (count - 1);
                    739:     flags = (res & 1);
                    740:     flags *= TME_M68K_FLAG_C;
                    741:     flags |= (flags * TME_M68K_FLAG_X);
                    742:     res >>= 1;
                    743:   }
                    744: 
                    745:   /* store the result: */
                    746:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
                    747: 
                    748:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                    749:      know the bit we want is within the range of the type, to try
                    750:      to affect the generated assembly: */
                    751:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    752: 
                    753:   /* generate the Z flag: */
                    754:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    755: 
                    756:   /* store the flags: */
                    757:   ic->tme_m68k_ireg_ccr = flags;
                    758:   TME_M68K_INSN_OK;
                    759: }
                    760: 
                    761: /* the rol function on a 8-byte EA: */
                    762: TME_M68K_INSN(tme_m68k_rol8)
                    763: {
                    764:   unsigned int count;
                    765:   tme_uint8_t res;
                    766:   tme_uint8_t flags;
                    767: 
                    768:   /* get the count and operand: */
                    769:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                    770:   res = TME_M68K_INSN_OP1(tme_uint8_t);
                    771: 
                    772:   /* generate the X, V, and C flags assuming the count is zero: */
                    773:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    774: 
                    775:   /* if the count is nonzero, update the result and
                    776:      generate the X, V, and C flags: */
                    777:   if (count > 0) {
                    778:     count &= (8 - 1);
                    779:     res = (res << count) | (res >> (8 - count));
                    780:     flags |= ((res & 1) * TME_M68K_FLAG_C);
                    781:   }
                    782: 
                    783:   /* store the result: */
                    784:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
                    785: 
                    786:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                    787:      know the bit we want is within the range of the type, to try
                    788:      to affect the generated assembly: */
                    789:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    790: 
                    791:   /* generate the Z flag: */
                    792:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    793: 
                    794:   /* store the flags: */
                    795:   ic->tme_m68k_ireg_ccr = flags;
                    796:   TME_M68K_INSN_OK;
                    797: }
                    798: 
                    799: /* the ror function on a 8-byte EA: */
                    800: TME_M68K_INSN(tme_m68k_ror8)
                    801: {
                    802:   unsigned int count;
                    803:   tme_uint8_t res;
                    804:   tme_uint8_t flags;
                    805: 
                    806:   /* get the count and operand: */
                    807:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                    808:   res = TME_M68K_INSN_OP1(tme_uint8_t);
                    809: 
                    810:   /* generate the X, V, and C flags assuming the count is zero: */
                    811:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    812: 
                    813:   /* if the count is nonzero, update the result and
                    814:      generate the X, V, and C flags: */
                    815:   if (count > 0) {
                    816:     count &= (8 - 1);
                    817:     res = (res << (8 - count)) | (res >> count);
                    818:     flags |= ((res >> (8 - 1)) * TME_M68K_FLAG_C);
                    819:   }
                    820: 
                    821:   /* store the result: */
                    822:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
                    823: 
                    824:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                    825:      know the bit we want is within the range of the type, to try
                    826:      to affect the generated assembly: */
                    827:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    828: 
                    829:   /* generate the Z flag: */
                    830:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    831: 
                    832:   /* store the flags: */
                    833:   ic->tme_m68k_ireg_ccr = flags;
                    834:   TME_M68K_INSN_OK;
                    835: }
                    836: 
                    837: /* the roxl function on a 8-byte EA: */
                    838: TME_M68K_INSN(tme_m68k_roxl8)
                    839: {
                    840:   unsigned int count;
                    841:   tme_uint8_t xbit;
                    842:   tme_uint8_t res;
                    843:   tme_uint8_t flags;
                    844: 
                    845:   /* get the count and operand: */
                    846:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                    847:   res = TME_M68K_INSN_OP1(tme_uint8_t);
                    848: 
                    849:   /* generate the X, V, and C flags assuming the count is zero: */
                    850:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    851:   xbit = (flags / TME_M68K_FLAG_X);
                    852:   flags |= (xbit * TME_M68K_FLAG_C);
                    853: 
                    854:   /* if the count is nonzero, update the result and
                    855:      generate the X, V, and C flags: */
                    856:   if (count > 0) {
                    857:     count %= (8 + 1);
                    858:     flags = xbit;
                    859:     if (count > 0) {
                    860:       flags = (res >> (8 - count)) & 1;
                    861:       if (8 > SHIFTMAX_INT8_T
                    862:           && count == 8) {
                    863:         res = 0 | (xbit << (8 - 1)) | (res >> ((8 + 1) - 8));
                    864:       }
                    865:       else if (8 > SHIFTMAX_INT8_T
                    866:                && count == 1) {
                    867:         res = (res << 1) | (xbit << (1 - 1)) | 0;
                    868:       }
                    869:       else {
                    870:         res = (res << count) | (xbit << (count - 1)) | (res >> ((8 + 1) - count));
                    871:       }
                    872:     }
                    873:     flags *= TME_M68K_FLAG_C;
                    874:     flags |= (flags * TME_M68K_FLAG_X);
                    875:   }
                    876: 
                    877:   /* store the result: */
                    878:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
                    879: 
                    880:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                    881:      know the bit we want is within the range of the type, to try
                    882:      to affect the generated assembly: */
                    883:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    884: 
                    885:   /* generate the Z flag: */
                    886:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    887: 
                    888:   /* store the flags: */
                    889:   ic->tme_m68k_ireg_ccr = flags;
                    890:   TME_M68K_INSN_OK;
                    891: }
                    892: 
                    893: /* the roxr function on a 8-byte EA: */
                    894: TME_M68K_INSN(tme_m68k_roxr8)
                    895: {
                    896:   unsigned int count;
                    897:   tme_uint8_t xbit;
                    898:   tme_uint8_t res;
                    899:   tme_uint8_t flags;
                    900: 
                    901:   /* get the count and operand: */
                    902:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                    903:   res = TME_M68K_INSN_OP1(tme_uint8_t);
                    904: 
                    905:   /* generate the X, V, and C flags assuming the count is zero: */
                    906:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                    907:   xbit = (flags / TME_M68K_FLAG_X);
                    908:   flags |= (xbit * TME_M68K_FLAG_C);
                    909: 
                    910:   /* if the count is nonzero, update the result and
                    911:      generate the X, V, and C flags: */
                    912:   if (count > 0) {
                    913:     count %= (8 + 1);
                    914:     flags = xbit;
                    915:     if (count > 0) {
                    916:       flags = (res >> (count - 1)) & 1;
                    917:       if (8 > SHIFTMAX_INT8_T
                    918:           && count == 8) {
                    919:         res = (res << ((8 + 1) - 8)) | (xbit << (8 - 8)) | 0;
                    920:       }
                    921:       else if (8 > SHIFTMAX_INT8_T
                    922:                && count == 1) {
                    923:         res = 0 | (xbit << (8 - 1)) | (res >> 1);
                    924:       }
                    925:       else {
                    926:         res = (res << ((8 + 1) - count)) | (xbit << (8 - count)) | (res >> count);
                    927:       }
                    928:     }
                    929:     flags *= TME_M68K_FLAG_C;
                    930:     flags |= (flags * TME_M68K_FLAG_X);
                    931:   }
                    932: 
                    933:   /* store the result: */
                    934:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
                    935: 
                    936:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                    937:      know the bit we want is within the range of the type, to try
                    938:      to affect the generated assembly: */
                    939:   flags |= ((tme_uint8_t) (((tme_uint8_t) res) >> (8 - 1))) * TME_M68K_FLAG_N;
                    940: 
                    941:   /* generate the Z flag: */
                    942:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                    943: 
                    944:   /* store the flags: */
                    945:   ic->tme_m68k_ireg_ccr = flags;
                    946:   TME_M68K_INSN_OK;
                    947: }
                    948: 
                    949: /* cas8: */
                    950: TME_M68K_INSN(tme_m68k_cas8)
                    951: {
1.1.1.4   root      952:   struct tme_m68k_rmw rmw;
1.1       root      953:   struct tme_m68k_tlb *tlb;
                    954:   int ireg_dc, ireg_du;
1.1.1.4   root      955:   tme_uint8_t value_dc, value_du, value_mem;
1.1       root      956: 
                    957:   /* start the read/modify/write cycle: */
1.1.1.4   root      958:   rmw.tme_m68k_rmw_addresses[0] = ic->_tme_m68k_ea_address;
                    959:   rmw.tme_m68k_rmw_address_count = 1;
                    960:   rmw.tme_m68k_rmw_size = sizeof(tme_uint8_t);
                    961:   if (tme_m68k_rmw_start(ic,
                    962:                          &rmw)) {
1.1       root      963:     TME_M68K_INSN_OK;
                    964:   }
                    965: 
1.1.1.4   root      966:   /* get the compare and update registers: */
                    967:   ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
                    968:   ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 6, 3);
                    969: 
                    970:   /* if we can do the fast compare-and-exchange: */
                    971:   if (!rmw.tme_m68k_rmw_slow_reads[0]) {
                    972: 
                    973:     /* get the compare and update values in big-endian byte order: */
                    974:     value_dc = ic->tme_m68k_ireg_uint8(ireg_dc << 2);
                    975:     value_du = ic->tme_m68k_ireg_uint8(ireg_du << 2);
                    976: 
                    977:     /* get this TLB entry: */
                    978:     tlb = rmw.tme_m68k_rmw_tlbs[0];
                    979: 
                    980:     /* this TLB entry must allow fast reading and fast writing
                    981:        to the same memory: */
                    982:     assert (tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF
                    983:             && tlb->tme_m68k_tlb_emulator_off_write == tlb->tme_m68k_tlb_emulator_off_read);
                    984: 
                    985:     /* do the compare-and-exchange: */
                    986:     value_mem =
                    987:       tme_memory_atomic_cx8(((tme_shared tme_uint8_t *)
                    988:                                    (tlb->tme_m68k_tlb_emulator_off_read
                    989:                                     + ic->_tme_m68k_ea_address)),
                    990:                                   value_dc,
                    991:                                   value_du,
                    992:                                   tlb->tme_m68k_tlb_bus_rwlock,
                    993:                                   sizeof(tme_uint8_t));
                    994:     ic->tme_m68k_ireg_memx8 = (value_mem);
                    995:   }
                    996: 
                    997:   /* compare the compare operand to the effective address operand: */
                    998:   tme_m68k_cmp8(ic, &ic->tme_m68k_ireg_uint8(ireg_dc << 2), &ic->tme_m68k_ireg_memx8);
1.1       root      999: 
1.1.1.4   root     1000:   /* if the comparison succeeded: */
1.1       root     1001:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
1.1.1.4   root     1002: 
                   1003:     /* write the update operand to the effective address operand: */
                   1004:     ic->tme_m68k_ireg_memx8 = ic->tme_m68k_ireg_uint8(ireg_du << 2);
1.1       root     1005:   }
                   1006: 
1.1.1.4   root     1007:   /* otherwise, the comparison failed: */
                   1008:   else {
1.1       root     1009: 
1.1.1.4   root     1010:     /* write the effective address operand to the compare operand: */
                   1011:     ic->tme_m68k_ireg_uint8(ireg_dc << 2) = ic->tme_m68k_ireg_memx8;
                   1012:   }
                   1013: 
                   1014:   /* finish the read/modify/write cycle: */
                   1015:   tme_m68k_rmw_finish(ic,
                   1016:                       &rmw,
                   1017:                       (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) != 0);
1.1       root     1018:   TME_M68K_INSN_OK;
                   1019: }
                   1020: 
                   1021: /* moves8: */
                   1022: TME_M68K_INSN(tme_m68k_moves8)
                   1023: {
                   1024:   int ireg;
1.1.1.4   root     1025:   tme_uint8_t ireg_value;
1.1.1.3   root     1026:   unsigned int ea_reg;
                   1027:   unsigned int increment;
                   1028:   TME_M68K_INSN_PRIV;
                   1029:   TME_M68K_INSN_CANFAULT;
1.1       root     1030:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
1.1.1.3   root     1031: 
1.1.1.4   root     1032:   /* in case we're storing the same address register used in a
                   1033:      postincrement or predecrement EA, save the current value
                   1034:      of the register now: */
                   1035:   ireg_value = ic->tme_m68k_ireg_uint8(ireg << 2);
                   1036: 
1.1.1.3   root     1037:   /* we have to handle postincrement and predecrement ourselves: */
                   1038:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1039:     ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   1040:     increment = TME_M68K_SIZE_8;
                   1041:     if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) {
                   1042:       increment = TME_M68K_SIZE_16;
                   1043:     }
                   1044:     switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) {
                   1045:     case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break;
                   1046:     case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break;
                   1047:     default: break;
                   1048:     }
                   1049:   }
                   1050: 
1.1       root     1051:   if (TME_M68K_INSN_SPECOP & TME_BIT(11)) {
1.1.1.3   root     1052:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     1053:       ic->tme_m68k_ireg_memx8 = ireg_value;
1.1.1.3   root     1054:       ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc;
                   1055:     }
                   1056:     tme_m68k_write_memx8(ic);
1.1       root     1057:   }
                   1058:   else {
1.1.1.3   root     1059:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1060:       ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc;
                   1061:     }
                   1062:     tme_m68k_read_memx8(ic);
1.1       root     1063:     if (ireg >= TME_M68K_IREG_A0) {
                   1064:       ic->tme_m68k_ireg_uint32(ireg) = 
                   1065:         TME_EXT_S8_U32((tme_int8_t) ic->tme_m68k_ireg_memx8);
                   1066:     }
                   1067:     else
                   1068:       ic->tme_m68k_ireg_uint8(ireg << 2) = ic->tme_m68k_ireg_memx8;
                   1069:   }
                   1070:   TME_M68K_INSN_OK;
                   1071: }
                   1072: 
                   1073: /* this does a 16-bit "add SRC, DST": */
                   1074: TME_M68K_INSN(tme_m68k_add16)
                   1075: {
                   1076:   tme_uint16_t res, op0, op1;
                   1077:   tme_uint8_t flags;
                   1078: 
                   1079:   /* load the operand(s): */
                   1080:   op0 = *((tme_uint16_t *) _op0);
                   1081:   op1 = *((tme_uint16_t *) _op1);
                   1082: 
                   1083:   /* perform the operation: */
                   1084:   res = op1 + op0;
                   1085: 
                   1086:   /* store the result: */
                   1087:   *((tme_uint16_t *) _op1) = res;
                   1088: 
                   1089:   /* set the flags: */
                   1090:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1091:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1092:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffff) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
                   1093:   if (op0 > (op1 ^ 0xffff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   1094:   ic->tme_m68k_ireg_ccr = flags;
                   1095: 
                   1096:   TME_M68K_INSN_OK;
                   1097: }
                   1098: 
                   1099: /* this does a 16-bit "sub SRC, DST": */
                   1100: TME_M68K_INSN(tme_m68k_sub16)
                   1101: {
                   1102:   tme_uint16_t res, op0, op1;
                   1103:   tme_uint8_t flags;
                   1104: 
                   1105:   /* load the operand(s): */
                   1106:   op0 = *((tme_uint16_t *) _op0);
                   1107:   op1 = *((tme_uint16_t *) _op1);
                   1108: 
                   1109:   /* perform the operation: */
                   1110:   res = op1 - op0;
                   1111: 
                   1112:   /* store the result: */
                   1113:   *((tme_uint16_t *) _op1) = res;
                   1114: 
                   1115:   /* set the flags: */
                   1116:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1117:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1118:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
                   1119:   if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   1120:   ic->tme_m68k_ireg_ccr = flags;
                   1121: 
                   1122:   TME_M68K_INSN_OK;
                   1123: }
                   1124: 
                   1125: /* this does a 16-bit "cmp SRC, DST": */
                   1126: TME_M68K_INSN(tme_m68k_cmp16)
                   1127: {
                   1128:   tme_uint16_t res, op0, op1;
                   1129:   tme_uint8_t flags;
                   1130: 
                   1131:   /* load the operand(s): */
                   1132:   op0 = *((tme_uint16_t *) _op0);
                   1133:   op1 = *((tme_uint16_t *) _op1);
                   1134: 
                   1135:   /* perform the operation: */
                   1136:   res = op1 - op0;
                   1137: 
                   1138:   /* set the flags: */
                   1139:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1140:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1141:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
                   1142:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
                   1143:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1144:   ic->tme_m68k_ireg_ccr = flags;
                   1145: 
                   1146:   TME_M68K_INSN_OK;
                   1147: }
                   1148: 
                   1149: /* this does a 16-bit "neg DST": */
                   1150: TME_M68K_INSN(tme_m68k_neg16)
                   1151: {
                   1152:   tme_uint16_t res, op1;
                   1153:   tme_uint8_t flags;
                   1154: 
                   1155:   /* load the operand(s): */
                   1156:   op1 = *((tme_uint16_t *) _op1);
                   1157: 
                   1158:   /* perform the operation: */
                   1159:   res = 0 - op1;
                   1160: 
                   1161:   /* store the result: */
                   1162:   *((tme_uint16_t *) _op1) = res;
                   1163: 
                   1164:   /* set the flags: */
                   1165:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1166:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1167:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
                   1168:   if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   1169:   ic->tme_m68k_ireg_ccr = flags;
                   1170: 
                   1171:   TME_M68K_INSN_OK;
                   1172: }
                   1173: 
                   1174: /* this does a 16-bit "or SRC, DST": */
                   1175: TME_M68K_INSN(tme_m68k_or16)
                   1176: {
                   1177:   tme_uint16_t res, op0, op1;
                   1178:   tme_uint8_t flags;
                   1179: 
                   1180:   /* load the operand(s): */
                   1181:   op0 = *((tme_uint16_t *) _op0);
                   1182:   op1 = *((tme_uint16_t *) _op1);
                   1183: 
                   1184:   /* perform the operation: */
                   1185:   res = op1 | op0;
                   1186: 
                   1187:   /* store the result: */
                   1188:   *((tme_uint16_t *) _op1) = res;
                   1189: 
                   1190:   /* set the flags: */
                   1191:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1192:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1193:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1194:   ic->tme_m68k_ireg_ccr = flags;
                   1195: 
                   1196:   TME_M68K_INSN_OK;
                   1197: }
                   1198: 
                   1199: /* this does a 16-bit "and SRC, DST": */
                   1200: TME_M68K_INSN(tme_m68k_and16)
                   1201: {
                   1202:   tme_uint16_t res, op0, op1;
                   1203:   tme_uint8_t flags;
                   1204: 
                   1205:   /* load the operand(s): */
                   1206:   op0 = *((tme_uint16_t *) _op0);
                   1207:   op1 = *((tme_uint16_t *) _op1);
                   1208: 
                   1209:   /* perform the operation: */
                   1210:   res = op1 & op0;
                   1211: 
                   1212:   /* store the result: */
                   1213:   *((tme_uint16_t *) _op1) = res;
                   1214: 
                   1215:   /* set the flags: */
                   1216:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1217:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1218:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1219:   ic->tme_m68k_ireg_ccr = flags;
                   1220: 
                   1221:   TME_M68K_INSN_OK;
                   1222: }
                   1223: 
                   1224: /* this does a 16-bit "eor SRC, DST": */
                   1225: TME_M68K_INSN(tme_m68k_eor16)
                   1226: {
                   1227:   tme_uint16_t res, op0, op1;
                   1228:   tme_uint8_t flags;
                   1229: 
                   1230:   /* load the operand(s): */
                   1231:   op0 = *((tme_uint16_t *) _op0);
                   1232:   op1 = *((tme_uint16_t *) _op1);
                   1233: 
                   1234:   /* perform the operation: */
                   1235:   res = op1 ^ op0;
                   1236: 
                   1237:   /* store the result: */
                   1238:   *((tme_uint16_t *) _op1) = res;
                   1239: 
                   1240:   /* set the flags: */
                   1241:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1242:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1243:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1244:   ic->tme_m68k_ireg_ccr = flags;
                   1245: 
                   1246:   TME_M68K_INSN_OK;
                   1247: }
                   1248: 
                   1249: /* this does a 16-bit "not DST": */
                   1250: TME_M68K_INSN(tme_m68k_not16)
                   1251: {
                   1252:   tme_uint16_t res, op1;
                   1253:   tme_uint8_t flags;
                   1254: 
                   1255:   /* load the operand(s): */
                   1256:   op1 = *((tme_uint16_t *) _op1);
                   1257: 
                   1258:   /* perform the operation: */
                   1259:   res = ~ op1;
                   1260: 
                   1261:   /* store the result: */
                   1262:   *((tme_uint16_t *) _op1) = res;
                   1263: 
                   1264:   /* set the flags: */
                   1265:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1266:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1267:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1268:   ic->tme_m68k_ireg_ccr = flags;
                   1269: 
                   1270:   TME_M68K_INSN_OK;
                   1271: }
                   1272: 
                   1273: /* this does a 16-bit "tst DST": */
                   1274: TME_M68K_INSN(tme_m68k_tst16)
                   1275: {
                   1276:   tme_uint16_t res, op1;
                   1277:   tme_uint8_t flags;
                   1278: 
                   1279:   /* load the operand(s): */
                   1280:   op1 = *((tme_uint16_t *) _op1);
                   1281: 
                   1282:   /* perform the operation: */
                   1283:   res = op1;
                   1284: 
                   1285:   /* set the flags: */
                   1286:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1287:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1288:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1289:   ic->tme_m68k_ireg_ccr = flags;
                   1290: 
                   1291:   TME_M68K_INSN_OK;
                   1292: }
                   1293: 
                   1294: /* this does a 16-bit "move DST": */
                   1295: TME_M68K_INSN(tme_m68k_move16)
                   1296: {
                   1297:   tme_uint16_t res, op1;
                   1298:   tme_uint8_t flags;
                   1299: 
                   1300:   /* load the operand(s): */
                   1301:   op1 = *((tme_uint16_t *) _op1);
                   1302: 
                   1303:   /* perform the operation: */
                   1304:   res = op1;
                   1305: 
                   1306:   /* store the result: */
                   1307:   *((tme_uint16_t *) _op0) = res;
                   1308: 
                   1309:   /* set the flags: */
                   1310:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1311:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1312:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1313:   ic->tme_m68k_ireg_ccr = flags;
                   1314: 
                   1315:   TME_M68K_INSN_OK;
                   1316: }
                   1317: 
                   1318: /* this does a 16-bit "clr DST": */
                   1319: TME_M68K_INSN(tme_m68k_clr16)
                   1320: {
                   1321:   tme_uint16_t res;
                   1322:   tme_uint8_t flags;
                   1323: 
                   1324:   /* load the operand(s): */
                   1325: 
                   1326:   /* perform the operation: */
                   1327:   res = 0;
                   1328: 
                   1329:   /* store the result: */
                   1330:   *((tme_uint16_t *) _op1) = res;
                   1331: 
                   1332:   /* set the flags: */
                   1333:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1334:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1335:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1336:   ic->tme_m68k_ireg_ccr = flags;
                   1337: 
                   1338:   TME_M68K_INSN_OK;
                   1339: }
                   1340: 
                   1341: /* this does a 16-bit "cmpa SRC, DST": */
                   1342: TME_M68K_INSN(tme_m68k_cmpa16)
                   1343: {
                   1344:   tme_uint32_t res, op0, op1;
                   1345:   tme_uint8_t flags;
                   1346: 
                   1347:   /* load the operand(s): */
                   1348:   op0 = (tme_uint32_t) ((tme_int32_t) *((tme_int16_t *) _op0));
                   1349:   op1 = *((tme_uint32_t *) _op1);
                   1350: 
                   1351:   /* perform the operation: */
                   1352:   res = op1 - op0;
                   1353: 
                   1354:   /* set the flags: */
                   1355:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   1356:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1357:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   1358:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
                   1359:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1360:   ic->tme_m68k_ireg_ccr = flags;
                   1361: 
                   1362:   TME_M68K_INSN_OK;
                   1363: }
                   1364: 
                   1365: /* this does a 16-bit "negx DST": */
                   1366: TME_M68K_INSN(tme_m68k_negx16)
                   1367: {
                   1368:   tme_uint16_t res, op1;
                   1369:   tme_uint8_t flags;
                   1370: 
                   1371:   /* load the operand(s): */
                   1372:   op1 = *((tme_uint16_t *) _op1);
                   1373: 
                   1374:   /* perform the operation: */
                   1375:   res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                   1376: 
                   1377:   /* store the result: */
                   1378:   *((tme_uint16_t *) _op1) = res;
                   1379: 
                   1380:   /* set the flags: */
                   1381:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1382:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                   1383:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
                   1384:   if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   1385:   ic->tme_m68k_ireg_ccr = flags;
                   1386: 
                   1387:   TME_M68K_INSN_OK;
                   1388: }
                   1389: 
                   1390: /* this does a 16-bit "addx SRC, DST": */
                   1391: TME_M68K_INSN(tme_m68k_addx16)
                   1392: {
                   1393:   tme_uint16_t res, op0, op1;
                   1394:   tme_uint8_t flags;
                   1395: 
                   1396:   /* load the operand(s): */
                   1397:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   1398:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   1399:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   1400:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t);
                   1401:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t);
                   1402:   tme_uint16_t memory;
                   1403: 
                   1404:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
                   1405:   if (memory) {
                   1406:     TME_M68K_INSN_CANFAULT;
                   1407:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1408:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
                   1409:       ic->_tme_m68k_ea_function_code = function_code;
                   1410:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                   1411:     }
                   1412:     tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16);
1.1.1.4   root     1413:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1414:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
                   1415:       ic->_tme_m68k_ea_function_code = function_code;
                   1416:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   1417:     }
                   1418:     tme_m68k_read_memx16(ic);
1.1       root     1419:     op1 = ic->tme_m68k_ireg_memx16;
                   1420:     op0 = ic->tme_m68k_ireg_memy16;
                   1421:   }
                   1422:   else {
                   1423:     op0 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_src) << 1);
                   1424:     op1 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1);
                   1425:   }
                   1426: 
                   1427:   /* perform the operation: */
                   1428:   res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                   1429: 
                   1430:   /* store the result: */
                   1431:   if (memory) {
                   1432:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1433:       ic->tme_m68k_ireg_memx16 = res;
                   1434:       ic->_tme_m68k_ea_function_code = function_code;
                   1435:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   1436:     }
                   1437:     tme_m68k_write_memx16(ic);
                   1438:   }
                   1439:   else {
                   1440:     ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1) = res;
                   1441:   }
                   1442: 
                   1443:   /* set the flags: */
                   1444:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1445:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                   1446:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffff) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
                   1447:   if (op0 > (op1 ^ 0xffff) || (op0 == (op1 ^ 0xffff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   1448:   ic->tme_m68k_ireg_ccr = flags;
                   1449: 
                   1450:   TME_M68K_INSN_OK;
                   1451: }
                   1452: 
                   1453: /* this does a 16-bit "subx SRC, DST": */
                   1454: TME_M68K_INSN(tme_m68k_subx16)
                   1455: {
                   1456:   tme_uint16_t res, op0, op1;
                   1457:   tme_uint8_t flags;
                   1458: 
                   1459:   /* load the operand(s): */
                   1460:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   1461:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   1462:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   1463:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t);
                   1464:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t);
                   1465:   tme_uint16_t memory;
                   1466: 
                   1467:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
                   1468:   if (memory) {
                   1469:     TME_M68K_INSN_CANFAULT;
                   1470:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1471:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
                   1472:       ic->_tme_m68k_ea_function_code = function_code;
                   1473:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                   1474:     }
                   1475:     tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16);
1.1.1.4   root     1476:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1477:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
                   1478:       ic->_tme_m68k_ea_function_code = function_code;
                   1479:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   1480:     }
                   1481:     tme_m68k_read_memx16(ic);
1.1       root     1482:     op1 = ic->tme_m68k_ireg_memx16;
                   1483:     op0 = ic->tme_m68k_ireg_memy16;
                   1484:   }
                   1485:   else {
                   1486:     op0 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_src) << 1);
                   1487:     op1 = ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1);
                   1488:   }
                   1489: 
                   1490:   /* perform the operation: */
                   1491:   res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                   1492: 
                   1493:   /* store the result: */
                   1494:   if (memory) {
                   1495:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1496:       ic->tme_m68k_ireg_memx16 = res;
                   1497:       ic->_tme_m68k_ea_function_code = function_code;
                   1498:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   1499:     }
                   1500:     tme_m68k_write_memx16(ic);
                   1501:   }
                   1502:   else {
                   1503:     ic->tme_m68k_ireg_uint16((TME_M68K_IREG_D0 + ireg_dst) << 1) = res;
                   1504:   }
                   1505: 
                   1506:   /* set the flags: */
                   1507:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1508:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                   1509:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
                   1510:   if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   1511:   ic->tme_m68k_ireg_ccr = flags;
                   1512: 
                   1513:   TME_M68K_INSN_OK;
                   1514: }
                   1515: 
                   1516: /* this does a 16-bit "cmpm SRC, DST": */
                   1517: TME_M68K_INSN(tme_m68k_cmpm16)
                   1518: {
                   1519:   tme_uint16_t res, op0, op1;
                   1520:   tme_uint8_t flags;
                   1521: 
                   1522:   /* load the operand(s): */
                   1523:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   1524:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   1525:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   1526:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint16_t);
                   1527:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint16_t);
                   1528: 
                   1529:   TME_M68K_INSN_CANFAULT;
                   1530: 
                   1531:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1532:     ic->_tme_m68k_ea_function_code = function_code;
                   1533:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                   1534:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust;
                   1535:   }
                   1536:   tme_m68k_read_mem16(ic, TME_M68K_IREG_MEMY16);
1.1.1.4   root     1537:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1538:     ic->_tme_m68k_ea_function_code = function_code;
                   1539:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   1540:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust;
                   1541:   }
                   1542:   tme_m68k_read_memx16(ic);
1.1       root     1543:   op1 = ic->tme_m68k_ireg_memx16;
                   1544:   op0 = ic->tme_m68k_ireg_memy16;
                   1545: 
                   1546:   /* perform the operation: */
                   1547:   res = op1 - op0;
                   1548: 
                   1549:   /* set the flags: */
                   1550:   flags = ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1551:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1552:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (16 - 1))) * TME_M68K_FLAG_V;
                   1553:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
                   1554:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   1555:   ic->tme_m68k_ireg_ccr = flags;
                   1556: 
                   1557:   TME_M68K_INSN_OK;
                   1558: }
                   1559: 
1.1.1.4   root     1560: /* a move of an address register to a predecrement or
                   1561:    postincrement EA with that same address register, must
                   1562:    store the original value of the address register.  since the
                   1563:    predecrement and postincrement code in the executer updates
                   1564:    the address register before the move has happened, we wrap
                   1565:    the normal move function in this one, that gives an op1
                   1566:    argument that is the original value of the address register: */
                   1567: TME_M68K_INSN(tme_m68k_move_srpd16)
                   1568: {
                   1569:   /* NB: both this function and tme_m68k_move16()
                   1570:      get the source operand as _op1, and the destination
                   1571:      operand as _op0: */
                   1572:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1573:     *((tme_uint16_t *) _op0)
                   1574:       = (*((tme_uint16_t *) _op1)
                   1575:          + sizeof(tme_uint16_t));
                   1576:   }
                   1577:   tme_m68k_move16(ic, _op0, _op0);
                   1578: }
                   1579: 
                   1580: /* a move of an address register to a predecrement or
                   1581:    postincrement EA with that same address register, must
                   1582:    store the original value of the address register.  since the
                   1583:    predecrement and postincrement code in the executer updates
                   1584:    the address register before the move has happened, we wrap
                   1585:    the normal move function in this one, that gives an op1
                   1586:    argument that is the original value of the address register: */
                   1587: TME_M68K_INSN(tme_m68k_move_srpi16)
                   1588: {
                   1589:   /* NB: both this function and tme_m68k_move16()
                   1590:      get the source operand as _op1, and the destination
                   1591:      operand as _op0: */
                   1592:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   1593:     *((tme_uint16_t *) _op0)
                   1594:       = (*((tme_uint16_t *) _op1)
                   1595:          - sizeof(tme_uint16_t));
                   1596:   }
                   1597:   tme_m68k_move16(ic, _op0, _op0);
                   1598: }
                   1599: 
1.1       root     1600: /* the suba function on a 16-byte EA: */
                   1601: TME_M68K_INSN(tme_m68k_suba16)
                   1602: {
                   1603:   *((tme_int32_t *) _op1) -= *((tme_int16_t *) _op0);
                   1604:   TME_M68K_INSN_OK;
                   1605: }
                   1606: 
                   1607: /* the adda function on a 16-byte EA: */
                   1608: TME_M68K_INSN(tme_m68k_adda16)
                   1609: {
                   1610:   *((tme_int32_t *) _op1) += *((tme_int16_t *) _op0);
                   1611:   TME_M68K_INSN_OK;
                   1612: }
                   1613: 
                   1614: /* the movea function on a 16-byte EA: */
                   1615: TME_M68K_INSN(tme_m68k_movea16)
                   1616: {
                   1617:   *((tme_int32_t *) _op0) = *((tme_int16_t *) _op1);
                   1618:   TME_M68K_INSN_OK;
                   1619: }
                   1620: 
                   1621: /* the asl function on a 16-byte EA: */
                   1622: TME_M68K_INSN(tme_m68k_asl16)
                   1623: {
                   1624:   unsigned int count;
1.1.1.2   root     1625:   tme_uint16_t sign_bits, sign_bits_mask;
1.1       root     1626:   tme_uint16_t res;
                   1627:   tme_uint8_t flags;
                   1628: 
                   1629:   /* get the count and operand: */
                   1630:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   1631:   res = TME_M68K_INSN_OP1(tme_uint16_t);
                   1632: 
                   1633:   /* generate the X, V, and C flags assuming the count is zero: */
                   1634:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   1635: 
                   1636:   /* if the count is nonzero, update the result and
                   1637:      generate the X, V, and C flags: */
                   1638:   if (count > 0) {
                   1639: 
                   1640:     /* we need to see how the sign of the result will change during
                   1641:        shifting in order to generate V.
                   1642: 
                   1643:        in general, the idea is to get all of the bits that will ever
1.1.1.2   root     1644:        appear in the sign position into sign_bits, with a mask in
                   1645:        sign_bits_mask.  if (sign_bits & sign_bits_mask) is zero or
                   1646:        sign_bits_mask, clear V, else set V.
1.1       root     1647: 
1.1.1.2   root     1648:        start by loading the operand into sign_bits and setting
                   1649:        sign_bits_mask to all-bits-one.
1.1       root     1650: 
                   1651:        if the shift count is exactly 16 - 1, then all of the bits
                   1652:        of the operand will appear in the sign position.
                   1653: 
                   1654:        if the shift count is less than 16 - 1, then some of the
                   1655:        less significant bits of the operand will never appear in the
1.1.1.2   root     1656:        sign position, so we can shift sign_bits_mask to ignore them.
1.1       root     1657: 
                   1658:        if the shift count is greater than 16 - 1, then all of the
                   1659:        bits in the operand, plus at least one zero bit, will appear in
                   1660:        the sign position.  the only way that the sign bit will never
                   1661:        change during the shift is if the operand was zero to begin with.
1.1.1.2   root     1662:        without any changes to sign_bits or sign_bits_mask, the final
                   1663:        test will always work, except when sign_bits is all-bits-one.
                   1664:        the magic below clears the least-significant bit of sign_bits
                   1665:        iff sign_bits is all-bits-one: */
1.1       root     1666:     sign_bits = res;
                   1667:     if (63 > SHIFTMAX_INT16_T
                   1668:         && count > 16) {
                   1669:       res = 0;
                   1670:     }
                   1671:     res <<= (count - 1);
                   1672:     flags = (res >> (16 - 1));
                   1673:     flags *= TME_M68K_FLAG_C;
                   1674:     flags |= (flags * TME_M68K_FLAG_X);
                   1675:     res <<= 1;
1.1.1.2   root     1676:     sign_bits_mask = (tme_uint16_t) -1;
1.1       root     1677:     if (count != 16 - 1) {
                   1678:       if (count < 16) {
1.1.1.2   root     1679:         sign_bits_mask <<= ((16 - 1) - count);
1.1       root     1680:       }
                   1681:       else {
1.1.1.2   root     1682:         sign_bits ^= !(sign_bits + 1);
1.1       root     1683:       }
                   1684:     }
1.1.1.2   root     1685:     sign_bits &= sign_bits_mask;
                   1686:     if (sign_bits != 0 && sign_bits != sign_bits_mask) {
1.1       root     1687:       flags |= TME_M68K_FLAG_V;
                   1688:     }
                   1689:   }
                   1690: 
                   1691:   /* store the result: */
                   1692:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
                   1693: 
                   1694:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   1695:      know the bit we want is within the range of the type, to try
                   1696:      to affect the generated assembly: */
                   1697:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1698: 
                   1699:   /* generate the Z flag: */
                   1700:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1701: 
                   1702:   /* store the flags: */
                   1703:   ic->tme_m68k_ireg_ccr = flags;
                   1704:   TME_M68K_INSN_OK;
                   1705: }
                   1706: 
                   1707: /* the asr function on a 16-byte EA: */
                   1708: TME_M68K_INSN(tme_m68k_asr16)
                   1709: {
                   1710:   unsigned int count;
                   1711:   tme_int16_t res;
                   1712:   tme_uint8_t flags;
                   1713: 
                   1714:   /* get the count and operand: */
                   1715:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   1716:   res = TME_M68K_INSN_OP1(tme_int16_t);
                   1717: 
                   1718:   /* generate the X, V, and C flags assuming the count is zero: */
                   1719:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   1720: 
                   1721:   /* if the count is nonzero, update the result and
                   1722:      generate the X, V, and C flags: */
                   1723:   if (count > 0) {
                   1724:     if (63 > SHIFTMAX_INT16_T
                   1725:         && count > 16) {
1.1.1.3   root     1726:       res = 0 - (res < 0);
1.1       root     1727:     }
1.1.1.3   root     1728: #ifdef SHIFTSIGNED_INT16_T
1.1       root     1729:     res >>= (count - 1);
1.1.1.3   root     1730: #else  /* !SHIFTSIGNED_INT16_T */
                   1731:     for (; --count > 0; ) {
                   1732:       res = (res & ~((tme_int16_t) 1)) / 2;
                   1733:     }
                   1734: #endif /* !SHIFTSIGNED_INT16_T */
1.1       root     1735:     flags = (res & 1);
                   1736:     flags *= TME_M68K_FLAG_C;
                   1737:     flags |= (flags * TME_M68K_FLAG_X);
1.1.1.3   root     1738: #ifdef SHIFTSIGNED_INT16_T
1.1       root     1739:     res >>= 1;
1.1.1.3   root     1740: #else  /* !SHIFTSIGNED_INT16_T */
                   1741:     res = (res & ~((tme_int16_t) 1)) / 2;
                   1742: #endif /* !SHIFTSIGNED_INT16_T */
1.1       root     1743:   }
                   1744: 
                   1745:   /* store the result: */
                   1746:   TME_M68K_INSN_OP1(tme_int16_t) = res;
                   1747: 
                   1748:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   1749:      know the bit we want is within the range of the type, to try
                   1750:      to affect the generated assembly: */
                   1751:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1752: 
                   1753:   /* generate the Z flag: */
                   1754:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1755: 
                   1756:   /* store the flags: */
                   1757:   ic->tme_m68k_ireg_ccr = flags;
                   1758:   TME_M68K_INSN_OK;
                   1759: }
                   1760: 
                   1761: /* the lsl function on a 16-byte EA: */
                   1762: TME_M68K_INSN(tme_m68k_lsl16)
                   1763: {
                   1764:   unsigned int count;
                   1765:   tme_uint16_t res;
                   1766:   tme_uint8_t flags;
                   1767: 
                   1768:   /* get the count and operand: */
                   1769:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   1770:   res = TME_M68K_INSN_OP1(tme_uint16_t);
                   1771: 
                   1772:   /* generate the X, V, and C flags assuming the count is zero: */
                   1773:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   1774: 
                   1775:   /* if the count is nonzero, update the result and
                   1776:      generate the X, V, and C flags: */
                   1777:   if (count > 0) {
                   1778:     if (63 > SHIFTMAX_INT16_T
                   1779:         && count > 16) {
                   1780:       res = 0;
                   1781:     }
                   1782:     res <<= (count - 1);
                   1783:     flags = (res >> (16 - 1));
                   1784:     flags *= TME_M68K_FLAG_C;
                   1785:     flags |= (flags * TME_M68K_FLAG_X);
                   1786:     res <<= 1;
                   1787:   }
                   1788: 
                   1789:   /* store the result: */
                   1790:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
                   1791: 
                   1792:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   1793:      know the bit we want is within the range of the type, to try
                   1794:      to affect the generated assembly: */
                   1795:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1796: 
                   1797:   /* generate the Z flag: */
                   1798:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1799: 
                   1800:   /* store the flags: */
                   1801:   ic->tme_m68k_ireg_ccr = flags;
                   1802:   TME_M68K_INSN_OK;
                   1803: }
                   1804: 
                   1805: /* the lsr function on a 16-byte EA: */
                   1806: TME_M68K_INSN(tme_m68k_lsr16)
                   1807: {
                   1808:   unsigned int count;
                   1809:   tme_uint16_t res;
                   1810:   tme_uint8_t flags;
                   1811: 
                   1812:   /* get the count and operand: */
                   1813:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   1814:   res = TME_M68K_INSN_OP1(tme_uint16_t);
                   1815: 
                   1816:   /* generate the X, V, and C flags assuming the count is zero: */
                   1817:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   1818: 
                   1819:   /* if the count is nonzero, update the result and
                   1820:      generate the X, V, and C flags: */
                   1821:   if (count > 0) {
                   1822:     if (63 > SHIFTMAX_INT16_T
                   1823:         && count > 16) {
                   1824:       res = 0;
                   1825:     }
                   1826:     res >>= (count - 1);
                   1827:     flags = (res & 1);
                   1828:     flags *= TME_M68K_FLAG_C;
                   1829:     flags |= (flags * TME_M68K_FLAG_X);
                   1830:     res >>= 1;
                   1831:   }
                   1832: 
                   1833:   /* store the result: */
                   1834:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
                   1835: 
                   1836:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   1837:      know the bit we want is within the range of the type, to try
                   1838:      to affect the generated assembly: */
                   1839:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1840: 
                   1841:   /* generate the Z flag: */
                   1842:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1843: 
                   1844:   /* store the flags: */
                   1845:   ic->tme_m68k_ireg_ccr = flags;
                   1846:   TME_M68K_INSN_OK;
                   1847: }
                   1848: 
                   1849: /* the rol function on a 16-byte EA: */
                   1850: TME_M68K_INSN(tme_m68k_rol16)
                   1851: {
                   1852:   unsigned int count;
                   1853:   tme_uint16_t res;
                   1854:   tme_uint8_t flags;
                   1855: 
                   1856:   /* get the count and operand: */
                   1857:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   1858:   res = TME_M68K_INSN_OP1(tme_uint16_t);
                   1859: 
                   1860:   /* generate the X, V, and C flags assuming the count is zero: */
                   1861:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   1862: 
                   1863:   /* if the count is nonzero, update the result and
                   1864:      generate the X, V, and C flags: */
                   1865:   if (count > 0) {
                   1866:     count &= (16 - 1);
                   1867:     res = (res << count) | (res >> (16 - count));
                   1868:     flags |= ((res & 1) * TME_M68K_FLAG_C);
                   1869:   }
                   1870: 
                   1871:   /* store the result: */
                   1872:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
                   1873: 
                   1874:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   1875:      know the bit we want is within the range of the type, to try
                   1876:      to affect the generated assembly: */
                   1877:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1878: 
                   1879:   /* generate the Z flag: */
                   1880:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1881: 
                   1882:   /* store the flags: */
                   1883:   ic->tme_m68k_ireg_ccr = flags;
                   1884:   TME_M68K_INSN_OK;
                   1885: }
                   1886: 
                   1887: /* the ror function on a 16-byte EA: */
                   1888: TME_M68K_INSN(tme_m68k_ror16)
                   1889: {
                   1890:   unsigned int count;
                   1891:   tme_uint16_t res;
                   1892:   tme_uint8_t flags;
                   1893: 
                   1894:   /* get the count and operand: */
                   1895:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   1896:   res = TME_M68K_INSN_OP1(tme_uint16_t);
                   1897: 
                   1898:   /* generate the X, V, and C flags assuming the count is zero: */
                   1899:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   1900: 
                   1901:   /* if the count is nonzero, update the result and
                   1902:      generate the X, V, and C flags: */
                   1903:   if (count > 0) {
                   1904:     count &= (16 - 1);
                   1905:     res = (res << (16 - count)) | (res >> count);
                   1906:     flags |= ((res >> (16 - 1)) * TME_M68K_FLAG_C);
                   1907:   }
                   1908: 
                   1909:   /* store the result: */
                   1910:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
                   1911: 
                   1912:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   1913:      know the bit we want is within the range of the type, to try
                   1914:      to affect the generated assembly: */
                   1915:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1916: 
                   1917:   /* generate the Z flag: */
                   1918:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1919: 
                   1920:   /* store the flags: */
                   1921:   ic->tme_m68k_ireg_ccr = flags;
                   1922:   TME_M68K_INSN_OK;
                   1923: }
                   1924: 
                   1925: /* the roxl function on a 16-byte EA: */
                   1926: TME_M68K_INSN(tme_m68k_roxl16)
                   1927: {
                   1928:   unsigned int count;
                   1929:   tme_uint8_t xbit;
                   1930:   tme_uint16_t res;
                   1931:   tme_uint8_t flags;
                   1932: 
                   1933:   /* get the count and operand: */
                   1934:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   1935:   res = TME_M68K_INSN_OP1(tme_uint16_t);
                   1936: 
                   1937:   /* generate the X, V, and C flags assuming the count is zero: */
                   1938:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   1939:   xbit = (flags / TME_M68K_FLAG_X);
                   1940:   flags |= (xbit * TME_M68K_FLAG_C);
                   1941: 
                   1942:   /* if the count is nonzero, update the result and
                   1943:      generate the X, V, and C flags: */
                   1944:   if (count > 0) {
                   1945:     count %= (16 + 1);
                   1946:     flags = xbit;
                   1947:     if (count > 0) {
                   1948:       flags = (res >> (16 - count)) & 1;
                   1949:       if (16 > SHIFTMAX_INT16_T
                   1950:           && count == 16) {
                   1951:         res = 0 | (xbit << (16 - 1)) | (res >> ((16 + 1) - 16));
                   1952:       }
                   1953:       else if (16 > SHIFTMAX_INT16_T
                   1954:                && count == 1) {
                   1955:         res = (res << 1) | (xbit << (1 - 1)) | 0;
                   1956:       }
                   1957:       else {
                   1958:         res = (res << count) | (xbit << (count - 1)) | (res >> ((16 + 1) - count));
                   1959:       }
                   1960:     }
                   1961:     flags *= TME_M68K_FLAG_C;
                   1962:     flags |= (flags * TME_M68K_FLAG_X);
                   1963:   }
                   1964: 
                   1965:   /* store the result: */
                   1966:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
                   1967: 
                   1968:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   1969:      know the bit we want is within the range of the type, to try
                   1970:      to affect the generated assembly: */
                   1971:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   1972: 
                   1973:   /* generate the Z flag: */
                   1974:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   1975: 
                   1976:   /* store the flags: */
                   1977:   ic->tme_m68k_ireg_ccr = flags;
                   1978:   TME_M68K_INSN_OK;
                   1979: }
                   1980: 
                   1981: /* the roxr function on a 16-byte EA: */
                   1982: TME_M68K_INSN(tme_m68k_roxr16)
                   1983: {
                   1984:   unsigned int count;
                   1985:   tme_uint8_t xbit;
                   1986:   tme_uint16_t res;
                   1987:   tme_uint8_t flags;
                   1988: 
                   1989:   /* get the count and operand: */
                   1990:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   1991:   res = TME_M68K_INSN_OP1(tme_uint16_t);
                   1992: 
                   1993:   /* generate the X, V, and C flags assuming the count is zero: */
                   1994:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   1995:   xbit = (flags / TME_M68K_FLAG_X);
                   1996:   flags |= (xbit * TME_M68K_FLAG_C);
                   1997: 
                   1998:   /* if the count is nonzero, update the result and
                   1999:      generate the X, V, and C flags: */
                   2000:   if (count > 0) {
                   2001:     count %= (16 + 1);
                   2002:     flags = xbit;
                   2003:     if (count > 0) {
                   2004:       flags = (res >> (count - 1)) & 1;
                   2005:       if (16 > SHIFTMAX_INT16_T
                   2006:           && count == 16) {
                   2007:         res = (res << ((16 + 1) - 16)) | (xbit << (16 - 16)) | 0;
                   2008:       }
                   2009:       else if (16 > SHIFTMAX_INT16_T
                   2010:                && count == 1) {
                   2011:         res = 0 | (xbit << (16 - 1)) | (res >> 1);
                   2012:       }
                   2013:       else {
                   2014:         res = (res << ((16 + 1) - count)) | (xbit << (16 - count)) | (res >> count);
                   2015:       }
                   2016:     }
                   2017:     flags *= TME_M68K_FLAG_C;
                   2018:     flags |= (flags * TME_M68K_FLAG_X);
                   2019:   }
                   2020: 
                   2021:   /* store the result: */
                   2022:   TME_M68K_INSN_OP1(tme_uint16_t) = res;
                   2023: 
                   2024:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   2025:      know the bit we want is within the range of the type, to try
                   2026:      to affect the generated assembly: */
                   2027:   flags |= ((tme_uint8_t) (((tme_uint16_t) res) >> (16 - 1))) * TME_M68K_FLAG_N;
                   2028: 
                   2029:   /* generate the Z flag: */
                   2030:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2031: 
                   2032:   /* store the flags: */
                   2033:   ic->tme_m68k_ireg_ccr = flags;
                   2034:   TME_M68K_INSN_OK;
                   2035: }
                   2036: 
                   2037: /* the movep_rm function on a 16-bit dreg: */
                   2038: TME_M68K_INSN(tme_m68k_movep_rm16)
                   2039: {
                   2040:   unsigned int function_code;
                   2041:   tme_uint32_t linear_address;
                   2042:   tme_uint16_t value;
                   2043:   int dreg;
                   2044: 
                   2045:   TME_M68K_INSN_CANFAULT;
                   2046: 
                   2047:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   2048:   linear_address = TME_M68K_INSN_OP1(tme_uint32_t);
                   2049:   linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP);
                   2050:   dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   2051:   value = ic->tme_m68k_ireg_uint16(dreg << 1);
                   2052:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2053:     ic->_tme_m68k_ea_function_code = function_code;
                   2054:     ic->_tme_m68k_ea_address = linear_address;
                   2055:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 8, 8);
                   2056:   }
                   2057:   tme_m68k_write_memx8(ic);
                   2058:   linear_address += 2;
                   2059:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2060:     ic->_tme_m68k_ea_function_code = function_code;
                   2061:     ic->_tme_m68k_ea_address = linear_address;
                   2062:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 0, 8);
                   2063:   }
                   2064:   tme_m68k_write_memx8(ic);
                   2065:   linear_address += 2;
                   2066:   TME_M68K_INSN_OK;
                   2067: }
                   2068: 
                   2069: /* the movem_rm function on 16-bit registers: */
                   2070: TME_M68K_INSN(tme_m68k_movem_rm16)
                   2071: {
                   2072:   int ireg, direction;
                   2073:   tme_uint16_t mask, bit;
                   2074:   unsigned int ea_mode;
                   2075:   tme_uint32_t addend;
1.1.1.4   root     2076:   tme_uint32_t total_size;
                   2077:   /* get the register mask, and figure out the total size
                   2078:      of the transfer: */
                   2079:   mask = TME_M68K_INSN_SPECOP;
                   2080:   total_size = 0;
                   2081:   if (mask != 0) {
                   2082:     TME_M68K_INSN_CANFAULT;
                   2083:     bit = mask;
                   2084:     do {
                   2085:       total_size += sizeof(tme_uint16_t);
                   2086:       bit &= (bit - 1);
                   2087:     } while (bit != 0);
                   2088:   }
1.1       root     2089: 
                   2090:   /* figure out what direction to move in, and where to start from: */
                   2091:   ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3);
                   2092:   direction = 1;
                   2093:   ireg = TME_M68K_IREG_D0;
                   2094:   if (ea_mode == 4) {
                   2095:     direction = -1;
                   2096:     ireg = TME_M68K_IREG_A7;
                   2097:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     2098: 
                   2099:       /* "For the MC68020, MC68030, MC68040, and CPU32, if
                   2100:          the addressing register is also moved to memory, the
                   2101:          value written is the initial register value decremented 
                   2102:          by the size of the operation. The MC68000 and MC68010 
                   2103:          write the initial register value (not decremented)." */
                   2104:       if (ic->tme_m68k_type >= TME_M68K_M68020) {
                   2105:         ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
                   2106:                                  + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
                   2107:           = (ic->_tme_m68k_ea_address - total_size);
                   2108:       }
                   2109: 
                   2110:       /* predecrement the effective address for the first transfer: */
1.1       root     2111:       ic->_tme_m68k_ea_address -= sizeof(tme_uint16_t);
                   2112:     }
                   2113:   }
                   2114:   addend = (tme_uint32_t) (direction * sizeof(tme_uint16_t));
                   2115: 
                   2116:   /* do the transfer: */
                   2117:   for (bit = 1; bit != 0; bit <<= 1) {
                   2118:     if (mask & bit) {
                   2119:       if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2120:         ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg << 1);
                   2121:       }
                   2122:       tme_m68k_write_memx16(ic);
                   2123:       if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2124:         ic->_tme_m68k_ea_address += addend;
                   2125:       }
                   2126:     }
                   2127:     ireg += direction;
                   2128:   }
                   2129: 
                   2130:   /* if this is the predecrement mode, update the address register: */
1.1.1.4   root     2131:   /* "For the MC68020, MC68030, MC68040, and CPU32, if
                   2132:      the addressing register is also moved to memory, the
                   2133:      value written is the initial register value decremented 
                   2134:      by the size of the operation. The MC68000 and MC68010 
                   2135:      write the initial register value (not decremented)." */
                   2136:   if (ea_mode == 4
                   2137:       && ic->tme_m68k_type < TME_M68K_M68020) {
1.1       root     2138:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
                   2139:                               + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
                   2140:       = (ic->_tme_m68k_ea_address + sizeof(tme_uint16_t));
                   2141:   }
                   2142:   TME_M68K_INSN_OK;
                   2143: }
                   2144: 
                   2145: /* the movep_mr function on a 16-bit dreg: */
                   2146: TME_M68K_INSN(tme_m68k_movep_mr16)
                   2147: {
                   2148:   unsigned int function_code;
                   2149:   tme_uint32_t linear_address;
                   2150:   int dreg;
                   2151: 
                   2152:   TME_M68K_INSN_CANFAULT;
                   2153: 
                   2154:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   2155:   linear_address = TME_M68K_INSN_OP1(tme_uint32_t);
                   2156:   linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP);
                   2157:   dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   2158:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2159:     ic->_tme_m68k_ea_function_code = function_code;
                   2160:     ic->_tme_m68k_ea_address = linear_address;
                   2161:   }
                   2162:   tme_m68k_read_memx8(ic);
                   2163:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2164:     TME_FIELD_DEPOSIT16(ic->tme_m68k_ireg_uint16(dreg << 1), 8, 8, ic->tme_m68k_ireg_memx8);
                   2165:   }
                   2166:   linear_address += 2;
                   2167:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2168:     ic->_tme_m68k_ea_function_code = function_code;
                   2169:     ic->_tme_m68k_ea_address = linear_address;
                   2170:   }
                   2171:   tme_m68k_read_memx8(ic);
                   2172:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2173:     TME_FIELD_DEPOSIT16(ic->tme_m68k_ireg_uint16(dreg << 1), 0, 8, ic->tme_m68k_ireg_memx8);
                   2174:   }
                   2175:   linear_address += 2;
                   2176:   TME_M68K_INSN_OK;
                   2177: }
                   2178: 
                   2179: /* the movem_mr function on 16-bit registers: */
                   2180: TME_M68K_INSN(tme_m68k_movem_mr16)
                   2181: {
                   2182:   int ireg, direction;
                   2183:   tme_uint16_t mask, bit;
                   2184:   unsigned int ea_mode;
                   2185:   tme_uint32_t addend;
1.1.1.4   root     2186:   tme_uint32_t total_size;
                   2187:   /* get the register mask, and figure out the total size
                   2188:      of the transfer: */
                   2189:   mask = TME_M68K_INSN_SPECOP;
                   2190:   total_size = 0;
                   2191:   if (mask != 0) {
                   2192:     TME_M68K_INSN_CANFAULT;
                   2193:     bit = mask;
                   2194:     do {
                   2195:       total_size += sizeof(tme_uint16_t);
                   2196:       bit &= (bit - 1);
                   2197:     } while (bit != 0);
                   2198:   }
1.1       root     2199: 
                   2200:   /* figure out what direction to move in, and where to start from: */
                   2201:   ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3);
                   2202:   direction = 1;
                   2203:   ireg = TME_M68K_IREG_D0;
                   2204:   addend = (tme_uint32_t) (direction * sizeof(tme_uint16_t));
                   2205: 
                   2206:   /* do the transfer: */
                   2207:   for (bit = 1; bit != 0; bit <<= 1) {
                   2208:     if (mask & bit) {
                   2209:       tme_m68k_read_memx16(ic);
                   2210:       if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2211:         ic->tme_m68k_ireg_uint32(ireg) = TME_EXT_S16_U32((tme_int16_t) ic->tme_m68k_ireg_memx16);
                   2212:         ic->_tme_m68k_ea_address += addend;
                   2213:       }
                   2214:     }
                   2215:     ireg += direction;
                   2216:   }
                   2217: 
                   2218:   /* if this is the postincrement mode, update the address register: */
                   2219:   if (ea_mode == 3) {
                   2220:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
                   2221:                               + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
                   2222:       = ic->_tme_m68k_ea_address;
                   2223:   }
                   2224:   TME_M68K_INSN_OK;
                   2225: }
                   2226: 
                   2227: /* chk16: */
                   2228: TME_M68K_INSN(tme_m68k_chk16)
                   2229: {
                   2230:   if (*((tme_int16_t *) _op0) < 0) {
                   2231:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_N;
1.1.1.3   root     2232:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root     2233:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3   root     2234:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK));
1.1       root     2235:   }
                   2236:   if (*((tme_int16_t *) _op0) > *((tme_int16_t *) _op1)) {
                   2237:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_N;
1.1.1.3   root     2238:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root     2239:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3   root     2240:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK));
1.1       root     2241:   }
                   2242:   TME_M68K_INSN_OK;
                   2243: }
                   2244: 
                   2245: /* cas16: */
                   2246: TME_M68K_INSN(tme_m68k_cas16)
                   2247: {
1.1.1.4   root     2248:   struct tme_m68k_rmw rmw;
1.1       root     2249:   struct tme_m68k_tlb *tlb;
                   2250:   int ireg_dc, ireg_du;
1.1.1.4   root     2251:   tme_uint16_t value_dc, value_du, value_mem;
1.1       root     2252: 
                   2253:   /* start the read/modify/write cycle: */
1.1.1.4   root     2254:   rmw.tme_m68k_rmw_addresses[0] = ic->_tme_m68k_ea_address;
                   2255:   rmw.tme_m68k_rmw_address_count = 1;
                   2256:   rmw.tme_m68k_rmw_size = sizeof(tme_uint16_t);
                   2257:   if (tme_m68k_rmw_start(ic,
                   2258:                          &rmw)) {
1.1       root     2259:     TME_M68K_INSN_OK;
                   2260:   }
                   2261: 
1.1.1.4   root     2262:   /* get the compare and update registers: */
                   2263:   ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
                   2264:   ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 6, 3);
                   2265: 
                   2266:   /* if we can do the fast compare-and-exchange: */
                   2267:   if (!rmw.tme_m68k_rmw_slow_reads[0]) {
                   2268: 
                   2269:     /* get the compare and update values in big-endian byte order: */
                   2270:     value_dc = ic->tme_m68k_ireg_uint16(ireg_dc << 1);
                   2271:     value_du = ic->tme_m68k_ireg_uint16(ireg_du << 1);
                   2272:     value_dc = tme_htobe_u16(value_dc);
                   2273:     value_du = tme_htobe_u16(value_du);
                   2274: 
                   2275:     /* get this TLB entry: */
                   2276:     tlb = rmw.tme_m68k_rmw_tlbs[0];
                   2277: 
                   2278:     /* this TLB entry must allow fast reading and fast writing
                   2279:        to the same memory: */
                   2280:     assert (tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF
                   2281:             && tlb->tme_m68k_tlb_emulator_off_write == tlb->tme_m68k_tlb_emulator_off_read);
                   2282: 
                   2283:     /* do the compare-and-exchange: */
                   2284:     value_mem =
                   2285:       tme_memory_atomic_cx16(((tme_shared tme_uint16_t *)
                   2286:                                    (tlb->tme_m68k_tlb_emulator_off_read
                   2287:                                     + ic->_tme_m68k_ea_address)),
                   2288:                                   value_dc,
                   2289:                                   value_du,
                   2290:                                   tlb->tme_m68k_tlb_bus_rwlock,
                   2291:                                   sizeof(tme_uint8_t));
                   2292:     ic->tme_m68k_ireg_memx16 = tme_betoh_u16(value_mem);
                   2293:   }
                   2294: 
                   2295:   /* compare the compare operand to the effective address operand: */
                   2296:   tme_m68k_cmp16(ic, &ic->tme_m68k_ireg_uint16(ireg_dc << 1), &ic->tme_m68k_ireg_memx16);
1.1       root     2297: 
1.1.1.4   root     2298:   /* if the comparison succeeded: */
1.1       root     2299:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
1.1.1.4   root     2300: 
                   2301:     /* write the update operand to the effective address operand: */
                   2302:     ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg_du << 1);
1.1       root     2303:   }
                   2304: 
1.1.1.4   root     2305:   /* otherwise, the comparison failed: */
                   2306:   else {
                   2307: 
                   2308:     /* write the effective address operand to the compare operand: */
                   2309:     ic->tme_m68k_ireg_uint16(ireg_dc << 1) = ic->tme_m68k_ireg_memx16;
                   2310:   }
1.1       root     2311: 
1.1.1.4   root     2312:   /* finish the read/modify/write cycle: */
                   2313:   tme_m68k_rmw_finish(ic,
                   2314:                       &rmw,
                   2315:                       (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) != 0);
1.1       root     2316:   TME_M68K_INSN_OK;
                   2317: }
                   2318: 
                   2319: /* cas2_16: */
                   2320: TME_M68K_INSN(tme_m68k_cas2_16)
                   2321: {
1.1.1.4   root     2322:   struct tme_m68k_rmw rmw;
                   2323:   int ireg_dcx, ireg_dux;
                   2324:   int ireg_dcy, ireg_duy;
                   2325:   const tme_uint16_t specopx = TME_M68K_INSN_SPECOP;
                   2326:   const tme_uint16_t specopy = TME_M68K_INSN_OP0(tme_uint16_t);
1.1       root     2327: 
                   2328:   /* start the read/modify/write cycle: */
1.1.1.4   root     2329:   ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   2330:   rmw.tme_m68k_rmw_addresses[0] = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
                   2331:                                                            + TME_FIELD_EXTRACTU(specopx, 12, 4));
                   2332:   rmw.tme_m68k_rmw_addresses[1] = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
                   2333:                                                            + TME_FIELD_EXTRACTU(specopy, 12, 4));
                   2334:   rmw.tme_m68k_rmw_address_count = 2;
                   2335:   rmw.tme_m68k_rmw_size = sizeof(tme_uint16_t);
                   2336:   if (tme_m68k_rmw_start(ic,
                   2337:                          &rmw)) {
1.1       root     2338:     TME_M68K_INSN_OK;
                   2339:   }
                   2340: 
1.1.1.4   root     2341:   /* do the comparisons: */
                   2342:   ireg_dcx = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
                   2343:   ireg_dcy = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3);
                   2344:   tme_m68k_cmp16(ic,
                   2345:                  &ic->tme_m68k_ireg_uint16(ireg_dcx << 1),
                   2346:                  &ic->tme_m68k_ireg_memx16);
1.1       root     2347:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
1.1.1.4   root     2348:     tme_m68k_cmp16(ic,
                   2349:                    &ic->tme_m68k_ireg_uint16(ireg_dcy << 1),
                   2350:                    &ic->tme_m68k_ireg_memy16);
1.1       root     2351:   }
                   2352: 
1.1.1.4   root     2353:   /* if the comparisons succeeded: */
1.1       root     2354:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
1.1.1.4   root     2355: 
                   2356:     /* write the update operands to the effective address operands: */
                   2357:     ireg_dux = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3);
                   2358:     ireg_duy = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 6, 3);
                   2359:     ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg_dux << 1);
                   2360:     ic->tme_m68k_ireg_memy16 = ic->tme_m68k_ireg_uint16(ireg_duy << 1);
1.1       root     2361:   }
                   2362: 
1.1.1.4   root     2363:   /* otherwise, the comparisons failed: */
                   2364:   else {
1.1       root     2365: 
1.1.1.4   root     2366:     /* write the effective address operands to the compare operands.
                   2367:        "If Dc1 and Dc2 specify the same data register and the comparison
                   2368:         fails, memory operand 1 is stored in the data register." */
                   2369:     ic->tme_m68k_ireg_uint16(ireg_dcy << 1) = ic->tme_m68k_ireg_memy16;
                   2370:     ic->tme_m68k_ireg_uint16(ireg_dcx << 1) = ic->tme_m68k_ireg_memx16;
                   2371:   }
                   2372: 
                   2373:   /* finish the read/modify/write cycle: */
                   2374:   tme_m68k_rmw_finish(ic,
                   2375:                       &rmw,
                   2376:                       (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) != 0);
1.1       root     2377:   TME_M68K_INSN_OK;
                   2378: }
                   2379: 
                   2380: /* moves16: */
                   2381: TME_M68K_INSN(tme_m68k_moves16)
                   2382: {
                   2383:   int ireg;
1.1.1.4   root     2384:   tme_uint16_t ireg_value;
1.1.1.3   root     2385:   unsigned int ea_reg;
                   2386:   unsigned int increment;
                   2387:   TME_M68K_INSN_PRIV;
                   2388:   TME_M68K_INSN_CANFAULT;
1.1       root     2389:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
1.1.1.3   root     2390: 
1.1.1.4   root     2391:   /* in case we're storing the same address register used in a
                   2392:      postincrement or predecrement EA, save the current value
                   2393:      of the register now: */
                   2394:   ireg_value = ic->tme_m68k_ireg_uint16(ireg << 1);
                   2395: 
1.1.1.3   root     2396:   /* we have to handle postincrement and predecrement ourselves: */
                   2397:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2398:     ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   2399:     increment = TME_M68K_SIZE_16;
                   2400:     if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) {
                   2401:       increment = TME_M68K_SIZE_16;
                   2402:     }
                   2403:     switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) {
                   2404:     case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break;
                   2405:     case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break;
                   2406:     default: break;
                   2407:     }
                   2408:   }
                   2409: 
1.1       root     2410:   if (TME_M68K_INSN_SPECOP & TME_BIT(11)) {
1.1.1.3   root     2411:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     2412:       ic->tme_m68k_ireg_memx16 = ireg_value;
1.1.1.3   root     2413:       ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc;
                   2414:     }
                   2415:     tme_m68k_write_memx16(ic);
1.1       root     2416:   }
                   2417:   else {
1.1.1.3   root     2418:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2419:       ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc;
                   2420:     }
                   2421:     tme_m68k_read_memx16(ic);
1.1       root     2422:     if (ireg >= TME_M68K_IREG_A0) {
                   2423:       ic->tme_m68k_ireg_uint32(ireg) = 
                   2424:         TME_EXT_S16_U32((tme_int16_t) ic->tme_m68k_ireg_memx16);
                   2425:     }
                   2426:     else
                   2427:       ic->tme_m68k_ireg_uint16(ireg << 1) = ic->tme_m68k_ireg_memx16;
                   2428:   }
                   2429:   TME_M68K_INSN_OK;
                   2430: }
                   2431: 
                   2432: /* this does a 32-bit "add SRC, DST": */
                   2433: TME_M68K_INSN(tme_m68k_add32)
                   2434: {
                   2435:   tme_uint32_t res, op0, op1;
                   2436:   tme_uint8_t flags;
                   2437: 
                   2438:   /* load the operand(s): */
                   2439:   op0 = *((tme_uint32_t *) _op0);
                   2440:   op1 = *((tme_uint32_t *) _op1);
                   2441: 
                   2442:   /* perform the operation: */
                   2443:   res = op1 + op0;
                   2444: 
                   2445:   /* store the result: */
                   2446:   *((tme_uint32_t *) _op1) = res;
                   2447: 
                   2448:   /* set the flags: */
                   2449:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2450:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2451:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffffffff) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   2452:   if (op0 > (op1 ^ 0xffffffff)) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   2453:   ic->tme_m68k_ireg_ccr = flags;
                   2454: 
                   2455:   TME_M68K_INSN_OK;
                   2456: }
                   2457: 
                   2458: /* this does a 32-bit "sub SRC, DST": */
                   2459: TME_M68K_INSN(tme_m68k_sub32)
                   2460: {
                   2461:   tme_uint32_t res, op0, op1;
                   2462:   tme_uint8_t flags;
                   2463: 
                   2464:   /* load the operand(s): */
                   2465:   op0 = *((tme_uint32_t *) _op0);
                   2466:   op1 = *((tme_uint32_t *) _op1);
                   2467: 
                   2468:   /* perform the operation: */
                   2469:   res = op1 - op0;
                   2470: 
                   2471:   /* store the result: */
                   2472:   *((tme_uint32_t *) _op1) = res;
                   2473: 
                   2474:   /* set the flags: */
                   2475:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2476:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2477:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   2478:   if (op0 > op1) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   2479:   ic->tme_m68k_ireg_ccr = flags;
                   2480: 
                   2481:   TME_M68K_INSN_OK;
                   2482: }
                   2483: 
                   2484: /* this does a 32-bit "cmp SRC, DST": */
                   2485: TME_M68K_INSN(tme_m68k_cmp32)
                   2486: {
                   2487:   tme_uint32_t res, op0, op1;
                   2488:   tme_uint8_t flags;
                   2489: 
                   2490:   /* load the operand(s): */
                   2491:   op0 = *((tme_uint32_t *) _op0);
                   2492:   op1 = *((tme_uint32_t *) _op1);
                   2493: 
                   2494:   /* perform the operation: */
                   2495:   res = op1 - op0;
                   2496: 
                   2497:   /* set the flags: */
                   2498:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2499:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2500:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   2501:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
                   2502:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2503:   ic->tme_m68k_ireg_ccr = flags;
                   2504: 
                   2505:   TME_M68K_INSN_OK;
                   2506: }
                   2507: 
                   2508: /* this does a 32-bit "neg DST": */
                   2509: TME_M68K_INSN(tme_m68k_neg32)
                   2510: {
                   2511:   tme_uint32_t res, op1;
                   2512:   tme_uint8_t flags;
                   2513: 
                   2514:   /* load the operand(s): */
                   2515:   op1 = *((tme_uint32_t *) _op1);
                   2516: 
                   2517:   /* perform the operation: */
                   2518:   res = 0 - op1;
                   2519: 
                   2520:   /* store the result: */
                   2521:   *((tme_uint32_t *) _op1) = res;
                   2522: 
                   2523:   /* set the flags: */
                   2524:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2525:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2526:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   2527:   if (op1 > 0) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   2528:   ic->tme_m68k_ireg_ccr = flags;
                   2529: 
                   2530:   TME_M68K_INSN_OK;
                   2531: }
                   2532: 
                   2533: /* this does a 32-bit "or SRC, DST": */
                   2534: TME_M68K_INSN(tme_m68k_or32)
                   2535: {
                   2536:   tme_uint32_t res, op0, op1;
                   2537:   tme_uint8_t flags;
                   2538: 
                   2539:   /* load the operand(s): */
                   2540:   op0 = *((tme_uint32_t *) _op0);
                   2541:   op1 = *((tme_uint32_t *) _op1);
                   2542: 
                   2543:   /* perform the operation: */
                   2544:   res = op1 | op0;
                   2545: 
                   2546:   /* store the result: */
                   2547:   *((tme_uint32_t *) _op1) = res;
                   2548: 
                   2549:   /* set the flags: */
                   2550:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2551:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2552:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2553:   ic->tme_m68k_ireg_ccr = flags;
                   2554: 
                   2555:   TME_M68K_INSN_OK;
                   2556: }
                   2557: 
                   2558: /* this does a 32-bit "and SRC, DST": */
                   2559: TME_M68K_INSN(tme_m68k_and32)
                   2560: {
                   2561:   tme_uint32_t res, op0, op1;
                   2562:   tme_uint8_t flags;
                   2563: 
                   2564:   /* load the operand(s): */
                   2565:   op0 = *((tme_uint32_t *) _op0);
                   2566:   op1 = *((tme_uint32_t *) _op1);
                   2567: 
                   2568:   /* perform the operation: */
                   2569:   res = op1 & op0;
                   2570: 
                   2571:   /* store the result: */
                   2572:   *((tme_uint32_t *) _op1) = res;
                   2573: 
                   2574:   /* set the flags: */
                   2575:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2576:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2577:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2578:   ic->tme_m68k_ireg_ccr = flags;
                   2579: 
                   2580:   TME_M68K_INSN_OK;
                   2581: }
                   2582: 
                   2583: /* this does a 32-bit "eor SRC, DST": */
                   2584: TME_M68K_INSN(tme_m68k_eor32)
                   2585: {
                   2586:   tme_uint32_t res, op0, op1;
                   2587:   tme_uint8_t flags;
                   2588: 
                   2589:   /* load the operand(s): */
                   2590:   op0 = *((tme_uint32_t *) _op0);
                   2591:   op1 = *((tme_uint32_t *) _op1);
                   2592: 
                   2593:   /* perform the operation: */
                   2594:   res = op1 ^ op0;
                   2595: 
                   2596:   /* store the result: */
                   2597:   *((tme_uint32_t *) _op1) = res;
                   2598: 
                   2599:   /* set the flags: */
                   2600:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2601:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2602:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2603:   ic->tme_m68k_ireg_ccr = flags;
                   2604: 
                   2605:   TME_M68K_INSN_OK;
                   2606: }
                   2607: 
                   2608: /* this does a 32-bit "not DST": */
                   2609: TME_M68K_INSN(tme_m68k_not32)
                   2610: {
                   2611:   tme_uint32_t res, op1;
                   2612:   tme_uint8_t flags;
                   2613: 
                   2614:   /* load the operand(s): */
                   2615:   op1 = *((tme_uint32_t *) _op1);
                   2616: 
                   2617:   /* perform the operation: */
                   2618:   res = ~ op1;
                   2619: 
                   2620:   /* store the result: */
                   2621:   *((tme_uint32_t *) _op1) = res;
                   2622: 
                   2623:   /* set the flags: */
                   2624:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2625:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2626:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2627:   ic->tme_m68k_ireg_ccr = flags;
                   2628: 
                   2629:   TME_M68K_INSN_OK;
                   2630: }
                   2631: 
                   2632: /* this does a 32-bit "tst DST": */
                   2633: TME_M68K_INSN(tme_m68k_tst32)
                   2634: {
                   2635:   tme_uint32_t res, op1;
                   2636:   tme_uint8_t flags;
                   2637: 
                   2638:   /* load the operand(s): */
                   2639:   op1 = *((tme_uint32_t *) _op1);
                   2640: 
                   2641:   /* perform the operation: */
                   2642:   res = op1;
                   2643: 
                   2644:   /* set the flags: */
                   2645:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2646:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2647:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2648:   ic->tme_m68k_ireg_ccr = flags;
                   2649: 
                   2650:   TME_M68K_INSN_OK;
                   2651: }
                   2652: 
                   2653: /* this does a 32-bit "move DST": */
                   2654: TME_M68K_INSN(tme_m68k_move32)
                   2655: {
                   2656:   tme_uint32_t res, op1;
                   2657:   tme_uint8_t flags;
                   2658: 
                   2659:   /* load the operand(s): */
                   2660:   op1 = *((tme_uint32_t *) _op1);
                   2661: 
                   2662:   /* perform the operation: */
                   2663:   res = op1;
                   2664: 
                   2665:   /* store the result: */
                   2666:   *((tme_uint32_t *) _op0) = res;
                   2667: 
                   2668:   /* set the flags: */
                   2669:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2670:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2671:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2672:   ic->tme_m68k_ireg_ccr = flags;
                   2673: 
                   2674:   TME_M68K_INSN_OK;
                   2675: }
                   2676: 
                   2677: /* this does a 32-bit "moveq DST": */
                   2678: TME_M68K_INSN(tme_m68k_moveq32)
                   2679: {
                   2680:   tme_uint32_t res;
                   2681:   tme_uint8_t flags;
                   2682: 
                   2683:   /* load the operand(s): */
                   2684: 
                   2685:   /* perform the operation: */
                   2686:   res = TME_EXT_S8_U32((tme_int8_t) (TME_M68K_INSN_OPCODE & 0xff));
                   2687: 
                   2688:   /* store the result: */
                   2689:   *((tme_uint32_t *) _op1) = res;
                   2690: 
                   2691:   /* set the flags: */
                   2692:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2693:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2694:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2695:   ic->tme_m68k_ireg_ccr = flags;
                   2696: 
                   2697:   TME_M68K_INSN_OK;
                   2698: }
                   2699: 
                   2700: /* this does a 32-bit "clr DST": */
                   2701: TME_M68K_INSN(tme_m68k_clr32)
                   2702: {
                   2703:   tme_uint32_t res;
                   2704:   tme_uint8_t flags;
                   2705: 
                   2706:   /* load the operand(s): */
                   2707: 
                   2708:   /* perform the operation: */
                   2709:   res = 0;
                   2710: 
                   2711:   /* store the result: */
                   2712:   *((tme_uint32_t *) _op1) = res;
                   2713: 
                   2714:   /* set the flags: */
                   2715:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2716:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2717:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2718:   ic->tme_m68k_ireg_ccr = flags;
                   2719: 
                   2720:   TME_M68K_INSN_OK;
                   2721: }
                   2722: 
                   2723: /* this does a 32-bit "negx DST": */
                   2724: TME_M68K_INSN(tme_m68k_negx32)
                   2725: {
                   2726:   tme_uint32_t res, op1;
                   2727:   tme_uint8_t flags;
                   2728: 
                   2729:   /* load the operand(s): */
                   2730:   op1 = *((tme_uint32_t *) _op1);
                   2731: 
                   2732:   /* perform the operation: */
                   2733:   res = 0 - op1 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                   2734: 
                   2735:   /* store the result: */
                   2736:   *((tme_uint32_t *) _op1) = res;
                   2737: 
                   2738:   /* set the flags: */
                   2739:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2740:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                   2741:   flags |= ((tme_uint8_t) (((op1 ^ 0) & (0 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   2742:   if (op1 > 0 || (op1 == 0 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   2743:   ic->tme_m68k_ireg_ccr = flags;
                   2744: 
                   2745:   TME_M68K_INSN_OK;
                   2746: }
                   2747: 
                   2748: /* this does a 32-bit "addx SRC, DST": */
                   2749: TME_M68K_INSN(tme_m68k_addx32)
                   2750: {
                   2751:   tme_uint32_t res, op0, op1;
                   2752:   tme_uint8_t flags;
                   2753: 
                   2754:   /* load the operand(s): */
                   2755:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   2756:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   2757:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   2758:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t);
                   2759:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t);
                   2760:   tme_uint16_t memory;
                   2761: 
                   2762:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
                   2763:   if (memory) {
                   2764:     TME_M68K_INSN_CANFAULT;
                   2765:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2766:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
                   2767:       ic->_tme_m68k_ea_function_code = function_code;
                   2768:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                   2769:     }
                   2770:     tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32);
1.1.1.4   root     2771:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2772:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
                   2773:       ic->_tme_m68k_ea_function_code = function_code;
                   2774:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   2775:     }
                   2776:     tme_m68k_read_memx32(ic);
1.1       root     2777:     op1 = ic->tme_m68k_ireg_memx32;
                   2778:     op0 = ic->tme_m68k_ireg_memy32;
                   2779:   }
                   2780:   else {
                   2781:     op0 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_src));
                   2782:     op1 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst));
                   2783:   }
                   2784: 
                   2785:   /* perform the operation: */
                   2786:   res = op1 + op0 + ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                   2787: 
                   2788:   /* store the result: */
                   2789:   if (memory) {
                   2790:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2791:       ic->tme_m68k_ireg_memx32 = res;
                   2792:       ic->_tme_m68k_ea_function_code = function_code;
                   2793:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   2794:     }
                   2795:     tme_m68k_write_memx32(ic);
                   2796:   }
                   2797:   else {
                   2798:     ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst)) = res;
                   2799:   }
                   2800: 
                   2801:   /* set the flags: */
                   2802:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2803:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                   2804:   flags |= ((tme_uint8_t) (((op0 ^ op1 ^ 0xffffffff) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   2805:   if (op0 > (op1 ^ 0xffffffff) || (op0 == (op1 ^ 0xffffffff) && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   2806:   ic->tme_m68k_ireg_ccr = flags;
                   2807: 
                   2808:   TME_M68K_INSN_OK;
                   2809: }
                   2810: 
                   2811: /* this does a 32-bit "subx SRC, DST": */
                   2812: TME_M68K_INSN(tme_m68k_subx32)
                   2813: {
                   2814:   tme_uint32_t res, op0, op1;
                   2815:   tme_uint8_t flags;
                   2816: 
                   2817:   /* load the operand(s): */
                   2818:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   2819:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   2820:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   2821:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t);
                   2822:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t);
                   2823:   tme_uint16_t memory;
                   2824: 
                   2825:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3));
                   2826:   if (memory) {
                   2827:     TME_M68K_INSN_CANFAULT;
                   2828:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2829:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) -= ireg_src_adjust;
                   2830:       ic->_tme_m68k_ea_function_code = function_code;
                   2831:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                   2832:     }
                   2833:     tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32);
1.1.1.4   root     2834:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2835:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) -= ireg_dst_adjust;
                   2836:       ic->_tme_m68k_ea_function_code = function_code;
                   2837:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   2838:     }
                   2839:     tme_m68k_read_memx32(ic);
1.1       root     2840:     op1 = ic->tme_m68k_ireg_memx32;
                   2841:     op0 = ic->tme_m68k_ireg_memy32;
                   2842:   }
                   2843:   else {
                   2844:     op0 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_src));
                   2845:     op1 = ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst));
                   2846:   }
                   2847: 
                   2848:   /* perform the operation: */
                   2849:   res = op1 - op0 - ((ic->tme_m68k_ireg_ccr / TME_M68K_FLAG_X) & 1);
                   2850: 
                   2851:   /* store the result: */
                   2852:   if (memory) {
                   2853:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2854:       ic->tme_m68k_ireg_memx32 = res;
                   2855:       ic->_tme_m68k_ea_function_code = function_code;
                   2856:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   2857:     }
                   2858:     tme_m68k_write_memx32(ic);
                   2859:   }
                   2860:   else {
                   2861:     ic->tme_m68k_ireg_uint32((TME_M68K_IREG_D0 + ireg_dst)) = res;
                   2862:   }
                   2863: 
                   2864:   /* set the flags: */
                   2865:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2866:   if (res == 0) flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z);
                   2867:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   2868:   if (op0 > op1 || (op0 == op1 && (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X))) flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   2869:   ic->tme_m68k_ireg_ccr = flags;
                   2870: 
                   2871:   TME_M68K_INSN_OK;
                   2872: }
                   2873: 
                   2874: /* this does a 32-bit "cmpm SRC, DST": */
                   2875: TME_M68K_INSN(tme_m68k_cmpm32)
                   2876: {
                   2877:   tme_uint32_t res, op0, op1;
                   2878:   tme_uint8_t flags;
                   2879: 
                   2880:   /* load the operand(s): */
                   2881:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   2882:   int ireg_src = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   2883:   int ireg_dst = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   2884:   tme_uint32_t ireg_src_adjust = sizeof(tme_uint32_t);
                   2885:   tme_uint32_t ireg_dst_adjust = sizeof(tme_uint32_t);
                   2886: 
                   2887:   TME_M68K_INSN_CANFAULT;
                   2888: 
                   2889:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2890:     ic->_tme_m68k_ea_function_code = function_code;
                   2891:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src);
                   2892:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_src) += ireg_src_adjust;
                   2893:   }
                   2894:   tme_m68k_read_mem32(ic, TME_M68K_IREG_MEMY32);
1.1.1.4   root     2895:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2896:     ic->_tme_m68k_ea_function_code = function_code;
                   2897:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst);
                   2898:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ireg_dst) += ireg_dst_adjust;
                   2899:   }
                   2900:   tme_m68k_read_memx32(ic);
1.1       root     2901:   op1 = ic->tme_m68k_ireg_memx32;
                   2902:   op0 = ic->tme_m68k_ireg_memy32;
                   2903: 
                   2904:   /* perform the operation: */
                   2905:   res = op1 - op0;
                   2906: 
                   2907:   /* set the flags: */
                   2908:   flags = ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   2909:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   2910:   flags |= ((tme_uint8_t) (((op0 ^ op1) & (op1 ^ res)) >> (32 - 1))) * TME_M68K_FLAG_V;
                   2911:   if (op0 > op1) flags |= TME_M68K_FLAG_C;
                   2912:   flags |= (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X);
                   2913:   ic->tme_m68k_ireg_ccr = flags;
                   2914: 
                   2915:   TME_M68K_INSN_OK;
                   2916: }
                   2917: 
1.1.1.4   root     2918: /* a move of an address register to a predecrement or
                   2919:    postincrement EA with that same address register, must
                   2920:    store the original value of the address register.  since the
                   2921:    predecrement and postincrement code in the executer updates
                   2922:    the address register before the move has happened, we wrap
                   2923:    the normal move function in this one, that gives an op1
                   2924:    argument that is the original value of the address register: */
                   2925: TME_M68K_INSN(tme_m68k_move_srpd32)
                   2926: {
                   2927:   /* NB: both this function and tme_m68k_move32()
                   2928:      get the source operand as _op1, and the destination
                   2929:      operand as _op0: */
                   2930:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2931:     *((tme_uint32_t *) _op0)
                   2932:       = (*((tme_uint32_t *) _op1)
                   2933:          + sizeof(tme_uint32_t));
                   2934:   }
                   2935:   tme_m68k_move32(ic, _op0, _op0);
                   2936: }
                   2937: 
                   2938: /* a move of an address register to a predecrement or
                   2939:    postincrement EA with that same address register, must
                   2940:    store the original value of the address register.  since the
                   2941:    predecrement and postincrement code in the executer updates
                   2942:    the address register before the move has happened, we wrap
                   2943:    the normal move function in this one, that gives an op1
                   2944:    argument that is the original value of the address register: */
                   2945: TME_M68K_INSN(tme_m68k_move_srpi32)
                   2946: {
                   2947:   /* NB: both this function and tme_m68k_move32()
                   2948:      get the source operand as _op1, and the destination
                   2949:      operand as _op0: */
                   2950:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   2951:     *((tme_uint32_t *) _op0)
                   2952:       = (*((tme_uint32_t *) _op1)
                   2953:          - sizeof(tme_uint32_t));
                   2954:   }
                   2955:   tme_m68k_move32(ic, _op0, _op0);
                   2956: }
                   2957: 
1.1       root     2958: /* the suba function on a 32-byte EA: */
                   2959: TME_M68K_INSN(tme_m68k_suba32)
                   2960: {
                   2961:   *((tme_int32_t *) _op1) -= *((tme_int32_t *) _op0);
                   2962:   TME_M68K_INSN_OK;
                   2963: }
                   2964: 
                   2965: /* the adda function on a 32-byte EA: */
                   2966: TME_M68K_INSN(tme_m68k_adda32)
                   2967: {
                   2968:   *((tme_int32_t *) _op1) += *((tme_int32_t *) _op0);
                   2969:   TME_M68K_INSN_OK;
                   2970: }
                   2971: 
                   2972: /* the movea function on a 32-byte EA: */
                   2973: TME_M68K_INSN(tme_m68k_movea32)
                   2974: {
                   2975:   *((tme_int32_t *) _op0) = *((tme_int32_t *) _op1);
                   2976:   TME_M68K_INSN_OK;
                   2977: }
                   2978: 
                   2979: /* the btst function on a 32-byte EA: */
                   2980: TME_M68K_INSN(tme_m68k_btst32)
                   2981: {
                   2982:   tme_uint32_t value, bit;
                   2983:   bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1));
                   2984:   value = TME_M68K_INSN_OP1(tme_uint32_t);
                   2985:   if (value & bit) {
                   2986:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
                   2987:   }
                   2988:   else {
                   2989:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                   2990:   }
                   2991:   TME_M68K_INSN_OK;
                   2992: }
                   2993: 
                   2994: /* the bchg function on a 32-byte EA: */
                   2995: TME_M68K_INSN(tme_m68k_bchg32)
                   2996: {
                   2997:   tme_uint32_t value, bit;
                   2998:   bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1));
                   2999:   value = TME_M68K_INSN_OP1(tme_uint32_t);
                   3000:   if (value & bit) {
                   3001:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
                   3002:   }
                   3003:   else {
                   3004:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                   3005:   }
                   3006:   TME_M68K_INSN_OP1(tme_uint32_t) = value ^ bit;
                   3007:   TME_M68K_INSN_OK;
                   3008: }
                   3009: 
                   3010: /* the bclr function on a 32-byte EA: */
                   3011: TME_M68K_INSN(tme_m68k_bclr32)
                   3012: {
                   3013:   tme_uint32_t value, bit;
                   3014:   bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1));
                   3015:   value = TME_M68K_INSN_OP1(tme_uint32_t);
                   3016:   if (value & bit) {
                   3017:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
                   3018:   }
                   3019:   else {
                   3020:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                   3021:   }
                   3022:   TME_M68K_INSN_OP1(tme_uint32_t) = value & ~bit;
                   3023:   TME_M68K_INSN_OK;
                   3024: }
                   3025: 
                   3026: /* the bset function on a 32-byte EA: */
                   3027: TME_M68K_INSN(tme_m68k_bset32)
                   3028: {
                   3029:   tme_uint32_t value, bit;
                   3030:   bit = _TME_BIT(tme_uint32_t, TME_M68K_INSN_OP0(tme_uint8_t) & (32 - 1));
                   3031:   value = TME_M68K_INSN_OP1(tme_uint32_t);
                   3032:   if (value & bit) {
                   3033:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_Z;
                   3034:   }
                   3035:   else {
                   3036:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_Z;
                   3037:   }
                   3038:   TME_M68K_INSN_OP1(tme_uint32_t) = value | bit;
                   3039:   TME_M68K_INSN_OK;
                   3040: }
                   3041: 
                   3042: /* the asl function on a 32-byte EA: */
                   3043: TME_M68K_INSN(tme_m68k_asl32)
                   3044: {
                   3045:   unsigned int count;
1.1.1.2   root     3046:   tme_uint32_t sign_bits, sign_bits_mask;
1.1       root     3047:   tme_uint32_t res;
                   3048:   tme_uint8_t flags;
                   3049: 
                   3050:   /* get the count and operand: */
                   3051:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   3052:   res = TME_M68K_INSN_OP1(tme_uint32_t);
                   3053: 
                   3054:   /* generate the X, V, and C flags assuming the count is zero: */
                   3055:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   3056: 
                   3057:   /* if the count is nonzero, update the result and
                   3058:      generate the X, V, and C flags: */
                   3059:   if (count > 0) {
                   3060: 
                   3061:     /* we need to see how the sign of the result will change during
                   3062:        shifting in order to generate V.
                   3063: 
                   3064:        in general, the idea is to get all of the bits that will ever
1.1.1.2   root     3065:        appear in the sign position into sign_bits, with a mask in
                   3066:        sign_bits_mask.  if (sign_bits & sign_bits_mask) is zero or
                   3067:        sign_bits_mask, clear V, else set V.
1.1       root     3068: 
1.1.1.2   root     3069:        start by loading the operand into sign_bits and setting
                   3070:        sign_bits_mask to all-bits-one.
1.1       root     3071: 
                   3072:        if the shift count is exactly 32 - 1, then all of the bits
                   3073:        of the operand will appear in the sign position.
                   3074: 
                   3075:        if the shift count is less than 32 - 1, then some of the
                   3076:        less significant bits of the operand will never appear in the
1.1.1.2   root     3077:        sign position, so we can shift sign_bits_mask to ignore them.
1.1       root     3078: 
                   3079:        if the shift count is greater than 32 - 1, then all of the
                   3080:        bits in the operand, plus at least one zero bit, will appear in
                   3081:        the sign position.  the only way that the sign bit will never
                   3082:        change during the shift is if the operand was zero to begin with.
1.1.1.2   root     3083:        without any changes to sign_bits or sign_bits_mask, the final
                   3084:        test will always work, except when sign_bits is all-bits-one.
                   3085:        the magic below clears the least-significant bit of sign_bits
                   3086:        iff sign_bits is all-bits-one: */
1.1       root     3087:     sign_bits = res;
                   3088:     if (63 > SHIFTMAX_INT32_T
                   3089:         && count > 32) {
                   3090:       res = 0;
                   3091:     }
                   3092:     res <<= (count - 1);
                   3093:     flags = (res >> (32 - 1));
                   3094:     flags *= TME_M68K_FLAG_C;
                   3095:     flags |= (flags * TME_M68K_FLAG_X);
                   3096:     res <<= 1;
1.1.1.2   root     3097:     sign_bits_mask = (tme_uint32_t) -1;
1.1       root     3098:     if (count != 32 - 1) {
                   3099:       if (count < 32) {
1.1.1.2   root     3100:         sign_bits_mask <<= ((32 - 1) - count);
1.1       root     3101:       }
                   3102:       else {
1.1.1.2   root     3103:         sign_bits ^= !(sign_bits + 1);
1.1       root     3104:       }
                   3105:     }
1.1.1.2   root     3106:     sign_bits &= sign_bits_mask;
                   3107:     if (sign_bits != 0 && sign_bits != sign_bits_mask) {
1.1       root     3108:       flags |= TME_M68K_FLAG_V;
                   3109:     }
                   3110:   }
                   3111: 
                   3112:   /* store the result: */
                   3113:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
                   3114: 
                   3115:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   3116:      know the bit we want is within the range of the type, to try
                   3117:      to affect the generated assembly: */
                   3118:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   3119: 
                   3120:   /* generate the Z flag: */
                   3121:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   3122: 
                   3123:   /* store the flags: */
                   3124:   ic->tme_m68k_ireg_ccr = flags;
                   3125:   TME_M68K_INSN_OK;
                   3126: }
                   3127: 
                   3128: /* the asr function on a 32-byte EA: */
                   3129: TME_M68K_INSN(tme_m68k_asr32)
                   3130: {
                   3131:   unsigned int count;
                   3132:   tme_int32_t res;
                   3133:   tme_uint8_t flags;
                   3134: 
                   3135:   /* get the count and operand: */
                   3136:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   3137:   res = TME_M68K_INSN_OP1(tme_int32_t);
                   3138: 
                   3139:   /* generate the X, V, and C flags assuming the count is zero: */
                   3140:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   3141: 
                   3142:   /* if the count is nonzero, update the result and
                   3143:      generate the X, V, and C flags: */
                   3144:   if (count > 0) {
                   3145:     if (63 > SHIFTMAX_INT32_T
                   3146:         && count > 32) {
1.1.1.3   root     3147:       res = 0 - (res < 0);
1.1       root     3148:     }
1.1.1.3   root     3149: #ifdef SHIFTSIGNED_INT32_T
1.1       root     3150:     res >>= (count - 1);
1.1.1.3   root     3151: #else  /* !SHIFTSIGNED_INT32_T */
                   3152:     for (; --count > 0; ) {
                   3153:       res = (res & ~((tme_int32_t) 1)) / 2;
                   3154:     }
                   3155: #endif /* !SHIFTSIGNED_INT32_T */
1.1       root     3156:     flags = (res & 1);
                   3157:     flags *= TME_M68K_FLAG_C;
                   3158:     flags |= (flags * TME_M68K_FLAG_X);
1.1.1.3   root     3159: #ifdef SHIFTSIGNED_INT32_T
1.1       root     3160:     res >>= 1;
1.1.1.3   root     3161: #else  /* !SHIFTSIGNED_INT32_T */
                   3162:     res = (res & ~((tme_int32_t) 1)) / 2;
                   3163: #endif /* !SHIFTSIGNED_INT32_T */
1.1       root     3164:   }
                   3165: 
                   3166:   /* store the result: */
                   3167:   TME_M68K_INSN_OP1(tme_int32_t) = res;
                   3168: 
                   3169:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   3170:      know the bit we want is within the range of the type, to try
                   3171:      to affect the generated assembly: */
                   3172:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   3173: 
                   3174:   /* generate the Z flag: */
                   3175:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   3176: 
                   3177:   /* store the flags: */
                   3178:   ic->tme_m68k_ireg_ccr = flags;
                   3179:   TME_M68K_INSN_OK;
                   3180: }
                   3181: 
                   3182: /* the lsl function on a 32-byte EA: */
                   3183: TME_M68K_INSN(tme_m68k_lsl32)
                   3184: {
                   3185:   unsigned int count;
                   3186:   tme_uint32_t res;
                   3187:   tme_uint8_t flags;
                   3188: 
                   3189:   /* get the count and operand: */
                   3190:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   3191:   res = TME_M68K_INSN_OP1(tme_uint32_t);
                   3192: 
                   3193:   /* generate the X, V, and C flags assuming the count is zero: */
                   3194:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   3195: 
                   3196:   /* if the count is nonzero, update the result and
                   3197:      generate the X, V, and C flags: */
                   3198:   if (count > 0) {
                   3199:     if (63 > SHIFTMAX_INT32_T
                   3200:         && count > 32) {
                   3201:       res = 0;
                   3202:     }
                   3203:     res <<= (count - 1);
                   3204:     flags = (res >> (32 - 1));
                   3205:     flags *= TME_M68K_FLAG_C;
                   3206:     flags |= (flags * TME_M68K_FLAG_X);
                   3207:     res <<= 1;
                   3208:   }
                   3209: 
                   3210:   /* store the result: */
                   3211:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
                   3212: 
                   3213:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   3214:      know the bit we want is within the range of the type, to try
                   3215:      to affect the generated assembly: */
                   3216:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   3217: 
                   3218:   /* generate the Z flag: */
                   3219:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   3220: 
                   3221:   /* store the flags: */
                   3222:   ic->tme_m68k_ireg_ccr = flags;
                   3223:   TME_M68K_INSN_OK;
                   3224: }
                   3225: 
                   3226: /* the lsr function on a 32-byte EA: */
                   3227: TME_M68K_INSN(tme_m68k_lsr32)
                   3228: {
                   3229:   unsigned int count;
                   3230:   tme_uint32_t res;
                   3231:   tme_uint8_t flags;
                   3232: 
                   3233:   /* get the count and operand: */
                   3234:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   3235:   res = TME_M68K_INSN_OP1(tme_uint32_t);
                   3236: 
                   3237:   /* generate the X, V, and C flags assuming the count is zero: */
                   3238:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   3239: 
                   3240:   /* if the count is nonzero, update the result and
                   3241:      generate the X, V, and C flags: */
                   3242:   if (count > 0) {
                   3243:     if (63 > SHIFTMAX_INT32_T
                   3244:         && count > 32) {
                   3245:       res = 0;
                   3246:     }
                   3247:     res >>= (count - 1);
                   3248:     flags = (res & 1);
                   3249:     flags *= TME_M68K_FLAG_C;
                   3250:     flags |= (flags * TME_M68K_FLAG_X);
                   3251:     res >>= 1;
                   3252:   }
                   3253: 
                   3254:   /* store the result: */
                   3255:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
                   3256: 
                   3257:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   3258:      know the bit we want is within the range of the type, to try
                   3259:      to affect the generated assembly: */
                   3260:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   3261: 
                   3262:   /* generate the Z flag: */
                   3263:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   3264: 
                   3265:   /* store the flags: */
                   3266:   ic->tme_m68k_ireg_ccr = flags;
                   3267:   TME_M68K_INSN_OK;
                   3268: }
                   3269: 
                   3270: /* the rol function on a 32-byte EA: */
                   3271: TME_M68K_INSN(tme_m68k_rol32)
                   3272: {
                   3273:   unsigned int count;
                   3274:   tme_uint32_t res;
                   3275:   tme_uint8_t flags;
                   3276: 
                   3277:   /* get the count and operand: */
                   3278:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   3279:   res = TME_M68K_INSN_OP1(tme_uint32_t);
                   3280: 
                   3281:   /* generate the X, V, and C flags assuming the count is zero: */
                   3282:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   3283: 
                   3284:   /* if the count is nonzero, update the result and
                   3285:      generate the X, V, and C flags: */
                   3286:   if (count > 0) {
                   3287:     count &= (32 - 1);
                   3288:     res = (res << count) | (res >> (32 - count));
                   3289:     flags |= ((res & 1) * TME_M68K_FLAG_C);
                   3290:   }
                   3291: 
                   3292:   /* store the result: */
                   3293:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
                   3294: 
                   3295:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   3296:      know the bit we want is within the range of the type, to try
                   3297:      to affect the generated assembly: */
                   3298:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   3299: 
                   3300:   /* generate the Z flag: */
                   3301:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   3302: 
                   3303:   /* store the flags: */
                   3304:   ic->tme_m68k_ireg_ccr = flags;
                   3305:   TME_M68K_INSN_OK;
                   3306: }
                   3307: 
                   3308: /* the ror function on a 32-byte EA: */
                   3309: TME_M68K_INSN(tme_m68k_ror32)
                   3310: {
                   3311:   unsigned int count;
                   3312:   tme_uint32_t res;
                   3313:   tme_uint8_t flags;
                   3314: 
                   3315:   /* get the count and operand: */
                   3316:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   3317:   res = TME_M68K_INSN_OP1(tme_uint32_t);
                   3318: 
                   3319:   /* generate the X, V, and C flags assuming the count is zero: */
                   3320:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   3321: 
                   3322:   /* if the count is nonzero, update the result and
                   3323:      generate the X, V, and C flags: */
                   3324:   if (count > 0) {
                   3325:     count &= (32 - 1);
                   3326:     res = (res << (32 - count)) | (res >> count);
                   3327:     flags |= ((res >> (32 - 1)) * TME_M68K_FLAG_C);
                   3328:   }
                   3329: 
                   3330:   /* store the result: */
                   3331:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
                   3332: 
                   3333:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   3334:      know the bit we want is within the range of the type, to try
                   3335:      to affect the generated assembly: */
                   3336:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   3337: 
                   3338:   /* generate the Z flag: */
                   3339:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   3340: 
                   3341:   /* store the flags: */
                   3342:   ic->tme_m68k_ireg_ccr = flags;
                   3343:   TME_M68K_INSN_OK;
                   3344: }
                   3345: 
                   3346: /* the roxl function on a 32-byte EA: */
                   3347: TME_M68K_INSN(tme_m68k_roxl32)
                   3348: {
                   3349:   unsigned int count;
                   3350:   tme_uint8_t xbit;
                   3351:   tme_uint32_t res;
                   3352:   tme_uint8_t flags;
                   3353: 
                   3354:   /* get the count and operand: */
                   3355:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   3356:   res = TME_M68K_INSN_OP1(tme_uint32_t);
                   3357: 
                   3358:   /* generate the X, V, and C flags assuming the count is zero: */
                   3359:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   3360:   xbit = (flags / TME_M68K_FLAG_X);
                   3361:   flags |= (xbit * TME_M68K_FLAG_C);
                   3362: 
                   3363:   /* if the count is nonzero, update the result and
                   3364:      generate the X, V, and C flags: */
                   3365:   if (count > 0) {
                   3366:     count %= (32 + 1);
                   3367:     flags = xbit;
                   3368:     if (count > 0) {
                   3369:       flags = (res >> (32 - count)) & 1;
                   3370:       if (32 > SHIFTMAX_INT32_T
                   3371:           && count == 32) {
                   3372:         res = 0 | (xbit << (32 - 1)) | (res >> ((32 + 1) - 32));
                   3373:       }
                   3374:       else if (32 > SHIFTMAX_INT32_T
                   3375:                && count == 1) {
                   3376:         res = (res << 1) | (xbit << (1 - 1)) | 0;
                   3377:       }
                   3378:       else {
                   3379:         res = (res << count) | (xbit << (count - 1)) | (res >> ((32 + 1) - count));
                   3380:       }
                   3381:     }
                   3382:     flags *= TME_M68K_FLAG_C;
                   3383:     flags |= (flags * TME_M68K_FLAG_X);
                   3384:   }
                   3385: 
                   3386:   /* store the result: */
                   3387:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
                   3388: 
                   3389:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   3390:      know the bit we want is within the range of the type, to try
                   3391:      to affect the generated assembly: */
                   3392:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   3393: 
                   3394:   /* generate the Z flag: */
                   3395:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   3396: 
                   3397:   /* store the flags: */
                   3398:   ic->tme_m68k_ireg_ccr = flags;
                   3399:   TME_M68K_INSN_OK;
                   3400: }
                   3401: 
                   3402: /* the roxr function on a 32-byte EA: */
                   3403: TME_M68K_INSN(tme_m68k_roxr32)
                   3404: {
                   3405:   unsigned int count;
                   3406:   tme_uint8_t xbit;
                   3407:   tme_uint32_t res;
                   3408:   tme_uint8_t flags;
                   3409: 
                   3410:   /* get the count and operand: */
                   3411:   count = TME_M68K_INSN_OP0(tme_uint8_t) & 63;
                   3412:   res = TME_M68K_INSN_OP1(tme_uint32_t);
                   3413: 
                   3414:   /* generate the X, V, and C flags assuming the count is zero: */
                   3415:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   3416:   xbit = (flags / TME_M68K_FLAG_X);
                   3417:   flags |= (xbit * TME_M68K_FLAG_C);
                   3418: 
                   3419:   /* if the count is nonzero, update the result and
                   3420:      generate the X, V, and C flags: */
                   3421:   if (count > 0) {
                   3422:     count %= (32 + 1);
                   3423:     flags = xbit;
                   3424:     if (count > 0) {
                   3425:       flags = (res >> (count - 1)) & 1;
                   3426:       if (32 > SHIFTMAX_INT32_T
                   3427:           && count == 32) {
                   3428:         res = (res << ((32 + 1) - 32)) | (xbit << (32 - 32)) | 0;
                   3429:       }
                   3430:       else if (32 > SHIFTMAX_INT32_T
                   3431:                && count == 1) {
                   3432:         res = 0 | (xbit << (32 - 1)) | (res >> 1);
                   3433:       }
                   3434:       else {
                   3435:         res = (res << ((32 + 1) - count)) | (xbit << (32 - count)) | (res >> count);
                   3436:       }
                   3437:     }
                   3438:     flags *= TME_M68K_FLAG_C;
                   3439:     flags |= (flags * TME_M68K_FLAG_X);
                   3440:   }
                   3441: 
                   3442:   /* store the result: */
                   3443:   TME_M68K_INSN_OP1(tme_uint32_t) = res;
                   3444: 
                   3445:   /* generate the N flag.  we cast to tme_uint8_t as soon as we
                   3446:      know the bit we want is within the range of the type, to try
                   3447:      to affect the generated assembly: */
                   3448:   flags |= ((tme_uint8_t) (((tme_uint32_t) res) >> (32 - 1))) * TME_M68K_FLAG_N;
                   3449: 
                   3450:   /* generate the Z flag: */
                   3451:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   3452: 
                   3453:   /* store the flags: */
                   3454:   ic->tme_m68k_ireg_ccr = flags;
                   3455:   TME_M68K_INSN_OK;
                   3456: }
                   3457: 
                   3458: /* the movep_rm function on a 32-bit dreg: */
                   3459: TME_M68K_INSN(tme_m68k_movep_rm32)
                   3460: {
                   3461:   unsigned int function_code;
                   3462:   tme_uint32_t linear_address;
                   3463:   tme_uint32_t value;
                   3464:   int dreg;
                   3465: 
                   3466:   TME_M68K_INSN_CANFAULT;
                   3467: 
                   3468:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   3469:   linear_address = TME_M68K_INSN_OP1(tme_uint32_t);
                   3470:   linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP);
                   3471:   dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   3472:   value = ic->tme_m68k_ireg_uint32(dreg);
                   3473:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3474:     ic->_tme_m68k_ea_function_code = function_code;
                   3475:     ic->_tme_m68k_ea_address = linear_address;
                   3476:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 24, 8);
                   3477:   }
                   3478:   tme_m68k_write_memx8(ic);
                   3479:   linear_address += 2;
                   3480:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3481:     ic->_tme_m68k_ea_function_code = function_code;
                   3482:     ic->_tme_m68k_ea_address = linear_address;
                   3483:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 16, 8);
                   3484:   }
                   3485:   tme_m68k_write_memx8(ic);
                   3486:   linear_address += 2;
                   3487:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3488:     ic->_tme_m68k_ea_function_code = function_code;
                   3489:     ic->_tme_m68k_ea_address = linear_address;
                   3490:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 8, 8);
                   3491:   }
                   3492:   tme_m68k_write_memx8(ic);
                   3493:   linear_address += 2;
                   3494:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3495:     ic->_tme_m68k_ea_function_code = function_code;
                   3496:     ic->_tme_m68k_ea_address = linear_address;
                   3497:     ic->tme_m68k_ireg_memx8 = TME_FIELD_EXTRACTU(value, 0, 8);
                   3498:   }
                   3499:   tme_m68k_write_memx8(ic);
                   3500:   linear_address += 2;
                   3501:   TME_M68K_INSN_OK;
                   3502: }
                   3503: 
                   3504: /* the movem_rm function on 32-bit registers: */
                   3505: TME_M68K_INSN(tme_m68k_movem_rm32)
                   3506: {
                   3507:   int ireg, direction;
                   3508:   tme_uint16_t mask, bit;
                   3509:   unsigned int ea_mode;
                   3510:   tme_uint32_t addend;
1.1.1.4   root     3511:   tme_uint32_t total_size;
                   3512:   /* get the register mask, and figure out the total size
                   3513:      of the transfer: */
                   3514:   mask = TME_M68K_INSN_SPECOP;
                   3515:   total_size = 0;
                   3516:   if (mask != 0) {
                   3517:     TME_M68K_INSN_CANFAULT;
                   3518:     bit = mask;
                   3519:     do {
                   3520:       total_size += sizeof(tme_uint32_t);
                   3521:       bit &= (bit - 1);
                   3522:     } while (bit != 0);
                   3523:   }
1.1       root     3524: 
                   3525:   /* figure out what direction to move in, and where to start from: */
                   3526:   ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3);
                   3527:   direction = 1;
                   3528:   ireg = TME_M68K_IREG_D0;
                   3529:   if (ea_mode == 4) {
                   3530:     direction = -1;
                   3531:     ireg = TME_M68K_IREG_A7;
                   3532:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     3533: 
                   3534:       /* "For the MC68020, MC68030, MC68040, and CPU32, if
                   3535:          the addressing register is also moved to memory, the
                   3536:          value written is the initial register value decremented 
                   3537:          by the size of the operation. The MC68000 and MC68010 
                   3538:          write the initial register value (not decremented)." */
                   3539:       if (ic->tme_m68k_type >= TME_M68K_M68020) {
                   3540:         ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
                   3541:                                  + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
                   3542:           = (ic->_tme_m68k_ea_address - total_size);
                   3543:       }
                   3544: 
                   3545:       /* predecrement the effective address for the first transfer: */
1.1       root     3546:       ic->_tme_m68k_ea_address -= sizeof(tme_uint32_t);
                   3547:     }
                   3548:   }
                   3549:   addend = (tme_uint32_t) (direction * sizeof(tme_uint32_t));
                   3550: 
                   3551:   /* do the transfer: */
                   3552:   for (bit = 1; bit != 0; bit <<= 1) {
                   3553:     if (mask & bit) {
                   3554:       if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3555:         ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg);
                   3556:       }
                   3557:       tme_m68k_write_memx32(ic);
                   3558:       if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3559:         ic->_tme_m68k_ea_address += addend;
                   3560:       }
                   3561:     }
                   3562:     ireg += direction;
                   3563:   }
                   3564: 
                   3565:   /* if this is the predecrement mode, update the address register: */
1.1.1.4   root     3566:   /* "For the MC68020, MC68030, MC68040, and CPU32, if
                   3567:      the addressing register is also moved to memory, the
                   3568:      value written is the initial register value decremented 
                   3569:      by the size of the operation. The MC68000 and MC68010 
                   3570:      write the initial register value (not decremented)." */
                   3571:   if (ea_mode == 4
                   3572:       && ic->tme_m68k_type < TME_M68K_M68020) {
1.1       root     3573:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
                   3574:                               + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
                   3575:       = (ic->_tme_m68k_ea_address + sizeof(tme_uint32_t));
                   3576:   }
                   3577:   TME_M68K_INSN_OK;
                   3578: }
                   3579: 
                   3580: /* the movep_mr function on a 32-bit dreg: */
                   3581: TME_M68K_INSN(tme_m68k_movep_mr32)
                   3582: {
                   3583:   unsigned int function_code;
                   3584:   tme_uint32_t linear_address;
                   3585:   int dreg;
                   3586: 
                   3587:   TME_M68K_INSN_CANFAULT;
                   3588: 
                   3589:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   3590:   linear_address = TME_M68K_INSN_OP1(tme_uint32_t);
                   3591:   linear_address += (tme_int32_t) ((tme_int16_t) TME_M68K_INSN_SPECOP);
                   3592:   dreg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   3593:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3594:     ic->_tme_m68k_ea_function_code = function_code;
                   3595:     ic->_tme_m68k_ea_address = linear_address;
                   3596:   }
                   3597:   tme_m68k_read_memx8(ic);
                   3598:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3599:     TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 24, 8, ic->tme_m68k_ireg_memx8);
                   3600:   }
                   3601:   linear_address += 2;
                   3602:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3603:     ic->_tme_m68k_ea_function_code = function_code;
                   3604:     ic->_tme_m68k_ea_address = linear_address;
                   3605:   }
                   3606:   tme_m68k_read_memx8(ic);
                   3607:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3608:     TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 16, 8, ic->tme_m68k_ireg_memx8);
                   3609:   }
                   3610:   linear_address += 2;
                   3611:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3612:     ic->_tme_m68k_ea_function_code = function_code;
                   3613:     ic->_tme_m68k_ea_address = linear_address;
                   3614:   }
                   3615:   tme_m68k_read_memx8(ic);
                   3616:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3617:     TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 8, 8, ic->tme_m68k_ireg_memx8);
                   3618:   }
                   3619:   linear_address += 2;
                   3620:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3621:     ic->_tme_m68k_ea_function_code = function_code;
                   3622:     ic->_tme_m68k_ea_address = linear_address;
                   3623:   }
                   3624:   tme_m68k_read_memx8(ic);
                   3625:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3626:     TME_FIELD_DEPOSIT32(ic->tme_m68k_ireg_uint32(dreg), 0, 8, ic->tme_m68k_ireg_memx8);
                   3627:   }
                   3628:   linear_address += 2;
                   3629:   TME_M68K_INSN_OK;
                   3630: }
                   3631: 
                   3632: /* the movem_mr function on 32-bit registers: */
                   3633: TME_M68K_INSN(tme_m68k_movem_mr32)
                   3634: {
                   3635:   int ireg, direction;
                   3636:   tme_uint16_t mask, bit;
                   3637:   unsigned int ea_mode;
                   3638:   tme_uint32_t addend;
1.1.1.4   root     3639:   tme_uint32_t total_size;
                   3640:   /* get the register mask, and figure out the total size
                   3641:      of the transfer: */
                   3642:   mask = TME_M68K_INSN_SPECOP;
                   3643:   total_size = 0;
                   3644:   if (mask != 0) {
                   3645:     TME_M68K_INSN_CANFAULT;
                   3646:     bit = mask;
                   3647:     do {
                   3648:       total_size += sizeof(tme_uint32_t);
                   3649:       bit &= (bit - 1);
                   3650:     } while (bit != 0);
                   3651:   }
1.1       root     3652: 
                   3653:   /* figure out what direction to move in, and where to start from: */
                   3654:   ea_mode = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3);
                   3655:   direction = 1;
                   3656:   ireg = TME_M68K_IREG_D0;
                   3657:   addend = (tme_uint32_t) (direction * sizeof(tme_uint32_t));
                   3658: 
                   3659:   /* do the transfer: */
                   3660:   for (bit = 1; bit != 0; bit <<= 1) {
                   3661:     if (mask & bit) {
                   3662:       tme_m68k_read_memx32(ic);
                   3663:       if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3664:         ic->tme_m68k_ireg_uint32(ireg) = ic->tme_m68k_ireg_memx32;
                   3665:         ic->_tme_m68k_ea_address += addend;
                   3666:       }
                   3667:     }
                   3668:     ireg += direction;
                   3669:   }
                   3670: 
                   3671:   /* if this is the postincrement mode, update the address register: */
                   3672:   if (ea_mode == 3) {
                   3673:     ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0
                   3674:                               + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3))
                   3675:       = ic->_tme_m68k_ea_address;
                   3676:   }
                   3677:   TME_M68K_INSN_OK;
                   3678: }
                   3679: 
                   3680: /* chk32: */
                   3681: TME_M68K_INSN(tme_m68k_chk32)
                   3682: {
                   3683:   if (*((tme_int32_t *) _op0) < 0) {
                   3684:     ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_N;
1.1.1.3   root     3685:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root     3686:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3   root     3687:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK));
1.1       root     3688:   }
                   3689:   if (*((tme_int32_t *) _op0) > *((tme_int32_t *) _op1)) {
                   3690:     ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_N;
1.1.1.3   root     3691:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root     3692:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3   root     3693:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK));
1.1       root     3694:   }
                   3695:   TME_M68K_INSN_OK;
                   3696: }
                   3697: 
                   3698: /* cas32: */
                   3699: TME_M68K_INSN(tme_m68k_cas32)
                   3700: {
1.1.1.4   root     3701:   struct tme_m68k_rmw rmw;
1.1       root     3702:   struct tme_m68k_tlb *tlb;
                   3703:   int ireg_dc, ireg_du;
1.1.1.4   root     3704:   tme_uint32_t value_dc, value_du, value_mem;
1.1       root     3705: 
                   3706:   /* start the read/modify/write cycle: */
1.1.1.4   root     3707:   rmw.tme_m68k_rmw_addresses[0] = ic->_tme_m68k_ea_address;
                   3708:   rmw.tme_m68k_rmw_address_count = 1;
                   3709:   rmw.tme_m68k_rmw_size = sizeof(tme_uint32_t);
                   3710:   if (tme_m68k_rmw_start(ic,
                   3711:                          &rmw)) {
1.1       root     3712:     TME_M68K_INSN_OK;
                   3713:   }
                   3714: 
1.1.1.4   root     3715:   /* get the compare and update registers: */
                   3716:   ireg_dc = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
                   3717:   ireg_du = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 6, 3);
                   3718: 
                   3719:   /* if we can do the fast compare-and-exchange: */
                   3720:   if (!rmw.tme_m68k_rmw_slow_reads[0]) {
                   3721: 
                   3722:     /* get the compare and update values in big-endian byte order: */
                   3723:     value_dc = ic->tme_m68k_ireg_uint32(ireg_dc);
                   3724:     value_du = ic->tme_m68k_ireg_uint32(ireg_du);
                   3725:     value_dc = tme_htobe_u32(value_dc);
                   3726:     value_du = tme_htobe_u32(value_du);
                   3727: 
                   3728:     /* get this TLB entry: */
                   3729:     tlb = rmw.tme_m68k_rmw_tlbs[0];
                   3730: 
                   3731:     /* this TLB entry must allow fast reading and fast writing
                   3732:        to the same memory: */
                   3733:     assert (tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF
                   3734:             && tlb->tme_m68k_tlb_emulator_off_write == tlb->tme_m68k_tlb_emulator_off_read);
                   3735: 
                   3736:     /* do the compare-and-exchange: */
                   3737:     value_mem =
                   3738:       tme_memory_atomic_cx32(((tme_shared tme_uint32_t *)
                   3739:                                    (tlb->tme_m68k_tlb_emulator_off_read
                   3740:                                     + ic->_tme_m68k_ea_address)),
                   3741:                                   value_dc,
                   3742:                                   value_du,
                   3743:                                   tlb->tme_m68k_tlb_bus_rwlock,
                   3744:                                   sizeof(tme_uint8_t));
                   3745:     ic->tme_m68k_ireg_memx32 = tme_betoh_u32(value_mem);
                   3746:   }
1.1       root     3747: 
1.1.1.4   root     3748:   /* compare the compare operand to the effective address operand: */
1.1       root     3749:   tme_m68k_cmp32(ic, &ic->tme_m68k_ireg_uint32(ireg_dc), &ic->tme_m68k_ireg_memx32);
                   3750: 
1.1.1.4   root     3751:   /* if the comparison succeeded: */
1.1       root     3752:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
1.1.1.4   root     3753: 
                   3754:     /* write the update operand to the effective address operand: */
1.1       root     3755:     ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg_du);
1.1.1.4   root     3756:   }
                   3757: 
                   3758:   /* otherwise, the comparison failed: */
                   3759:   else {
                   3760: 
                   3761:     /* write the effective address operand to the compare operand: */
1.1       root     3762:     ic->tme_m68k_ireg_uint32(ireg_dc) = ic->tme_m68k_ireg_memx32;
                   3763:   }
                   3764: 
                   3765:   /* finish the read/modify/write cycle: */
1.1.1.4   root     3766:   tme_m68k_rmw_finish(ic,
                   3767:                       &rmw,
                   3768:                       (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) != 0);
1.1       root     3769:   TME_M68K_INSN_OK;
                   3770: }
                   3771: 
                   3772: /* cas2_32: */
                   3773: TME_M68K_INSN(tme_m68k_cas2_32)
                   3774: {
1.1.1.4   root     3775:   struct tme_m68k_rmw rmw;
                   3776:   int ireg_dcx, ireg_dux;
                   3777:   int ireg_dcy, ireg_duy;
                   3778:   const tme_uint16_t specopx = TME_M68K_INSN_SPECOP;
                   3779:   const tme_uint16_t specopy = TME_M68K_INSN_OP0(tme_uint16_t);
1.1       root     3780: 
                   3781:   /* start the read/modify/write cycle: */
1.1.1.4   root     3782:   ic->_tme_m68k_ea_function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   3783:   rmw.tme_m68k_rmw_addresses[0] = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
                   3784:                                                            + TME_FIELD_EXTRACTU(specopx, 12, 4));
                   3785:   rmw.tme_m68k_rmw_addresses[1] = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_D0
                   3786:                                                            + TME_FIELD_EXTRACTU(specopy, 12, 4));
                   3787:   rmw.tme_m68k_rmw_address_count = 2;
                   3788:   rmw.tme_m68k_rmw_size = sizeof(tme_uint32_t);
                   3789:   if (tme_m68k_rmw_start(ic,
                   3790:                          &rmw)) {
1.1       root     3791:     TME_M68K_INSN_OK;
                   3792:   }
                   3793: 
1.1.1.4   root     3794:   /* do the comparisons: */
                   3795:   ireg_dcx = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 0, 3);
                   3796:   ireg_dcy = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 0, 3);
                   3797:   tme_m68k_cmp32(ic,
                   3798:                  &ic->tme_m68k_ireg_uint32(ireg_dcx),
                   3799:                  &ic->tme_m68k_ireg_memx32);
1.1       root     3800:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
1.1.1.4   root     3801:     tme_m68k_cmp32(ic,
                   3802:                    &ic->tme_m68k_ireg_uint32(ireg_dcy),
                   3803:                    &ic->tme_m68k_ireg_memy32);
1.1       root     3804:   }
                   3805: 
1.1.1.4   root     3806:   /* if the comparisons succeeded: */
1.1       root     3807:   if (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) {
1.1.1.4   root     3808: 
                   3809:     /* write the update operands to the effective address operands: */
                   3810:     ireg_dux = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopx, 6, 3);
                   3811:     ireg_duy = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(specopy, 6, 3);
                   3812:     ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg_dux);
                   3813:     ic->tme_m68k_ireg_memy32 = ic->tme_m68k_ireg_uint32(ireg_duy);
1.1       root     3814:   }
                   3815: 
1.1.1.4   root     3816:   /* otherwise, the comparisons failed: */
                   3817:   else {
                   3818: 
                   3819:     /* write the effective address operands to the compare operands.
                   3820:        "If Dc1 and Dc2 specify the same data register and the comparison
                   3821:         fails, memory operand 1 is stored in the data register." */
                   3822:     ic->tme_m68k_ireg_uint32(ireg_dcy) = ic->tme_m68k_ireg_memy32;
                   3823:     ic->tme_m68k_ireg_uint32(ireg_dcx) = ic->tme_m68k_ireg_memx32;
                   3824:   }
1.1       root     3825: 
1.1.1.4   root     3826:   /* finish the read/modify/write cycle: */
                   3827:   tme_m68k_rmw_finish(ic,
                   3828:                       &rmw,
                   3829:                       (ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_Z) != 0);
1.1       root     3830:   TME_M68K_INSN_OK;
                   3831: }
                   3832: 
                   3833: /* moves32: */
                   3834: TME_M68K_INSN(tme_m68k_moves32)
                   3835: {
                   3836:   int ireg;
1.1.1.4   root     3837:   tme_uint32_t ireg_value;
1.1.1.3   root     3838:   unsigned int ea_reg;
                   3839:   unsigned int increment;
                   3840:   TME_M68K_INSN_PRIV;
                   3841:   TME_M68K_INSN_CANFAULT;
1.1       root     3842:   ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4);
1.1.1.3   root     3843: 
1.1.1.4   root     3844:   /* in case we're storing the same address register used in a
                   3845:      postincrement or predecrement EA, save the current value
                   3846:      of the register now: */
                   3847:   ireg_value = ic->tme_m68k_ireg_uint32(ireg);
                   3848: 
1.1.1.3   root     3849:   /* we have to handle postincrement and predecrement ourselves: */
                   3850:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3851:     ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   3852:     increment = TME_M68K_SIZE_32;
                   3853:     if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) {
                   3854:       increment = TME_M68K_SIZE_16;
                   3855:     }
                   3856:     switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) {
                   3857:     case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break;
                   3858:     case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break;
                   3859:     default: break;
                   3860:     }
                   3861:   }
                   3862: 
1.1       root     3863:   if (TME_M68K_INSN_SPECOP & TME_BIT(11)) {
1.1.1.3   root     3864:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     3865:       ic->tme_m68k_ireg_memx32 = ireg_value;
1.1.1.3   root     3866:       ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc;
                   3867:     }
                   3868:     tme_m68k_write_memx32(ic);
1.1       root     3869:   }
                   3870:   else {
1.1.1.3   root     3871:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   3872:       ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc;
                   3873:     }
                   3874:     tme_m68k_read_memx32(ic);
1.1       root     3875:     ic->tme_m68k_ireg_uint32(ireg) = ic->tme_m68k_ireg_memx32;
                   3876:   }
                   3877:   TME_M68K_INSN_OK;
                   3878: }
                   3879: 
                   3880: /* this reads a 8-bit memx value: */
                   3881: void
                   3882: tme_m68k_read_memx8(struct tme_m68k *ic) 
                   3883: {
1.1.1.5   root     3884:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     3885:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   3886:   tme_uint32_t linear_address = ic->_tme_m68k_ea_address;
1.1.1.5   root     3887:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address);
1.1.1.4   root     3888:   tme_uint8_t mem_value;
                   3889:   const tme_shared tme_uint8_t *mem;
1.1       root     3890: 
1.1.1.3   root     3891: #ifdef _TME_M68K_STATS
                   3892:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   3893: #endif /* _TME_M68K_STATS */
                   3894: 
1.1.1.4   root     3895:   /* busy this TLB entry: */
                   3896:   tme_m68k_tlb_busy(tlb);
                   3897: 
                   3898:   /* if we aren't restarting, and this address is properly aligned,
                   3899:      and this TLB entry covers the operand and allows fast reads: */
1.1       root     3900:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.5   root     3901:                          && tme_m68k_tlb_is_valid(tlb)
                   3902:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   3903:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   3904:                              & TME_BIT(function_code))
                   3905:                          && linear_address >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   3906:                          && linear_address <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   3907:                          && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     3908: 
1.1.1.4   root     3909:     /* make the emulator memory pointer: */
                   3910:     mem = (const tme_shared tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address);
                   3911: 
                   3912:     /* do the 8-bit bus read: */
                   3913:     mem_value = tme_memory_bus_read8(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   3914: 
                   3915:     /* put the value read: */
                   3916:     ic->tme_m68k_ireg_memx8 = mem_value;
                   3917: 
                   3918:     /* step the transfer count: */
1.1       root     3919:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   3920:   }
                   3921: 
                   3922:   /* otherwise, do the bus cycles the slow way: */
                   3923:   else {
                   3924:     tme_m68k_read8(ic, tlb,
                   3925:                     &ic->_tme_m68k_ea_function_code,
                   3926:                     &ic->_tme_m68k_ea_address,
                   3927:                     &ic->tme_m68k_ireg_memx8,
                   3928:                     TME_M68K_BUS_CYCLE_NORMAL);
                   3929:   }
                   3930: 
1.1.1.4   root     3931:   /* unbusy this TLB entry: */
                   3932:   tme_m68k_tlb_unbusy(tlb);
                   3933: 
1.1       root     3934:   /* log the value read: */
                   3935:   tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx8, TME_BUS_CYCLE_READ);
                   3936:   tme_m68k_log(ic, 1000, TME_OK,
                   3937:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     3938:                 _("read_memx8  %d:0x%08x:      0x%02x"),
1.1       root     3939:                 ic->_tme_m68k_ea_function_code,
                   3940:                 ic->_tme_m68k_ea_address,
                   3941:                 ic->tme_m68k_ireg_memx8));
                   3942: }
                   3943: 
                   3944: /* this reads a 8-bit mem value: */
                   3945: void
                   3946: tme_m68k_read_mem8(struct tme_m68k *ic, int ireg) 
                   3947: {
1.1.1.5   root     3948:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     3949:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   3950:   tme_uint32_t linear_address = ic->_tme_m68k_ea_address;
1.1.1.5   root     3951:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address);
1.1.1.4   root     3952:   tme_uint8_t mem_value;
                   3953:   const tme_shared tme_uint8_t *mem;
1.1       root     3954: 
1.1.1.3   root     3955: #ifdef _TME_M68K_STATS
                   3956:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   3957: #endif /* _TME_M68K_STATS */
                   3958: 
1.1.1.4   root     3959:   /* busy this TLB entry: */
                   3960:   tme_m68k_tlb_busy(tlb);
                   3961: 
                   3962:   /* if we aren't restarting, and this address is properly aligned,
                   3963:      and this TLB entry covers the operand and allows fast reads: */
1.1       root     3964:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.5   root     3965:                          && tme_m68k_tlb_is_valid(tlb)
                   3966:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   3967:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   3968:                              & TME_BIT(function_code))
                   3969:                          && linear_address >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   3970:                          && linear_address <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   3971:                          && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     3972: 
1.1.1.4   root     3973:     /* make the emulator memory pointer: */
                   3974:     mem = (const tme_shared tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address);
                   3975: 
                   3976:     /* do the 8-bit bus read: */
                   3977:     mem_value = tme_memory_bus_read8(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   3978: 
                   3979:     /* put the value read: */
                   3980:     ic->tme_m68k_ireg_uint8(ireg) = mem_value;
                   3981: 
                   3982:     /* step the transfer count: */
1.1       root     3983:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   3984:   }
                   3985: 
                   3986:   /* otherwise, do the bus cycles the slow way: */
                   3987:   else {
                   3988:     tme_m68k_read8(ic, tlb,
                   3989:                     &ic->_tme_m68k_ea_function_code,
                   3990:                     &ic->_tme_m68k_ea_address,
                   3991:                     &ic->tme_m68k_ireg_uint8(ireg),
                   3992:                     TME_M68K_BUS_CYCLE_NORMAL);
                   3993:   }
                   3994: 
1.1.1.4   root     3995:   /* unbusy this TLB entry: */
                   3996:   tme_m68k_tlb_unbusy(tlb);
                   3997: 
1.1       root     3998:   /* log the value read: */
                   3999:   tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint8(ireg), TME_BUS_CYCLE_READ);
                   4000:   tme_m68k_log(ic, 1000, TME_OK,
                   4001:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4002:                 _("read_mem8   %d:0x%08x:      0x%02x"),
1.1       root     4003:                 ic->_tme_m68k_ea_function_code,
                   4004:                 ic->_tme_m68k_ea_address,
                   4005:                 ic->tme_m68k_ireg_uint8(ireg)));
                   4006: }
                   4007: 
                   4008: /* this writes a 8-bit memx value: */
                   4009: void
                   4010: tme_m68k_write_memx8(struct tme_m68k *ic) 
                   4011: {
1.1.1.5   root     4012:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4013:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   4014:   tme_uint32_t linear_address = ic->_tme_m68k_ea_address;
1.1.1.5   root     4015:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address);
1.1.1.4   root     4016:   tme_uint8_t mem_value;
                   4017:   tme_shared tme_uint8_t *mem;
1.1       root     4018: 
1.1.1.3   root     4019: #ifdef _TME_M68K_STATS
                   4020:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4021: #endif /* _TME_M68K_STATS */
                   4022: 
1.1       root     4023:   /* log the value written: */
                   4024:   tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx8, TME_BUS_CYCLE_WRITE);
                   4025:   tme_m68k_log(ic, 1000, TME_OK, 
                   4026:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4027:                 _("write_memx8 %d:0x%08x:      0x%02x"),
1.1       root     4028:                 ic->_tme_m68k_ea_function_code,
                   4029:                 ic->_tme_m68k_ea_address,
                   4030:                 ic->tme_m68k_ireg_memx8));
                   4031: 
1.1.1.4   root     4032:   /* busy this TLB entry: */
                   4033:   tme_m68k_tlb_busy(tlb);
                   4034: 
                   4035:   /* if we aren't restarting, and this address is properly aligned,
                   4036:      and this TLB entry covers the operand and allows fast writes: */
1.1       root     4037:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.5   root     4038:                          && tme_m68k_tlb_is_valid(tlb)
                   4039:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4040:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4041:                              & TME_BIT(function_code))
                   4042:                          && linear_address >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4043:                          && linear_address <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4044:                          && tlb->tme_m68k_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4045: 
1.1.1.4   root     4046:     /* make the emulator memory pointer: */
                   4047:     mem = (tme_shared tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address);
                   4048: 
                   4049:     /* get the value to write: */
                   4050:     mem_value = ic->tme_m68k_ireg_memx8;
                   4051: 
                   4052:     /* do the 8-bit bus write: */
                   4053:     tme_memory_bus_write8(mem, mem_value, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4054: 
                   4055:     /* step the transfer count: */
1.1       root     4056:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4057:   }
                   4058: 
                   4059:   /* otherwise, do the bus cycles the slow way: */
                   4060:   else {
                   4061:     tme_m68k_write8(ic, tlb,
                   4062:                     &ic->_tme_m68k_ea_function_code,
                   4063:                     &ic->_tme_m68k_ea_address,
                   4064:                     &ic->tme_m68k_ireg_memx8,
                   4065:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4066:   }
1.1.1.4   root     4067: 
                   4068:   /* unbusy this TLB entry: */
                   4069:   tme_m68k_tlb_unbusy(tlb);
1.1       root     4070: }
                   4071: 
                   4072: /* this writes a 8-bit mem value: */
                   4073: void
                   4074: tme_m68k_write_mem8(struct tme_m68k *ic, int ireg) 
                   4075: {
1.1.1.5   root     4076:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4077:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   4078:   tme_uint32_t linear_address = ic->_tme_m68k_ea_address;
1.1.1.5   root     4079:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address);
1.1.1.4   root     4080:   tme_uint8_t mem_value;
                   4081:   tme_shared tme_uint8_t *mem;
1.1       root     4082: 
1.1.1.3   root     4083: #ifdef _TME_M68K_STATS
                   4084:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4085: #endif /* _TME_M68K_STATS */
                   4086: 
1.1       root     4087:   /* log the value written: */
                   4088:   tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint8(ireg), TME_BUS_CYCLE_WRITE);
                   4089:   tme_m68k_log(ic, 1000, TME_OK, 
                   4090:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4091:                 _("write_mem8  %d:0x%08x:      0x%02x"),
1.1       root     4092:                 ic->_tme_m68k_ea_function_code,
                   4093:                 ic->_tme_m68k_ea_address,
                   4094:                 ic->tme_m68k_ireg_uint8(ireg)));
                   4095: 
1.1.1.4   root     4096:   /* busy this TLB entry: */
                   4097:   tme_m68k_tlb_busy(tlb);
                   4098: 
                   4099:   /* if we aren't restarting, and this address is properly aligned,
                   4100:      and this TLB entry covers the operand and allows fast writes: */
1.1       root     4101:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.5   root     4102:                          && tme_m68k_tlb_is_valid(tlb)
                   4103:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4104:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4105:                              & TME_BIT(function_code))
                   4106:                          && linear_address >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4107:                          && linear_address <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4108:                          && tlb->tme_m68k_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4109: 
1.1.1.4   root     4110:     /* make the emulator memory pointer: */
                   4111:     mem = (tme_shared tme_uint8_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address);
                   4112: 
                   4113:     /* get the value to write: */
                   4114:     mem_value = ic->tme_m68k_ireg_uint8(ireg);
                   4115: 
                   4116:     /* do the 8-bit bus write: */
                   4117:     tme_memory_bus_write8(mem, mem_value, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4118: 
                   4119:     /* step the transfer count: */
1.1       root     4120:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4121:   }
                   4122: 
                   4123:   /* otherwise, do the bus cycles the slow way: */
                   4124:   else {
                   4125:     tme_m68k_write8(ic, tlb,
                   4126:                     &ic->_tme_m68k_ea_function_code,
                   4127:                     &ic->_tme_m68k_ea_address,
                   4128:                     &ic->tme_m68k_ireg_uint8(ireg),
                   4129:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4130:   }
1.1.1.4   root     4131: 
                   4132:   /* unbusy this TLB entry: */
                   4133:   tme_m68k_tlb_unbusy(tlb);
1.1       root     4134: }
                   4135: 
                   4136: /* this reads a 16-bit memx value: */
                   4137: void
                   4138: tme_m68k_read_memx16(struct tme_m68k *ic) 
                   4139: {
1.1.1.5   root     4140:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4141:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   4142:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
                   4143:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
1.1.1.5   root     4144:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4145:   tme_uint16_t mem_value;
                   4146:   const tme_shared tme_uint16_t *mem;
1.1       root     4147: 
1.1.1.3   root     4148: #ifdef _TME_M68K_STATS
                   4149:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4150: #endif /* _TME_M68K_STATS */
                   4151: 
1.1.1.4   root     4152:   /* busy this TLB entry: */
                   4153:   tme_m68k_tlb_busy(tlb);
                   4154: 
                   4155:   /* if we aren't restarting, and this address is properly aligned,
                   4156:      and this TLB entry covers the operand and allows fast reads: */
1.1       root     4157:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4158:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4159:                          && tme_m68k_tlb_is_valid(tlb)
                   4160:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4161:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4162:                              & TME_BIT(function_code))
                   4163:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4164:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4165:                          && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4166: 
1.1.1.4   root     4167:     /* make the emulator memory pointer: */
                   4168:     mem = (const tme_shared tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first);
                   4169: 
                   4170:     /* do the 16-bit bus read: */
                   4171:     mem_value = tme_memory_bus_read16(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4172: 
                   4173:     /* put the value read, in host byte order: */
                   4174:     ic->tme_m68k_ireg_memx16 = tme_betoh_u16(mem_value);
                   4175: 
                   4176:     /* step the transfer count: */
1.1       root     4177:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4178:   }
                   4179: 
                   4180:   /* otherwise, do the bus cycles the slow way: */
                   4181:   else {
                   4182:     tme_m68k_read16(ic, tlb,
                   4183:                     &ic->_tme_m68k_ea_function_code,
                   4184:                     &ic->_tme_m68k_ea_address,
                   4185:                     &ic->tme_m68k_ireg_memx16,
                   4186:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4187:   }
                   4188: 
1.1.1.4   root     4189:   /* unbusy this TLB entry: */
                   4190:   tme_m68k_tlb_unbusy(tlb);
                   4191: 
1.1       root     4192:   /* log the value read: */
                   4193:   tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx16, TME_BUS_CYCLE_READ);
                   4194:   tme_m68k_log(ic, 1000, TME_OK,
                   4195:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4196:                 _("read_memx16 %d:0x%08x:      0x%04x"),
1.1       root     4197:                 ic->_tme_m68k_ea_function_code,
                   4198:                 ic->_tme_m68k_ea_address,
                   4199:                 ic->tme_m68k_ireg_memx16));
                   4200: }
                   4201: 
                   4202: /* this reads a 16-bit mem value: */
                   4203: void
                   4204: tme_m68k_read_mem16(struct tme_m68k *ic, int ireg) 
                   4205: {
1.1.1.5   root     4206:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4207:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   4208:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
                   4209:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
1.1.1.5   root     4210:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4211:   tme_uint16_t mem_value;
                   4212:   const tme_shared tme_uint16_t *mem;
1.1       root     4213: 
1.1.1.3   root     4214: #ifdef _TME_M68K_STATS
                   4215:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4216: #endif /* _TME_M68K_STATS */
                   4217: 
1.1.1.4   root     4218:   /* busy this TLB entry: */
                   4219:   tme_m68k_tlb_busy(tlb);
                   4220: 
                   4221:   /* if we aren't restarting, and this address is properly aligned,
                   4222:      and this TLB entry covers the operand and allows fast reads: */
1.1       root     4223:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4224:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4225:                          && tme_m68k_tlb_is_valid(tlb)
                   4226:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4227:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4228:                              & TME_BIT(function_code))
                   4229:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4230:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4231:                          && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4232: 
1.1.1.4   root     4233:     /* make the emulator memory pointer: */
                   4234:     mem = (const tme_shared tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first);
                   4235: 
                   4236:     /* do the 16-bit bus read: */
                   4237:     mem_value = tme_memory_bus_read16(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4238: 
                   4239:     /* put the value read, in host byte order: */
                   4240:     ic->tme_m68k_ireg_uint16(ireg) = tme_betoh_u16(mem_value);
                   4241: 
                   4242:     /* step the transfer count: */
1.1       root     4243:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4244:   }
                   4245: 
                   4246:   /* otherwise, do the bus cycles the slow way: */
                   4247:   else {
                   4248:     tme_m68k_read16(ic, tlb,
                   4249:                     &ic->_tme_m68k_ea_function_code,
                   4250:                     &ic->_tme_m68k_ea_address,
                   4251:                     &ic->tme_m68k_ireg_uint16(ireg),
                   4252:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4253:   }
                   4254: 
1.1.1.4   root     4255:   /* unbusy this TLB entry: */
                   4256:   tme_m68k_tlb_unbusy(tlb);
                   4257: 
1.1       root     4258:   /* log the value read: */
                   4259:   tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint16(ireg), TME_BUS_CYCLE_READ);
                   4260:   tme_m68k_log(ic, 1000, TME_OK,
                   4261:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4262:                 _("read_mem16  %d:0x%08x:      0x%04x"),
1.1       root     4263:                 ic->_tme_m68k_ea_function_code,
                   4264:                 ic->_tme_m68k_ea_address,
                   4265:                 ic->tme_m68k_ireg_uint16(ireg)));
                   4266: }
                   4267: 
                   4268: /* this reads a 16-bit inst value: */
                   4269: tme_uint16_t
                   4270: tme_m68k_fetch16(struct tme_m68k *ic, tme_uint32_t pc) 
                   4271: {
1.1.1.5   root     4272:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4273:   unsigned int function_code = TME_M68K_FUNCTION_CODE_PROGRAM(ic);
                   4274:   tme_uint32_t linear_address_first = pc;
                   4275:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
1.1.1.5   root     4276:   struct tme_m68k_tlb *tlb = &ic->_tme_m68k_itlb;
1.1.1.4   root     4277:   tme_uint16_t mem_value;
                   4278:   const tme_shared tme_uint16_t *mem;
                   4279:   unsigned int fetch_slow_next = ic->_tme_m68k_insn_fetch_slow_next;
1.1       root     4280: 
1.1.1.3   root     4281: #ifdef _TME_M68K_STATS
                   4282:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4283: #endif /* _TME_M68K_STATS */
                   4284: 
1.1.1.4   root     4285:   /* busy this TLB entry: */
                   4286:   tme_m68k_tlb_busy(tlb);
1.1       root     4287: 
1.1.1.4   root     4288:   /* if this fetch was done by the fast executor: */
                   4289:   if (__tme_predict_true(fetch_slow_next < ic->_tme_m68k_insn_fetch_slow_count_fast)) {
1.1       root     4290: 
1.1.1.4   root     4291:     /* the entire fetch must be in the instruction buffer, and
                   4292:        we must be restarting: */
                   4293:     assert ((fetch_slow_next + sizeof(tme_uint16_t))
                   4294:             <= ic->_tme_m68k_insn_fetch_slow_count_fast);
                   4295:     assert (TME_M68K_SEQUENCE_RESTARTING);
                   4296:     mem_value = tme_memory_read16(((tme_uint16_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)), sizeof(tme_uint16_t));
                   4297:   }
                   4298: 
                   4299:   /* otherwise, this fetch was not done by the fast executor: */
                   4300:   else {
                   4301: 
                   4302:     /* if we're restarting, but the offset in the instruction buffer
                   4303:        to fetch into is at the instruction buffer total, this must be
                   4304:        a fake fault caused by the fast executor.  we confirm this by
                   4305:        checking that this transfer "caused" the fault, and that this
                   4306:        transfer will be the first slow one after any fast fetches.
                   4307:        in this case, we can cancel the restart for now: */
                   4308:     if (TME_M68K_SEQUENCE_RESTARTING
                   4309:         && (fetch_slow_next
                   4310:             == ic->_tme_m68k_insn_fetch_slow_count_total)) {
                   4311:       assert ((ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next
                   4312:                == ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted)
                   4313:               && (fetch_slow_next
                   4314:                   == ic->_tme_m68k_insn_fetch_slow_count_fast));
                   4315:       ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted--;
                   4316:     }
                   4317: 
                   4318:     /* if we're not restarting: */
                   4319:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   4320: 
                   4321:       /* we advance the instruction buffer total *before* we do
                   4322:          what may be a slow fetch, because we may transfer a few
                   4323:          bytes and then fault.  without this, those few bytes
                   4324:          would not get saved in the exception stack frame and
                   4325:          restored later before the continuation of the fetch: */
                   4326:       ic->_tme_m68k_insn_fetch_slow_count_total += sizeof(tme_uint16_t);
                   4327:     }
                   4328: 
                   4329:     /* make sure that if this is a new transfer or if this
                   4330:        transfer faulted, that we're fetching for the current
                   4331:        last positions in the instruction buffer: */
                   4332:     assert ((ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next
                   4333:              < ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted)
                   4334:             || ((fetch_slow_next + sizeof(tme_uint16_t))
                   4335:                 == ic->_tme_m68k_insn_fetch_slow_count_total));
                   4336: 
                   4337:     /* if we aren't restarting, and this address is properly aligned,
                   4338:        and this TLB entry covers the operand and allows fast reads: */
                   4339:     if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
                   4340:                            && ((sizeof(tme_uint16_t) - 1) & linear_address_first) == 0
1.1.1.5   root     4341:                            && tme_m68k_tlb_is_valid(tlb)
                   4342:                            && tlb->tme_m68k_tlb_bus_context == bus_context
                   4343:                            && (tlb->tme_m68k_tlb_function_codes_mask
                   4344:                                & TME_BIT(function_code))
                   4345:                            && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4346:                            && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4347:                            && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1.1.4   root     4348: 
                   4349:       /* make the emulator memory pointer: */
                   4350:       mem = (const tme_shared tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first);
                   4351: 
                   4352:       /* do the 16-bit bus read: */
                   4353:       mem_value = tme_memory_bus_read16(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t));
                   4354: 
                   4355:       /* put the value read, in host byte order: */
                   4356:       mem_value = tme_betoh_u16(mem_value);
                   4357:       tme_memory_write16(((tme_uint16_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)), mem_value, sizeof(tme_uint16_t));
                   4358: 
                   4359:       /* step the transfer count: */
                   4360:       TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4361:     }
                   4362: 
                   4363:     /* otherwise, do the bus cycles the slow way: */
                   4364:     else {
                   4365:       tme_m68k_read16(ic, tlb,
                   4366:                       &function_code,
                   4367:                       &pc,
                   4368:                       ((tme_uint16_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)),
                   4369:                       TME_M68K_BUS_CYCLE_FETCH);
                   4370:       mem_value = tme_memory_read16(((tme_uint16_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)), sizeof(tme_uint16_t));
                   4371:     }
1.1       root     4372:   }
                   4373: 
1.1.1.4   root     4374:   /* unbusy this TLB entry: */
                   4375:   tme_m68k_tlb_unbusy(tlb);
                   4376: 
1.1       root     4377:   /* log the value read: */
1.1.1.4   root     4378:   tme_m68k_verify_mem16(ic, function_code, pc, *((tme_uint16_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)), TME_BUS_CYCLE_READ);
1.1       root     4379:   tme_m68k_log(ic, 1000, TME_OK,
                   4380:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4381:                 _("fetch16     %d:0x%08x:      0x%04x"),
1.1       root     4382:                 function_code,
                   4383:                 pc,
1.1.1.4   root     4384:                 *((tme_uint16_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next))));
                   4385: 
                   4386:   /* advance the offset in the instruction buffer for the next slow fetch: */
                   4387:   fetch_slow_next += sizeof(tme_uint16_t);
                   4388:   ic->_tme_m68k_insn_fetch_slow_next = fetch_slow_next;
                   4389: 
                   4390:   /* return the fetched value: */
                   4391:   return(mem_value);
1.1       root     4392: }
                   4393: 
                   4394: /* this reads a 16-bit stack value: */
                   4395: void
                   4396: tme_m68k_pop16(struct tme_m68k *ic, tme_uint16_t *_value) 
                   4397: {
1.1.1.5   root     4398:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4399:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   4400:   tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7;
                   4401:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
1.1.1.5   root     4402:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4403:   tme_uint16_t mem_value;
                   4404:   const tme_shared tme_uint16_t *mem;
1.1       root     4405: 
1.1.1.3   root     4406: #ifdef _TME_M68K_STATS
                   4407:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4408: #endif /* _TME_M68K_STATS */
                   4409: 
1.1.1.4   root     4410:   /* busy this TLB entry: */
                   4411:   tme_m68k_tlb_busy(tlb);
                   4412: 
                   4413:   /* if we aren't restarting, and this address is properly aligned,
                   4414:      and this TLB entry covers the operand and allows fast reads: */
1.1       root     4415:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4416:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4417:                          && tme_m68k_tlb_is_valid(tlb)
                   4418:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4419:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4420:                              & TME_BIT(function_code))
                   4421:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4422:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4423:                          && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4424: 
1.1.1.4   root     4425:     /* make the emulator memory pointer: */
                   4426:     mem = (const tme_shared tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first);
                   4427: 
                   4428:     /* do the 16-bit bus read: */
                   4429:     mem_value = tme_memory_bus_read16(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4430: 
                   4431:     /* put the value read, in host byte order: */
                   4432:     *_value = tme_betoh_u16(mem_value);
                   4433: 
                   4434:     /* step the transfer count: */
1.1       root     4435:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4436:   }
                   4437: 
                   4438:   /* otherwise, do the bus cycles the slow way: */
                   4439:   else {
                   4440:     tme_m68k_read16(ic, tlb,
                   4441:                     &function_code,
                   4442:                     &ic->tme_m68k_ireg_a7,
                   4443:                     _value,
                   4444:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4445:   }
                   4446: 
1.1.1.4   root     4447:   /* unbusy this TLB entry: */
                   4448:   tme_m68k_tlb_unbusy(tlb);
                   4449: 
1.1       root     4450:   /* log the value read: */
                   4451:   tme_m68k_verify_mem16(ic, function_code, ic->tme_m68k_ireg_a7, *_value, TME_BUS_CYCLE_READ);
                   4452:   tme_m68k_log(ic, 1000, TME_OK,
                   4453:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4454:                 _("pop16       %d:0x%08x:      0x%04x"),
1.1       root     4455:                 function_code,
                   4456:                 ic->tme_m68k_ireg_a7,
                   4457:                 *_value));
                   4458:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   4459:     ic->tme_m68k_ireg_a7 += sizeof(tme_uint16_t);
                   4460:   }
                   4461: }
                   4462: 
                   4463: /* this writes a 16-bit memx value: */
                   4464: void
                   4465: tme_m68k_write_memx16(struct tme_m68k *ic) 
                   4466: {
1.1.1.5   root     4467:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4468:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   4469:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
                   4470:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
1.1.1.5   root     4471:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4472:   tme_uint16_t mem_value;
                   4473:   tme_shared tme_uint16_t *mem;
1.1       root     4474: 
1.1.1.3   root     4475: #ifdef _TME_M68K_STATS
                   4476:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4477: #endif /* _TME_M68K_STATS */
                   4478: 
1.1       root     4479:   /* log the value written: */
                   4480:   tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx16, TME_BUS_CYCLE_WRITE);
                   4481:   tme_m68k_log(ic, 1000, TME_OK, 
                   4482:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4483:                 _("write_memx16        %d:0x%08x:      0x%04x"),
1.1       root     4484:                 ic->_tme_m68k_ea_function_code,
                   4485:                 ic->_tme_m68k_ea_address,
                   4486:                 ic->tme_m68k_ireg_memx16));
                   4487: 
1.1.1.4   root     4488:   /* busy this TLB entry: */
                   4489:   tme_m68k_tlb_busy(tlb);
                   4490: 
                   4491:   /* if we aren't restarting, and this address is properly aligned,
                   4492:      and this TLB entry covers the operand and allows fast writes: */
1.1       root     4493:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4494:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4495:                          && tme_m68k_tlb_is_valid(tlb)
                   4496:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4497:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4498:                              & TME_BIT(function_code))
                   4499:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4500:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4501:                          && tlb->tme_m68k_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4502: 
1.1.1.4   root     4503:     /* make the emulator memory pointer: */
                   4504:     mem = (tme_shared tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first);
                   4505: 
                   4506:     /* get the value to write, in big-endian byte order: */
                   4507:     mem_value = tme_htobe_u16(ic->tme_m68k_ireg_memx16);
                   4508: 
1.1.1.6 ! root     4509: #if 1
        !          4510:     {
        !          4511:            extern int printf(const char *format, ...);
        !          4512:            if ((int)ic->tme_m68k_ireg_pc == 0x3c3bc) {
        !          4513:                    printf("tme_m68k_write_memx16 #1; mem %x, val %x\n", (int)mem, (int)mem_value);
        !          4514:            }
        !          4515:     }
        !          4516: #endif
        !          4517: 
1.1.1.4   root     4518:     /* do the 16-bit bus write: */
                   4519:     tme_memory_bus_write16(mem, mem_value, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4520: 
                   4521:     /* step the transfer count: */
1.1       root     4522:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4523:   }
                   4524: 
                   4525:   /* otherwise, do the bus cycles the slow way: */
                   4526:   else {
1.1.1.6 ! root     4527: #if 1
        !          4528:     {
        !          4529:            extern int printf(const char *format, ...);
        !          4530:            if ((int)ic->tme_m68k_ireg_pc == 0x3c3bc) {
        !          4531:                    mem = (tme_shared tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first);
        !          4532:                    mem_value = tme_htobe_u16(ic->tme_m68k_ireg_memx16);
        !          4533:                    printf("tme_m68k_write_memx16 #2; mem %x, val %x\n", (int)mem, (int)mem_value);
        !          4534:            }
        !          4535:     }
        !          4536: #endif
1.1       root     4537:     tme_m68k_write16(ic, tlb,
                   4538:                     &ic->_tme_m68k_ea_function_code,
                   4539:                     &ic->_tme_m68k_ea_address,
                   4540:                     &ic->tme_m68k_ireg_memx16,
                   4541:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4542:   }
1.1.1.4   root     4543: 
                   4544:   /* unbusy this TLB entry: */
                   4545:   tme_m68k_tlb_unbusy(tlb);
1.1       root     4546: }
                   4547: 
                   4548: /* this writes a 16-bit mem value: */
                   4549: void
                   4550: tme_m68k_write_mem16(struct tme_m68k *ic, int ireg) 
                   4551: {
1.1.1.5   root     4552:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4553:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   4554:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
                   4555:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
1.1.1.5   root     4556:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4557:   tme_uint16_t mem_value;
                   4558:   tme_shared tme_uint16_t *mem;
1.1       root     4559: 
1.1.1.3   root     4560: #ifdef _TME_M68K_STATS
                   4561:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4562: #endif /* _TME_M68K_STATS */
                   4563: 
1.1       root     4564:   /* log the value written: */
                   4565:   tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint16(ireg), TME_BUS_CYCLE_WRITE);
                   4566:   tme_m68k_log(ic, 1000, TME_OK, 
                   4567:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4568:                 _("write_mem16 %d:0x%08x:      0x%04x"),
1.1       root     4569:                 ic->_tme_m68k_ea_function_code,
                   4570:                 ic->_tme_m68k_ea_address,
                   4571:                 ic->tme_m68k_ireg_uint16(ireg)));
                   4572: 
1.1.1.4   root     4573:   /* busy this TLB entry: */
                   4574:   tme_m68k_tlb_busy(tlb);
                   4575: 
                   4576:   /* if we aren't restarting, and this address is properly aligned,
                   4577:      and this TLB entry covers the operand and allows fast writes: */
1.1       root     4578:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4579:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4580:                          && tme_m68k_tlb_is_valid(tlb)
                   4581:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4582:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4583:                              & TME_BIT(function_code))
                   4584:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4585:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4586:                          && tlb->tme_m68k_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4587: 
1.1.1.4   root     4588:     /* make the emulator memory pointer: */
                   4589:     mem = (tme_shared tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first);
                   4590: 
                   4591:     /* get the value to write, in big-endian byte order: */
                   4592:     mem_value = tme_htobe_u16(ic->tme_m68k_ireg_uint16(ireg));
                   4593: 
                   4594:     /* do the 16-bit bus write: */
                   4595:     tme_memory_bus_write16(mem, mem_value, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4596: 
                   4597:     /* step the transfer count: */
1.1       root     4598:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4599:   }
                   4600: 
                   4601:   /* otherwise, do the bus cycles the slow way: */
                   4602:   else {
                   4603:     tme_m68k_write16(ic, tlb,
                   4604:                     &ic->_tme_m68k_ea_function_code,
                   4605:                     &ic->_tme_m68k_ea_address,
                   4606:                     &ic->tme_m68k_ireg_uint16(ireg),
                   4607:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4608:   }
1.1.1.4   root     4609: 
                   4610:   /* unbusy this TLB entry: */
                   4611:   tme_m68k_tlb_unbusy(tlb);
1.1       root     4612: }
                   4613: 
                   4614: /* this writes a 16-bit stack value: */
                   4615: void
                   4616: tme_m68k_push16(struct tme_m68k *ic, tme_uint16_t value) 
                   4617: {
1.1.1.5   root     4618:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4619:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   4620:   tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7 - sizeof(tme_uint16_t);
                   4621:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1;
1.1.1.5   root     4622:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4623:   tme_uint16_t mem_value;
                   4624:   tme_shared tme_uint16_t *mem;
1.1       root     4625: 
1.1.1.3   root     4626: #ifdef _TME_M68K_STATS
                   4627:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4628: #endif /* _TME_M68K_STATS */
                   4629: 
1.1       root     4630:   /* log the value written: */
                   4631:   tme_m68k_verify_mem16(ic, function_code, linear_address_first, value, TME_BUS_CYCLE_WRITE);
                   4632:   tme_m68k_log(ic, 1000, TME_OK, 
                   4633:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4634:                 _("push16      %d:0x%08x:      0x%04x"),
1.1       root     4635:                 function_code,
                   4636:                 linear_address_first,
                   4637:                 value));
                   4638: 
1.1.1.4   root     4639:   /* busy this TLB entry: */
                   4640:   tme_m68k_tlb_busy(tlb);
                   4641: 
                   4642:   /* if we aren't restarting, and this address is properly aligned,
                   4643:      and this TLB entry covers the operand and allows fast writes: */
1.1       root     4644:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4645:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4646:                          && tme_m68k_tlb_is_valid(tlb)
                   4647:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4648:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4649:                              & TME_BIT(function_code))
                   4650:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4651:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4652:                          && tlb->tme_m68k_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4653: 
1.1.1.4   root     4654:     /* make the emulator memory pointer: */
                   4655:     mem = (tme_shared tme_uint16_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first);
                   4656: 
                   4657:     /* get the value to write, in big-endian byte order: */
                   4658:     mem_value = tme_htobe_u16(value);
                   4659: 
                   4660:     /* do the 16-bit bus write: */
                   4661:     tme_memory_bus_write16(mem, mem_value, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4662: 
                   4663:     /* step the transfer count: */
1.1       root     4664:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4665:   }
                   4666: 
                   4667:   /* otherwise, do the bus cycles the slow way: */
                   4668:   else {
                   4669:     tme_m68k_write16(ic, tlb,
                   4670:                     &function_code,
                   4671:                     &linear_address_first,
                   4672:                     &value,
                   4673:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4674:   }
1.1.1.4   root     4675: 
                   4676:   /* unbusy this TLB entry: */
                   4677:   tme_m68k_tlb_unbusy(tlb);
1.1       root     4678:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   4679:     ic->tme_m68k_ireg_a7 -= sizeof(tme_uint16_t);
                   4680:   }
                   4681: }
                   4682: 
                   4683: /* this reads a 32-bit memx value: */
                   4684: void
                   4685: tme_m68k_read_memx32(struct tme_m68k *ic) 
                   4686: {
1.1.1.5   root     4687:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4688:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   4689:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
                   4690:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
1.1.1.5   root     4691:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4692:   tme_uint32_t mem_value;
                   4693:   const tme_shared tme_uint32_t *mem;
1.1       root     4694: 
1.1.1.3   root     4695: #ifdef _TME_M68K_STATS
                   4696:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4697: #endif /* _TME_M68K_STATS */
                   4698: 
1.1.1.4   root     4699:   /* busy this TLB entry: */
                   4700:   tme_m68k_tlb_busy(tlb);
                   4701: 
                   4702:   /* if we aren't restarting, and this address is properly aligned,
                   4703:      and this TLB entry covers the operand and allows fast reads: */
1.1       root     4704:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4705:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4706:                          && tme_m68k_tlb_is_valid(tlb)
                   4707:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4708:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4709:                              & TME_BIT(function_code))
                   4710:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4711:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4712:                          && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4713: 
1.1.1.4   root     4714:     /* make the emulator memory pointer: */
                   4715:     mem = (const tme_shared tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first);
                   4716: 
                   4717:     /* do the 32-bit bus read: */
                   4718:     mem_value = tme_memory_bus_read32(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4719: 
                   4720:     /* put the value read, in host byte order: */
                   4721:     ic->tme_m68k_ireg_memx32 = tme_betoh_u32(mem_value);
                   4722: 
                   4723:     /* step the transfer count: */
1.1       root     4724:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4725:   }
                   4726: 
                   4727:   /* otherwise, do the bus cycles the slow way: */
                   4728:   else {
                   4729:     tme_m68k_read32(ic, tlb,
                   4730:                     &ic->_tme_m68k_ea_function_code,
                   4731:                     &ic->_tme_m68k_ea_address,
                   4732:                     &ic->tme_m68k_ireg_memx32,
                   4733:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4734:   }
                   4735: 
1.1.1.4   root     4736:   /* unbusy this TLB entry: */
                   4737:   tme_m68k_tlb_unbusy(tlb);
                   4738: 
1.1       root     4739:   /* log the value read: */
                   4740:   tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx32, TME_BUS_CYCLE_READ);
                   4741:   tme_m68k_log(ic, 1000, TME_OK,
                   4742:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4743:                 _("read_memx32 %d:0x%08x:      0x%08x"),
1.1       root     4744:                 ic->_tme_m68k_ea_function_code,
                   4745:                 ic->_tme_m68k_ea_address,
                   4746:                 ic->tme_m68k_ireg_memx32));
                   4747: }
                   4748: 
                   4749: /* this reads a 32-bit mem value: */
                   4750: void
                   4751: tme_m68k_read_mem32(struct tme_m68k *ic, int ireg) 
                   4752: {
1.1.1.5   root     4753:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4754:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   4755:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
                   4756:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
1.1.1.5   root     4757:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4758:   tme_uint32_t mem_value;
                   4759:   const tme_shared tme_uint32_t *mem;
1.1       root     4760: 
1.1.1.3   root     4761: #ifdef _TME_M68K_STATS
                   4762:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4763: #endif /* _TME_M68K_STATS */
                   4764: 
1.1.1.4   root     4765:   /* busy this TLB entry: */
                   4766:   tme_m68k_tlb_busy(tlb);
                   4767: 
                   4768:   /* if we aren't restarting, and this address is properly aligned,
                   4769:      and this TLB entry covers the operand and allows fast reads: */
1.1       root     4770:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4771:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4772:                          && tme_m68k_tlb_is_valid(tlb)
                   4773:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4774:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4775:                              & TME_BIT(function_code))
                   4776:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4777:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4778:                          && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4779: 
1.1.1.4   root     4780:     /* make the emulator memory pointer: */
                   4781:     mem = (const tme_shared tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first);
                   4782: 
                   4783:     /* do the 32-bit bus read: */
                   4784:     mem_value = tme_memory_bus_read32(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4785: 
                   4786:     /* put the value read, in host byte order: */
                   4787:     ic->tme_m68k_ireg_uint32(ireg) = tme_betoh_u32(mem_value);
                   4788: 
                   4789:     /* step the transfer count: */
1.1       root     4790:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4791:   }
                   4792: 
                   4793:   /* otherwise, do the bus cycles the slow way: */
                   4794:   else {
                   4795:     tme_m68k_read32(ic, tlb,
                   4796:                     &ic->_tme_m68k_ea_function_code,
                   4797:                     &ic->_tme_m68k_ea_address,
                   4798:                     &ic->tme_m68k_ireg_uint32(ireg),
                   4799:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4800:   }
                   4801: 
1.1.1.4   root     4802:   /* unbusy this TLB entry: */
                   4803:   tme_m68k_tlb_unbusy(tlb);
                   4804: 
1.1       root     4805:   /* log the value read: */
                   4806:   tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint32(ireg), TME_BUS_CYCLE_READ);
                   4807:   tme_m68k_log(ic, 1000, TME_OK,
                   4808:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4809:                 _("read_mem32  %d:0x%08x:      0x%08x"),
1.1       root     4810:                 ic->_tme_m68k_ea_function_code,
                   4811:                 ic->_tme_m68k_ea_address,
                   4812:                 ic->tme_m68k_ireg_uint32(ireg)));
                   4813: }
                   4814: 
                   4815: /* this reads a 32-bit inst value: */
                   4816: tme_uint32_t
                   4817: tme_m68k_fetch32(struct tme_m68k *ic, tme_uint32_t pc) 
                   4818: {
1.1.1.5   root     4819:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4820:   unsigned int function_code = TME_M68K_FUNCTION_CODE_PROGRAM(ic);
                   4821:   tme_uint32_t linear_address_first = pc;
                   4822:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
1.1.1.5   root     4823:   struct tme_m68k_tlb *tlb = &ic->_tme_m68k_itlb;
1.1.1.4   root     4824:   tme_uint32_t mem_value;
                   4825:   const tme_shared tme_uint32_t *mem;
                   4826:   unsigned int fetch_slow_next = ic->_tme_m68k_insn_fetch_slow_next;
1.1       root     4827: 
1.1.1.3   root     4828: #ifdef _TME_M68K_STATS
                   4829:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4830: #endif /* _TME_M68K_STATS */
                   4831: 
1.1.1.4   root     4832:   /* busy this TLB entry: */
                   4833:   tme_m68k_tlb_busy(tlb);
1.1       root     4834: 
1.1.1.4   root     4835:   /* if this fetch was done by the fast executor: */
                   4836:   if (__tme_predict_true(fetch_slow_next < ic->_tme_m68k_insn_fetch_slow_count_fast)) {
                   4837: 
                   4838:     /* the entire fetch must be in the instruction buffer, and
                   4839:        we must be restarting: */
                   4840:     assert ((fetch_slow_next + sizeof(tme_uint32_t))
                   4841:             <= ic->_tme_m68k_insn_fetch_slow_count_fast);
                   4842:     assert (TME_M68K_SEQUENCE_RESTARTING);
                   4843:     mem_value = tme_memory_read32(((tme_uint32_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)), sizeof(tme_uint16_t));
                   4844:   }
                   4845: 
                   4846:   /* otherwise, this fetch was not done by the fast executor: */
                   4847:   else {
                   4848: 
                   4849:     /* if we're restarting, but the offset in the instruction buffer
                   4850:        to fetch into is at the instruction buffer total, this must be
                   4851:        a fake fault caused by the fast executor.  we confirm this by
                   4852:        checking that this transfer "caused" the fault, and that this
                   4853:        transfer will be the first slow one after any fast fetches.
                   4854:        in this case, we can cancel the restart for now: */
                   4855:     if (TME_M68K_SEQUENCE_RESTARTING
                   4856:         && (fetch_slow_next
                   4857:             == ic->_tme_m68k_insn_fetch_slow_count_total)) {
                   4858:       assert ((ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next
                   4859:                == ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted)
                   4860:               && (fetch_slow_next
                   4861:                   == ic->_tme_m68k_insn_fetch_slow_count_fast));
                   4862:       ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted--;
1.1       root     4863:     }
1.1.1.4   root     4864: 
                   4865:     /* if we're not restarting: */
                   4866:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   4867: 
                   4868:       /* we advance the instruction buffer total *before* we do
                   4869:          what may be a slow fetch, because we may transfer a few
                   4870:          bytes and then fault.  without this, those few bytes
                   4871:          would not get saved in the exception stack frame and
                   4872:          restored later before the continuation of the fetch: */
                   4873:       ic->_tme_m68k_insn_fetch_slow_count_total += sizeof(tme_uint32_t);
                   4874:     }
                   4875: 
                   4876:     /* make sure that if this is a new transfer or if this
                   4877:        transfer faulted, that we're fetching for the current
                   4878:        last positions in the instruction buffer: */
                   4879:     assert ((ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next
                   4880:              < ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted)
                   4881:             || ((fetch_slow_next + sizeof(tme_uint32_t))
                   4882:                 == ic->_tme_m68k_insn_fetch_slow_count_total));
                   4883: 
                   4884:     /* if we aren't restarting, and this address is properly aligned,
                   4885:        and this TLB entry covers the operand and allows fast reads: */
                   4886:     if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
                   4887:                            && ((sizeof(tme_uint16_t) - 1) & linear_address_first) == 0
1.1.1.5   root     4888:                            && tme_m68k_tlb_is_valid(tlb)
                   4889:                            && tlb->tme_m68k_tlb_bus_context == bus_context
                   4890:                            && (tlb->tme_m68k_tlb_function_codes_mask
                   4891:                                & TME_BIT(function_code))
                   4892:                            && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4893:                            && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4894:                            && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1.1.4   root     4895: 
                   4896:       /* make the emulator memory pointer: */
                   4897:       mem = (const tme_shared tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first);
                   4898: 
                   4899:       /* do the 32-bit bus read: */
                   4900:       mem_value = tme_memory_bus_read32(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t));
                   4901: 
                   4902:       /* put the value read, in host byte order: */
                   4903:       mem_value = tme_betoh_u32(mem_value);
                   4904:       tme_memory_write32(((tme_uint32_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)), mem_value, sizeof(tme_uint16_t));
                   4905: 
                   4906:       /* step the transfer count: */
                   4907:       TME_M68K_SEQUENCE_TRANSFER_STEP;
1.1       root     4908:     }
1.1.1.4   root     4909: 
                   4910:     /* otherwise, do the bus cycles the slow way: */
1.1       root     4911:     else {
1.1.1.4   root     4912:       tme_m68k_read32(ic, tlb,
                   4913:                       &function_code,
                   4914:                       &pc,
                   4915:                       ((tme_uint32_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)),
                   4916:                       TME_M68K_BUS_CYCLE_FETCH);
                   4917:       mem_value = tme_memory_read32(((tme_uint32_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)), sizeof(tme_uint16_t));
1.1       root     4918:     }
                   4919:   }
                   4920: 
1.1.1.4   root     4921:   /* unbusy this TLB entry: */
                   4922:   tme_m68k_tlb_unbusy(tlb);
1.1       root     4923: 
                   4924:   /* log the value read: */
1.1.1.4   root     4925:   tme_m68k_verify_mem32(ic, function_code, pc, *((tme_uint32_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next)), TME_BUS_CYCLE_READ);
1.1       root     4926:   tme_m68k_log(ic, 1000, TME_OK,
                   4927:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     4928:                 _("fetch32     %d:0x%08x:      0x%08x"),
1.1       root     4929:                 function_code,
                   4930:                 pc,
1.1.1.4   root     4931:                 *((tme_uint32_t *) (((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) + fetch_slow_next))));
                   4932: 
                   4933:   /* advance the offset in the instruction buffer for the next slow fetch: */
                   4934:   fetch_slow_next += sizeof(tme_uint32_t);
                   4935:   ic->_tme_m68k_insn_fetch_slow_next = fetch_slow_next;
                   4936: 
                   4937:   /* return the fetched value: */
                   4938:   return(mem_value);
1.1       root     4939: }
                   4940: 
                   4941: /* this reads a 32-bit stack value: */
                   4942: void
                   4943: tme_m68k_pop32(struct tme_m68k *ic, tme_uint32_t *_value) 
                   4944: {
1.1.1.5   root     4945:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     4946:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   4947:   tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7;
                   4948:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
1.1.1.5   root     4949:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     4950:   tme_uint32_t mem_value;
                   4951:   const tme_shared tme_uint32_t *mem;
1.1       root     4952: 
1.1.1.3   root     4953: #ifdef _TME_M68K_STATS
                   4954:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   4955: #endif /* _TME_M68K_STATS */
                   4956: 
1.1.1.4   root     4957:   /* busy this TLB entry: */
                   4958:   tme_m68k_tlb_busy(tlb);
                   4959: 
                   4960:   /* if we aren't restarting, and this address is properly aligned,
                   4961:      and this TLB entry covers the operand and allows fast reads: */
1.1       root     4962:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     4963:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     4964:                          && tme_m68k_tlb_is_valid(tlb)
                   4965:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   4966:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   4967:                              & TME_BIT(function_code))
                   4968:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   4969:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   4970:                          && tlb->tme_m68k_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     4971: 
1.1.1.4   root     4972:     /* make the emulator memory pointer: */
                   4973:     mem = (const tme_shared tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_read + linear_address_first);
                   4974: 
                   4975:     /* do the 32-bit bus read: */
                   4976:     mem_value = tme_memory_bus_read32(mem, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   4977: 
                   4978:     /* put the value read, in host byte order: */
                   4979:     *_value = tme_betoh_u32(mem_value);
                   4980: 
                   4981:     /* step the transfer count: */
1.1       root     4982:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   4983:   }
                   4984: 
                   4985:   /* otherwise, do the bus cycles the slow way: */
                   4986:   else {
                   4987:     tme_m68k_read32(ic, tlb,
                   4988:                     &function_code,
                   4989:                     &ic->tme_m68k_ireg_a7,
                   4990:                     _value,
                   4991:                     TME_M68K_BUS_CYCLE_NORMAL);
                   4992:   }
                   4993: 
1.1.1.4   root     4994:   /* unbusy this TLB entry: */
                   4995:   tme_m68k_tlb_unbusy(tlb);
                   4996: 
1.1       root     4997:   /* log the value read: */
                   4998:   tme_m68k_verify_mem32(ic, function_code, ic->tme_m68k_ireg_a7, *_value, TME_BUS_CYCLE_READ);
                   4999:   tme_m68k_log(ic, 1000, TME_OK,
                   5000:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     5001:                 _("pop32       %d:0x%08x:      0x%08x"),
1.1       root     5002:                 function_code,
                   5003:                 ic->tme_m68k_ireg_a7,
                   5004:                 *_value));
                   5005:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   5006:     ic->tme_m68k_ireg_a7 += sizeof(tme_uint32_t);
                   5007:   }
                   5008: }
                   5009: 
                   5010: /* this writes a 32-bit memx value: */
                   5011: void
                   5012: tme_m68k_write_memx32(struct tme_m68k *ic) 
                   5013: {
1.1.1.5   root     5014:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     5015:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   5016:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
                   5017:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
1.1.1.5   root     5018:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     5019:   tme_uint32_t mem_value;
                   5020:   tme_shared tme_uint32_t *mem;
1.1       root     5021: 
1.1.1.3   root     5022: #ifdef _TME_M68K_STATS
                   5023:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   5024: #endif /* _TME_M68K_STATS */
                   5025: 
1.1       root     5026:   /* log the value written: */
                   5027:   tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx32, TME_BUS_CYCLE_WRITE);
                   5028:   tme_m68k_log(ic, 1000, TME_OK, 
                   5029:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     5030:                 _("write_memx32        %d:0x%08x:      0x%08x"),
1.1       root     5031:                 ic->_tme_m68k_ea_function_code,
                   5032:                 ic->_tme_m68k_ea_address,
                   5033:                 ic->tme_m68k_ireg_memx32));
                   5034: 
1.1.1.4   root     5035:   /* busy this TLB entry: */
                   5036:   tme_m68k_tlb_busy(tlb);
                   5037: 
                   5038:   /* if we aren't restarting, and this address is properly aligned,
                   5039:      and this TLB entry covers the operand and allows fast writes: */
1.1       root     5040:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     5041:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     5042:                          && tme_m68k_tlb_is_valid(tlb)
                   5043:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   5044:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   5045:                              & TME_BIT(function_code))
                   5046:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   5047:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   5048:                          && tlb->tme_m68k_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     5049: 
1.1.1.4   root     5050:     /* make the emulator memory pointer: */
                   5051:     mem = (tme_shared tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first);
                   5052: 
                   5053:     /* get the value to write, in big-endian byte order: */
                   5054:     mem_value = tme_htobe_u32(ic->tme_m68k_ireg_memx32);
                   5055: 
                   5056:     /* do the 32-bit bus write: */
                   5057:     tme_memory_bus_write32(mem, mem_value, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   5058: 
                   5059:     /* step the transfer count: */
1.1       root     5060:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   5061:   }
                   5062: 
                   5063:   /* otherwise, do the bus cycles the slow way: */
                   5064:   else {
                   5065:     tme_m68k_write32(ic, tlb,
                   5066:                     &ic->_tme_m68k_ea_function_code,
                   5067:                     &ic->_tme_m68k_ea_address,
                   5068:                     &ic->tme_m68k_ireg_memx32,
                   5069:                     TME_M68K_BUS_CYCLE_NORMAL);
                   5070:   }
1.1.1.4   root     5071: 
                   5072:   /* unbusy this TLB entry: */
                   5073:   tme_m68k_tlb_unbusy(tlb);
1.1       root     5074: }
                   5075: 
                   5076: /* this writes a 32-bit mem value: */
                   5077: void
                   5078: tme_m68k_write_mem32(struct tme_m68k *ic, int ireg) 
                   5079: {
1.1.1.5   root     5080:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     5081:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   5082:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
                   5083:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
1.1.1.5   root     5084:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     5085:   tme_uint32_t mem_value;
                   5086:   tme_shared tme_uint32_t *mem;
1.1       root     5087: 
1.1.1.3   root     5088: #ifdef _TME_M68K_STATS
                   5089:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   5090: #endif /* _TME_M68K_STATS */
                   5091: 
1.1       root     5092:   /* log the value written: */
                   5093:   tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint32(ireg), TME_BUS_CYCLE_WRITE);
                   5094:   tme_m68k_log(ic, 1000, TME_OK, 
                   5095:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     5096:                 _("write_mem32 %d:0x%08x:      0x%08x"),
1.1       root     5097:                 ic->_tme_m68k_ea_function_code,
                   5098:                 ic->_tme_m68k_ea_address,
                   5099:                 ic->tme_m68k_ireg_uint32(ireg)));
                   5100: 
1.1.1.4   root     5101:   /* busy this TLB entry: */
                   5102:   tme_m68k_tlb_busy(tlb);
                   5103: 
                   5104:   /* if we aren't restarting, and this address is properly aligned,
                   5105:      and this TLB entry covers the operand and allows fast writes: */
1.1       root     5106:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     5107:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     5108:                          && tme_m68k_tlb_is_valid(tlb)
                   5109:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   5110:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   5111:                              & TME_BIT(function_code))
                   5112:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   5113:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   5114:                          && tlb->tme_m68k_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     5115: 
1.1.1.4   root     5116:     /* make the emulator memory pointer: */
                   5117:     mem = (tme_shared tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first);
                   5118: 
                   5119:     /* get the value to write, in big-endian byte order: */
                   5120:     mem_value = tme_htobe_u32(ic->tme_m68k_ireg_uint32(ireg));
                   5121: 
                   5122:     /* do the 32-bit bus write: */
                   5123:     tme_memory_bus_write32(mem, mem_value, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   5124: 
                   5125:     /* step the transfer count: */
1.1       root     5126:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   5127:   }
                   5128: 
                   5129:   /* otherwise, do the bus cycles the slow way: */
                   5130:   else {
                   5131:     tme_m68k_write32(ic, tlb,
                   5132:                     &ic->_tme_m68k_ea_function_code,
                   5133:                     &ic->_tme_m68k_ea_address,
                   5134:                     &ic->tme_m68k_ireg_uint32(ireg),
                   5135:                     TME_M68K_BUS_CYCLE_NORMAL);
                   5136:   }
1.1.1.4   root     5137: 
                   5138:   /* unbusy this TLB entry: */
                   5139:   tme_m68k_tlb_unbusy(tlb);
1.1       root     5140: }
                   5141: 
                   5142: /* this writes a 32-bit stack value: */
                   5143: void
                   5144: tme_m68k_push32(struct tme_m68k *ic, tme_uint32_t value) 
                   5145: {
1.1.1.5   root     5146:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     5147:   unsigned int function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   5148:   tme_uint32_t linear_address_first = ic->tme_m68k_ireg_a7 - sizeof(tme_uint32_t);
                   5149:   tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1;
1.1.1.5   root     5150:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1.1.4   root     5151:   tme_uint32_t mem_value;
                   5152:   tme_shared tme_uint32_t *mem;
1.1       root     5153: 
1.1.1.3   root     5154: #ifdef _TME_M68K_STATS
                   5155:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   5156: #endif /* _TME_M68K_STATS */
                   5157: 
1.1       root     5158:   /* log the value written: */
                   5159:   tme_m68k_verify_mem32(ic, function_code, linear_address_first, value, TME_BUS_CYCLE_WRITE);
                   5160:   tme_m68k_log(ic, 1000, TME_OK, 
                   5161:                (TME_M68K_LOG_HANDLE(ic),
1.1.1.5   root     5162:                 _("push32      %d:0x%08x:      0x%08x"),
1.1       root     5163:                 function_code,
                   5164:                 linear_address_first,
                   5165:                 value));
                   5166: 
1.1.1.4   root     5167:   /* busy this TLB entry: */
                   5168:   tme_m68k_tlb_busy(tlb);
                   5169: 
                   5170:   /* if we aren't restarting, and this address is properly aligned,
                   5171:      and this TLB entry covers the operand and allows fast writes: */
1.1       root     5172:   if (__tme_predict_true(!TME_M68K_SEQUENCE_RESTARTING
1.1.1.4   root     5173:                          && (ic->_tme_m68k_bus_16bit & linear_address_first) == 0
1.1.1.5   root     5174:                          && tme_m68k_tlb_is_valid(tlb)
                   5175:                          && tlb->tme_m68k_tlb_bus_context == bus_context
                   5176:                          && (tlb->tme_m68k_tlb_function_codes_mask
                   5177:                              & TME_BIT(function_code))
                   5178:                          && linear_address_first >= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   5179:                          && linear_address_last <= (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
                   5180:                          && tlb->tme_m68k_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     5181: 
1.1.1.4   root     5182:     /* make the emulator memory pointer: */
                   5183:     mem = (tme_shared tme_uint32_t *) (tlb->tme_m68k_tlb_emulator_off_write + linear_address_first);
                   5184: 
                   5185:     /* get the value to write, in big-endian byte order: */
                   5186:     mem_value = tme_htobe_u32(value);
                   5187: 
                   5188:     /* do the 32-bit bus write: */
                   5189:     tme_memory_bus_write32(mem, mem_value, tlb->tme_m68k_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
                   5190: 
                   5191:     /* step the transfer count: */
1.1       root     5192:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   5193:   }
                   5194: 
                   5195:   /* otherwise, do the bus cycles the slow way: */
                   5196:   else {
                   5197:     tme_m68k_write32(ic, tlb,
                   5198:                     &function_code,
                   5199:                     &linear_address_first,
                   5200:                     &value,
                   5201:                     TME_M68K_BUS_CYCLE_NORMAL);
                   5202:   }
1.1.1.4   root     5203: 
                   5204:   /* unbusy this TLB entry: */
                   5205:   tme_m68k_tlb_unbusy(tlb);
1.1       root     5206:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   5207:     ic->tme_m68k_ireg_a7 -= sizeof(tme_uint32_t);
                   5208:   }
                   5209: }
                   5210: 
                   5211: /* this reads a any-bit mem value: */
                   5212: void
                   5213: tme_m68k_read_mem(struct tme_m68k *ic, tme_uint8_t *buffer, unsigned int count) 
                   5214: {
1.1.1.5   root     5215:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     5216:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   5217:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
1.1.1.5   root     5218:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1       root     5219: 
1.1.1.3   root     5220: #ifdef _TME_M68K_STATS
                   5221:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   5222: #endif /* _TME_M68K_STATS */
                   5223: 
1.1.1.4   root     5224:   /* busy this TLB entry: */
                   5225:   tme_m68k_tlb_busy(tlb);
1.1       root     5226: 
1.1.1.4   root     5227:   /* call the full read function: */
                   5228:   tme_m68k_read(ic, tlb, &ic->_tme_m68k_ea_function_code, &ic->_tme_m68k_ea_address, buffer, count, TME_M68K_BUS_CYCLE_RAW);
1.1       root     5229: 
1.1.1.4   root     5230:   /* unbusy this TLB entry: */
                   5231:   tme_m68k_tlb_unbusy(tlb);
1.1       root     5232: 
                   5233:   /* log the value read: */
                   5234:   tme_m68k_verify_mem_any(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, buffer, count, TME_BUS_CYCLE_READ);
                   5235:   tme_m68k_log_start(ic, 1000, TME_OK) {
                   5236:     unsigned int byte_i;
                   5237:     tme_log_part(TME_M68K_LOG_HANDLE(ic),
                   5238:                  _("read_mem %d:0x%08x count %d:"),
                   5239:                  ic->_tme_m68k_ea_function_code,
                   5240:                  ic->_tme_m68k_ea_address,
                   5241:                  count);
                   5242:     for (byte_i = 0; byte_i < count ; byte_i++) {
                   5243:       tme_log_part(TME_M68K_LOG_HANDLE(ic), " 0x%02x", (buffer)[byte_i]);
                   5244:     }
                   5245:   } tme_m68k_log_finish(ic);
                   5246: }
                   5247: 
                   5248: /* this reads a region of address space using actual bus cycles: */
                   5249: void
                   5250: tme_m68k_read(struct tme_m68k *ic, 
                   5251:               struct tme_m68k_tlb *tlb,
                   5252:               unsigned int *_function_code, 
                   5253:               tme_uint32_t *_linear_address, 
                   5254:               tme_uint8_t *reg,
                   5255:               unsigned int reg_size,
                   5256:               unsigned int flags)
                   5257: {
                   5258:   unsigned int function_code;
                   5259:   tme_uint32_t linear_address;
                   5260:   tme_bus_addr_t physical_address;
                   5261:   int shift;
                   5262:   struct tme_bus_cycle cycle;
                   5263:   unsigned int transferred, resid, cycle_size;
                   5264:   int exception;
                   5265:   int err;
                   5266:   tme_uint8_t *reg_p;
                   5267:   unsigned int buffer_i;
1.1.1.4   root     5268:   tme_uint8_t reg_buffer[sizeof(tme_uint32_t) * 2];
                   5269:   const tme_shared tme_uint8_t *mem;
1.1       root     5270: 
                   5271:   /* if we're not restarting, everything is fresh: */
                   5272:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   5273:     function_code = *_function_code;
                   5274:     linear_address = *_linear_address;
                   5275:     transferred = 0;
                   5276:   }
                   5277: 
                   5278:   /* otherwise, if this is the transfer that faulted, restore
                   5279:      our state to the cycle that faulted, then take into account
                   5280:      any data provided by a software rerun of the faulted cycle: */
                   5281:   else if (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted
                   5282:            == ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) {
                   5283:     function_code = *_function_code = ic->_tme_m68k_group0_function_code;
                   5284:     linear_address = ic->_tme_m68k_group0_address;
                   5285:     transferred = ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted_after;
                   5286:     if (transferred >= reg_size) abort();
                   5287:     *_linear_address = linear_address - transferred;
                   5288:     resid = reg_size - transferred;
                   5289:     if (ic->_tme_m68k_group0_buffer_read_size > resid) abort();
                   5290:     if (ic->_tme_m68k_group0_buffer_read_softrr > resid) abort();
                   5291:     if (ic->_tme_m68k_group0_buffer_read_softrr > 0) {
                   5292: #ifdef WORDS_BIGENDIAN
                   5293:       memcpy(reg + transferred, 
                   5294:              ic->_tme_m68k_group0_buffer_read,
                   5295:              ic->_tme_m68k_group0_buffer_read_size);
                   5296: #else  /* !WORDS_BIGENDIAN */
                   5297:       reg_p = (reg + reg_size - 1) - transferred;
                   5298:       for (buffer_i = 0;
                   5299:            buffer_i < ic->_tme_m68k_group0_buffer_read_size;
                   5300:            buffer_i++) {
                   5301:         *(reg_p--) = ic->_tme_m68k_group0_buffer_read[buffer_i];
                   5302:       }
                   5303: #endif /* !WORDS_BIGENDIAN */
                   5304:     }
                   5305:     transferred += ic->_tme_m68k_group0_buffer_read_softrr;
                   5306:   }
                   5307: 
                   5308:   /* otherwise, a later transfer has faulted.  just step the
                   5309:      transfer number and return: */
                   5310:   else {
                   5311:     TME_M68K_SEQUENCE_TRANSFER_STEP;
                   5312:     return;
                   5313:   }
                   5314: 
                   5315:   /* do as many bus cycles as needed to complete the transfer: */
                   5316:   exception = TME_M68K_EXCEPTION_NONE;
                   5317:   cycle_size = 0;
                   5318:   for(; transferred < reg_size; ) {
                   5319:     resid = reg_size - transferred;
                   5320: 
                   5321:     /* start the bus cycle structure: */
                   5322:     cycle.tme_bus_cycle_type = TME_BUS_CYCLE_READ;
                   5323:     if (TME_ENDIAN_NATIVE == TME_ENDIAN_BIG
                   5324:         || (flags & TME_M68K_BUS_CYCLE_RAW)) {
                   5325:       cycle.tme_bus_cycle_buffer = reg + transferred;
                   5326:       cycle.tme_bus_cycle_buffer_increment = 1;
                   5327:     }
                   5328:     else {
                   5329:       cycle.tme_bus_cycle_buffer = reg + reg_size - (1 + transferred);
                   5330:       cycle.tme_bus_cycle_buffer_increment = -1;
                   5331:     }
                   5332: 
                   5333:     /* if we're emulating a CPU with a 16-bit bus interface: */
                   5334:     if (ic->_tme_m68k_bus_16bit) {
                   5335: 
                   5336:       /* if we're trying to transfer a non-power-of-two
                   5337:          number of bytes, either the CPU is broken (no
                   5338:          instructions ever transfer a non-power-of-two
                   5339:          number of bytes), or this function allowed an
                   5340:          unaligned transfer: */
                   5341:       assert((resid & (resid - 1)) == 0
                   5342:              || (flags & TME_M68K_BUS_CYCLE_RAW));
                   5343: 
                   5344:       /* only byte transfers can be unaligned: */
                   5345:       if (resid > sizeof(tme_uint8_t)
                   5346:           && (linear_address & 1)) {
1.1.1.3   root     5347:           exception = TME_M68K_EXCEPTION_AERR;
1.1       root     5348:           break;
                   5349:       }
                   5350: 
                   5351:       /* set the bus-size specific parts of the bus cycle structure: */
                   5352:       cycle_size = TME_MIN(resid, sizeof(tme_uint16_t));
                   5353:       cycle.tme_bus_cycle_size = cycle_size;
                   5354:       cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS16_LOG2);
                   5355:       cycle.tme_bus_cycle_lane_routing = 
                   5356:         &tme_m68k_router_16[TME_M68K_BUS_ROUTER_INDEX(TME_BUS16_LOG2, cycle_size, linear_address)];
                   5357:     }
                   5358: 
                   5359:     /* otherwise we're emulating a CPU with a 32-bit bus interface: */
                   5360:     else {
                   5361: 
                   5362:       /* an instruction fetch must be aligned: */
                   5363:       if (flags & TME_M68K_BUS_CYCLE_FETCH) {
                   5364:         if (linear_address & 1) {
1.1.1.3   root     5365:           exception = TME_M68K_EXCEPTION_AERR;
1.1       root     5366:           break;
                   5367:         }
                   5368:         assert(!(resid & 1));
                   5369:       }
                   5370: 
                   5371:       /* set the bus-size specific parts of the bus cycle structure: */
                   5372:       cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (linear_address & (sizeof(tme_uint32_t) - 1)));
                   5373:       cycle.tme_bus_cycle_size = cycle_size;
                   5374:       cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2);
                   5375:       cycle.tme_bus_cycle_lane_routing = 
                   5376:         &tme_m68k_router_32[TME_M68K_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, linear_address)];
                   5377:     }
                   5378: 
1.1.1.4   root     5379:     /* loop while this TLB entry is invalid or does not apply: */
1.1.1.5   root     5380:     for (; __tme_predict_false(tme_m68k_tlb_is_invalid(tlb)
                   5381:                                || tlb->tme_m68k_tlb_bus_context != ic->_tme_m68k_bus_context
1.1.1.4   root     5382:                                || (tlb->tme_m68k_tlb_function_codes_mask & TME_BIT(function_code)) == 0
1.1.1.5   root     5383:                                || linear_address < (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   5384:                                || linear_address > (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
1.1.1.4   root     5385:                                || (tlb->tme_m68k_tlb_emulator_off_read == TME_EMULATOR_OFF_UNDEF
                   5386:                                    && (tlb->tme_m68k_tlb_cycles_ok & TME_BUS_CYCLE_READ) == 0)); ) {
                   5387: 
                   5388:       /* this must not be part of a read/modify/write cycle: */
                   5389:       assert(!(flags & TME_M68K_BUS_CYCLE_RMW));
                   5390: 
                   5391:       /* fill this TLB entry: */
1.1       root     5392:       tme_m68k_tlb_fill(ic, tlb,
                   5393:                         function_code,
                   5394:                         linear_address,
                   5395:                         TME_BUS_CYCLE_READ);
                   5396:     }
                   5397: 
1.1.1.4   root     5398:     /* if this TLB entry allows for fast reads: */
                   5399:     mem = tlb->tme_m68k_tlb_emulator_off_read;
                   5400:     if (__tme_predict_true(mem != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     5401: 
1.1.1.4   root     5402:       /* make the emulator memory pointer: */
                   5403:       mem += linear_address;
                   5404: 
                   5405:       /* limit the cycle size to addresses covered by the TLB entry: */
                   5406:       if (__tme_predict_false((cycle_size - 1)
1.1.1.5   root     5407:                               > (((tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last) - linear_address))) {
                   5408:         cycle_size = (((tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last) - linear_address) + 1;
1.1       root     5409:       }
                   5410: 
1.1.1.4   root     5411:       /* if this is a little-endian host, and this isn't a raw read: */
                   5412:       if (TME_ENDIAN_NATIVE == TME_ENDIAN_LITTLE
                   5413:           && (flags & TME_M68K_BUS_CYCLE_RAW) == 0) {
                   5414: 
                   5415:         /* use the intermediate buffer for the read: */
                   5416:         cycle.tme_bus_cycle_buffer = &reg_buffer[0];
1.1       root     5417:       }
1.1.1.4   root     5418: 
                   5419:       /* do the bus read: */
                   5420:       tme_memory_bus_read_buffer(mem,
                   5421:                                  cycle.tme_bus_cycle_buffer,
                   5422:                                  cycle_size,
                   5423:                                  tlb->tme_m68k_tlb_bus_rwlock,
                   5424:                                  sizeof(tme_uint8_t),
                   5425:                                  sizeof(tme_uint32_t));
                   5426: 
                   5427:       /* if this is a little-endian host, and this isn't a raw read: */
                   5428:       if (TME_ENDIAN_NATIVE == TME_ENDIAN_LITTLE
                   5429:           && (flags & TME_M68K_BUS_CYCLE_RAW) == 0) {
                   5430: 
                   5431:         /* byteswap the read data in the intermediate buffer: */
                   5432:         reg_p = reg + reg_size - (1 + transferred);
                   5433:         buffer_i = 0;
                   5434:         do {
                   5435:           *(reg_p--) = reg_buffer[buffer_i];
                   5436:         } while (++buffer_i != cycle_size);
                   5437:       }
                   5438: 
                   5439:       /* update: */
                   5440:       linear_address += cycle_size;
                   5441:       transferred += cycle_size;
                   5442:       continue;
                   5443:     }
                   5444: 
                   5445:     /* otherwise, this TLB entry does not allow for fast reads: */
                   5446: 
                   5447:     /* if this is a part of a read/modify/write cycle: */
                   5448:     if (flags & TME_M68K_BUS_CYCLE_RMW) {
                   5449: 
                   5450:       /* if this is the first cycle in this read,
                   5451:          we will establish the new lock, otherwise
                   5452:          we will continue using the existing lock: */
                   5453:       cycle.tme_bus_cycle_type
                   5454:         |= (TME_BUS_CYCLE_LOCK
                   5455:             | (transferred == 0 ? 0 : TME_BUS_CYCLE_UNLOCK));
1.1       root     5456:     }
                   5457: 
                   5458:     /* form the physical address for the bus cycle handler: */
                   5459:     physical_address = tlb->tme_m68k_tlb_addr_offset + linear_address;
                   5460:     shift = tlb->tme_m68k_tlb_addr_shift;
                   5461:     if (shift < 0) {
                   5462:       physical_address <<= (0 - shift);
                   5463:     }
                   5464:     else if (shift > 0) {
                   5465:       physical_address >>= shift;
                   5466:     }
                   5467:     cycle.tme_bus_cycle_address = physical_address;
                   5468: 
                   5469:     /* run the bus cycle: */
1.1.1.4   root     5470:     tme_m68k_tlb_unbusy(tlb);
                   5471:     tme_m68k_callout_unlock(ic);
1.1       root     5472:     err = (*tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle)
                   5473:          (tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle);
1.1.1.4   root     5474:     tme_m68k_callout_relock(ic);
                   5475:     tme_m68k_tlb_busy(tlb);
1.1       root     5476: 
1.1.1.4   root     5477:     /* if the TLB entry was invalidated before the read: */
                   5478:     if (err == EBADF
1.1.1.5   root     5479:         && tme_m68k_tlb_is_invalid(tlb)) {
1.1.1.4   root     5480:       cycle.tme_bus_cycle_size = 0;
1.1       root     5481:     }
                   5482: 
1.1.1.3   root     5483:     /* otherwise, if we didn't get a bus error, but some
                   5484:        synchronous event has happened: */
                   5485:     else if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {
                   5486: 
                   5487:       /* after the currently executing instruction finishes, check
                   5488:          for external resets, halts, or interrupts: */
                   5489:       ic->_tme_m68k_instruction_burst_remaining = 0;
                   5490:     }
                   5491: 
1.1       root     5492:     /* otherwise, any other error might be a bus error: */
                   5493:     else if (err != TME_OK) {
                   5494:       err = tme_bus_tlb_fault(&tlb->tme_m68k_tlb_bus_tlb, &cycle, err);
                   5495:       if (err != TME_OK) {
1.1.1.3   root     5496:         exception = TME_M68K_EXCEPTION_BERR;
1.1       root     5497:         break;
                   5498:       }
                   5499:     }
                   5500: 
                   5501:     /* update: */
                   5502:     linear_address += cycle.tme_bus_cycle_size;
                   5503:     transferred += cycle.tme_bus_cycle_size;
                   5504:   }
                   5505: 
1.1.1.4   root     5506:   /* NB: there is no need to explicitly unlock
                   5507:      a device.  if a locked bus cycle to a device
                   5508:      faults, the lock must be automatically unlocked: */
1.1       root     5509: 
                   5510:   /* if we faulted, stash the information the fault stacker
                   5511:      will need and start exception processing: */
                   5512:   if (exception != TME_M68K_EXCEPTION_NONE) {
                   5513:     ic->_tme_m68k_group0_flags = flags | TME_M68K_BUS_CYCLE_READ;
                   5514:     ic->_tme_m68k_group0_function_code = function_code;
                   5515:     ic->_tme_m68k_group0_address = linear_address;
                   5516:     ic->_tme_m68k_group0_sequence = ic->_tme_m68k_sequence;
                   5517:     ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted_after = transferred;
                   5518:     ic->_tme_m68k_group0_buffer_read_size = cycle_size;
                   5519:     if (ic->_tme_m68k_group0_hook != NULL) {
                   5520:       (*ic->_tme_m68k_group0_hook)(ic);
                   5521:     }
                   5522:     ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted = 
                   5523:       ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_next;
1.1.1.4   root     5524:     tme_m68k_tlb_unbusy(tlb);
1.1       root     5525:     tme_m68k_exception(ic, exception);
                   5526:   }
                   5527: 
                   5528:   /* otherwise, this transfer has now completed: */
                   5529:   TME_M68K_SEQUENCE_TRANSFER_STEP;
                   5530: }
                   5531: 
                   5532: /* this writes a any-bit mem value: */
                   5533: void
                   5534: tme_m68k_write_mem(struct tme_m68k *ic, tme_uint8_t *buffer, unsigned int count) 
                   5535: {
1.1.1.5   root     5536:   tme_bus_context_t bus_context = ic->_tme_m68k_bus_context;
1.1       root     5537:   unsigned int function_code = ic->_tme_m68k_ea_function_code;
                   5538:   tme_uint32_t linear_address_first = ic->_tme_m68k_ea_address;
1.1.1.5   root     5539:   struct tme_m68k_tlb *tlb = TME_M68K_DTLB_ENTRY(ic, bus_context, function_code, linear_address_first);
1.1       root     5540: 
1.1.1.3   root     5541: #ifdef _TME_M68K_STATS
                   5542:   ic->tme_m68k_stats.tme_m68k_stats_memory_total++;
                   5543: #endif /* _TME_M68K_STATS */
                   5544: 
1.1       root     5545:   /* log the value written: */
                   5546:   tme_m68k_verify_mem_any(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, buffer, count, TME_BUS_CYCLE_WRITE);
                   5547:   tme_m68k_log_start(ic, 1000, TME_OK) {
                   5548:     unsigned int byte_i;
                   5549:     tme_log_part(TME_M68K_LOG_HANDLE(ic),
                   5550:                  _("write_mem %d:0x%08x count %d:"),
                   5551:                  ic->_tme_m68k_ea_function_code,
                   5552:                  ic->_tme_m68k_ea_address,
                   5553:                  count);
                   5554:     for (byte_i = 0; byte_i < count ; byte_i++) {
                   5555:       tme_log_part(TME_M68K_LOG_HANDLE(ic), " 0x%02x", (buffer)[byte_i]);
                   5556:     }
                   5557:   } tme_m68k_log_finish(ic);
                   5558: 
1.1.1.4   root     5559:   /* busy this TLB entry: */
                   5560:   tme_m68k_tlb_busy(tlb);
1.1       root     5561: 
1.1.1.4   root     5562:   /* call the full write function: */
                   5563:   tme_m68k_write(ic, tlb, &ic->_tme_m68k_ea_function_code, &ic->_tme_m68k_ea_address, buffer, count, TME_M68K_BUS_CYCLE_RAW);
1.1       root     5564: 
1.1.1.4   root     5565:   /* unbusy this TLB entry: */
                   5566:   tme_m68k_tlb_unbusy(tlb);
1.1       root     5567: }
                   5568: 
                   5569: /* this writes a region of address space using actual bus cycles: */
                   5570: void
                   5571: tme_m68k_write(struct tme_m68k *ic, 
                   5572:               struct tme_m68k_tlb *tlb,
                   5573:               unsigned int *_function_code, 
                   5574:               tme_uint32_t *_linear_address, 
                   5575:               tme_uint8_t *reg,
                   5576:               unsigned int reg_size,
                   5577:               unsigned int flags)
                   5578: {
                   5579:   unsigned int function_code;
                   5580:   tme_uint32_t linear_address;
                   5581:   tme_bus_addr_t physical_address;
                   5582:   int shift;
                   5583:   struct tme_bus_cycle cycle;
                   5584:   unsigned int transferred, resid, cycle_size;
                   5585:   int exception;
                   5586:   int err;
                   5587:   tme_uint8_t *reg_p;
                   5588:   unsigned int buffer_i;
1.1.1.4   root     5589:   tme_uint8_t reg_buffer[sizeof(tme_uint32_t) * 2];
                   5590:   tme_shared tme_uint8_t *mem;
1.1       root     5591: 
1.1.1.6 ! root     5592: #if 1
        !          5593:   int should_fault = 0;
        !          5594:     {
        !          5595:            extern int printf(const char *format, ...);
        !          5596:            if ((int)ic->tme_m68k_ireg_pc == 0x3c3bc) {
        !          5597:                    printf("tme_m68k_write; *_linear_address %x\n", (int)*_linear_address);
        !          5598:                    if ((int)*_linear_address == 0x509000) {
        !          5599:                            should_fault = 1;
        !          5600:                    }
        !          5601:                    printf("tme_m68k_write; should_fault %d\n", should_fault);
        !          5602:            }
        !          5603:     }
        !          5604: #endif
        !          5605: 
1.1       root     5606:   /* if we're not restarting, everything is fresh: */
                   5607:   if (!TME_M68K_SEQUENCE_RESTARTING) {
                   5608:     function_code = *_function_code;
                   5609:     linear_address = *_linear_address;
                   5610:     transferred = 0;
                   5611:   }
                   5612: 
                   5613:   /* otherwise, if this is the transfer that faulted, restore
                   5614:      our state to the cycle that faulted, then take into account
                   5615:      any data provided by a software rerun of the faulted cycle: */
                   5616:   else if (ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted
                   5617:            == ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_next) {
                   5618:     function_code = *_function_code = ic->_tme_m68k_group0_function_code;
                   5619:     linear_address = ic->_tme_m68k_group0_address;
                   5620:     transferred = ic->_tme_m68k_sequence._tme_m68k_sequence_transfer_faulted_after;
                   5621:     if (transferred >= reg_size) abort();
                   5622:     *_linear_address = linear_address - transferred;
                   5623:     resid = reg_size - transferred;
                   5624:     if (ic->_tme_m68k_group0_buffer_write_size > resid) abort();
                   5625:     if (ic->_tme_m68k_group0_buffer_write_softrr > resid) abort();
                   5626:     if (ic->_tme_m68k_group0_buffer_write_softrr == 0) {
                   5627: #ifdef WORDS_BIGENDIAN
                   5628:       memcpy(reg + transferred, 
                   5629:              ic->_tme_m68k_group0_buffer_write,
                   5630:              ic->_tme_m68k_group0_buffer_write_size);
                   5631: #else  /* !WORDS_BIGENDIAN */
                   5632:       reg_p = (reg + reg_size - 1) - transferred;
                   5633:       for (buffer_i = 0;
                   5634:            buffer_i < ic->_tme_m68k_group0_buffer_write_size;
                   5635:            buffer_i++) {
                   5636:         *(reg_p--) = ic->_tme_m68k_group0_buffer_write[buffer_i];
                   5637:       }
                   5638: #endif /* !WORDS_BIGENDIAN */
                   5639:     }
                   5640:     transferred += ic->_tme_m68k_group0_buffer_write_softrr;
                   5641:   }
                   5642: 
                   5643:   /* otherwise, a later transfer has faulted.  just step the
                   5644:      transfer number and return: */
                   5645:   else {
                   5646:     TME_M68K_SEQUENCE_TRANSFER_STEP;
1.1.1.6 ! root     5647: #if 0
        !          5648:     {
        !          5649:            extern int printf(const char *format, ...);
        !          5650:            if ((int)ic->tme_m68k_ireg_pc == 0x3c3bc) {
        !          5651:                    printf("tme_m68k_write; returning\n");
        !          5652:            }
        !          5653:     }
        !          5654: #endif
1.1       root     5655:     return;
                   5656:   }
                   5657: 
                   5658:   /* do as many bus cycles as needed to complete the transfer: */
                   5659:   exception = TME_M68K_EXCEPTION_NONE;
                   5660:   cycle_size = 0;
                   5661:   for(; transferred < reg_size; ) {
1.1.1.6 ! root     5662: #if 0
        !          5663:     {
        !          5664:            extern int printf(const char *format, ...);
        !          5665:            if ((int)ic->tme_m68k_ireg_pc == 0x3c3bc) {
        !          5666:                    printf("tme_m68k_write; loop %x\n", (int)linear_address);
        !          5667:            }
        !          5668:     }
        !          5669: #endif
1.1       root     5670:     resid = reg_size - transferred;
                   5671: 
                   5672:     /* start the bus cycle structure: */
                   5673:     cycle.tme_bus_cycle_type = TME_BUS_CYCLE_WRITE;
                   5674:     if (TME_ENDIAN_NATIVE == TME_ENDIAN_BIG
                   5675:         || (flags & TME_M68K_BUS_CYCLE_RAW)) {
                   5676:       cycle.tme_bus_cycle_buffer = reg + transferred;
                   5677:       cycle.tme_bus_cycle_buffer_increment = 1;
                   5678:     }
                   5679:     else {
                   5680:       cycle.tme_bus_cycle_buffer = reg + reg_size - (1 + transferred);
                   5681:       cycle.tme_bus_cycle_buffer_increment = -1;
                   5682:     }
                   5683: 
                   5684:     /* if we're emulating a CPU with a 16-bit bus interface: */
                   5685:     if (ic->_tme_m68k_bus_16bit) {
                   5686: 
                   5687:       /* if we're trying to transfer a non-power-of-two
                   5688:          number of bytes, either the CPU is broken (no
                   5689:          instructions ever transfer a non-power-of-two
                   5690:          number of bytes), or this function allowed an
                   5691:          unaligned transfer: */
                   5692:       assert((resid & (resid - 1)) == 0
                   5693:              || (flags & TME_M68K_BUS_CYCLE_RAW));
                   5694: 
                   5695:       /* only byte transfers can be unaligned: */
                   5696:       if (resid > sizeof(tme_uint8_t)
                   5697:           && (linear_address & 1)) {
1.1.1.3   root     5698:           exception = TME_M68K_EXCEPTION_AERR;
1.1       root     5699:           break;
                   5700:       }
                   5701: 
                   5702:       /* set the bus-size specific parts of the bus cycle structure: */
                   5703:       cycle_size = TME_MIN(resid, sizeof(tme_uint16_t));
                   5704:       cycle.tme_bus_cycle_size = cycle_size;
                   5705:       cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS16_LOG2);
                   5706:       cycle.tme_bus_cycle_lane_routing = 
                   5707:         &tme_m68k_router_16[TME_M68K_BUS_ROUTER_INDEX(TME_BUS16_LOG2, cycle_size, linear_address)];
                   5708:     }
                   5709: 
                   5710:     /* otherwise we're emulating a CPU with a 32-bit bus interface: */
                   5711:     else {
                   5712: 
                   5713:       /* set the bus-size specific parts of the bus cycle structure: */
                   5714:       cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (linear_address & (sizeof(tme_uint32_t) - 1)));
                   5715:       cycle.tme_bus_cycle_size = cycle_size;
                   5716:       cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2);
                   5717:       cycle.tme_bus_cycle_lane_routing = 
                   5718:         &tme_m68k_router_32[TME_M68K_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, linear_address)];
                   5719:     }
                   5720: 
1.1.1.4   root     5721:     /* loop while this TLB entry is invalid or does not apply: */
1.1.1.5   root     5722:     for (; __tme_predict_false(tme_m68k_tlb_is_invalid(tlb)
                   5723:                                || tlb->tme_m68k_tlb_bus_context != ic->_tme_m68k_bus_context
1.1.1.4   root     5724:                                || (tlb->tme_m68k_tlb_function_codes_mask & TME_BIT(function_code)) == 0
1.1.1.5   root     5725:                                || linear_address < (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_first
                   5726:                                || linear_address > (tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last
1.1.1.4   root     5727:                                || (tlb->tme_m68k_tlb_emulator_off_write == TME_EMULATOR_OFF_UNDEF
                   5728:                                    && (tlb->tme_m68k_tlb_cycles_ok & TME_BUS_CYCLE_WRITE) == 0)); ) {
                   5729: 
                   5730:       /* this must not be part of a read/modify/write cycle: */
                   5731:       assert(!(flags & TME_M68K_BUS_CYCLE_RMW));
                   5732: 
                   5733:       /* fill this TLB entry: */
1.1       root     5734:       tme_m68k_tlb_fill(ic, tlb,
                   5735:                         function_code,
                   5736:                         linear_address,
                   5737:                         TME_BUS_CYCLE_WRITE);
                   5738:     }
                   5739: 
1.1.1.4   root     5740:     /* if this TLB entry allows for fast writes: */
                   5741:     mem = tlb->tme_m68k_tlb_emulator_off_write;
                   5742:     if (__tme_predict_true(mem != TME_EMULATOR_OFF_UNDEF)) {
1.1       root     5743: 
1.1.1.4   root     5744:       /* make the emulator memory pointer: */
                   5745:       mem += linear_address;
                   5746: 
                   5747:       /* limit the cycle size to addresses covered by the TLB entry: */
                   5748:       if (__tme_predict_false((cycle_size - 1)
1.1.1.5   root     5749:                               > (((tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last) - linear_address))) {
                   5750:         cycle_size = (((tme_bus_addr32_t) tlb->tme_m68k_tlb_linear_last) - linear_address) + 1;
1.1       root     5751:       }
                   5752: 
1.1.1.4   root     5753:       /* if this is a little-endian host, and this isn't a raw write: */
                   5754:       if (TME_ENDIAN_NATIVE == TME_ENDIAN_LITTLE
                   5755:           && (flags & TME_M68K_BUS_CYCLE_RAW) == 0) {
                   5756: 
                   5757:         /* byteswap the data to write in the intermediate buffer: */
                   5758:         reg_p = cycle.tme_bus_cycle_buffer;
                   5759:         buffer_i = 0;
                   5760:         do {
                   5761:           reg_buffer[buffer_i] = *(reg_p--);
                   5762:         } while (++buffer_i != cycle_size);
                   5763: 
                   5764:         /* use the intermediate buffer for the write: */
                   5765:         cycle.tme_bus_cycle_buffer = &reg_buffer[0];
1.1       root     5766:       }
1.1.1.4   root     5767: 
                   5768:       /* do the bus write: */
                   5769:       tme_memory_bus_write_buffer(mem,
                   5770:                                  cycle.tme_bus_cycle_buffer,
                   5771:                                  cycle_size,
                   5772:                                  tlb->tme_m68k_tlb_bus_rwlock,
                   5773:                                  sizeof(tme_uint8_t),
                   5774:                                  sizeof(tme_uint32_t));
                   5775: 
                   5776:       /* update: */
                   5777:       linear_address += cycle_size;
                   5778:       transferred += cycle_size;
                   5779:       continue;
                   5780:     }
                   5781: 
                   5782:     /* otherwise, this TLB entry does not allow for fast writes: */
                   5783: 
                   5784:     /* if this is a part of a read/modify/write cycle: */
                   5785:     if (flags & TME_M68K_BUS_CYCLE_RMW) {
                   5786: 
                   5787:       /* we will continue using the existing lock.
                   5788:          the device will automatically unlock after
                   5789:          the last cycle of this write: */
                   5790:       cycle.tme_bus_cycle_type
                   5791:         |= (TME_BUS_CYCLE_LOCK
                   5792:             | (TME_BUS_CYCLE_UNLOCK));
1.1       root     5793:     }
                   5794: 
                   5795:     /* form the physical address for the bus cycle handler: */
                   5796:     physical_address = tlb->tme_m68k_tlb_addr_offset + linear_address;
                   5797:     shift = tlb->tme_m68k_tlb_addr_shift;
                   5798:     if (shift < 0) {
                   5799:       physical_address <<= (0 - shift);
                   5800:     }
                   5801:     else if (shift > 0) {
                   5802:       physical_address >>= shift;
                   5803:     }
                   5804:     cycle.tme_bus_cycle_address = physical_address;
                   5805: 
                   5806:     /* run the bus cycle: */
1.1.1.4   root     5807:     tme_m68k_tlb_unbusy(tlb);
                   5808:     tme_m68k_callout_unlock(ic);
1.1       root     5809:     err = (*tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle)
                   5810:          (tlb->tme_m68k_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle);
1.1.1.4   root     5811:     tme_m68k_callout_relock(ic);
                   5812:     tme_m68k_tlb_busy(tlb);
1.1       root     5813: 
1.1.1.6 ! root     5814: #if 0
        !          5815:     {
        !          5816:            extern int printf(const char *format, ...);
        !          5817:            if ((int)ic->tme_m68k_ireg_pc == 0x3c3bc) {
        !          5818:                    printf("tme_m68k_write; old %x\n", (int)err);
        !          5819:                    err = ENOENT;
        !          5820:            }
        !          5821:     }
        !          5822: #endif
        !          5823: 
1.1.1.4   root     5824:     /* if the TLB entry was invalidated before the write: */
                   5825:     if (err == EBADF
1.1.1.5   root     5826:         && tme_m68k_tlb_is_invalid(tlb)) {
1.1.1.4   root     5827:       cycle.tme_bus_cycle_size = 0;
1.1       root     5828:     }
                   5829: 
1.1.1.3   root     5830:     /* otherwise, if we didn't get a bus error, but some
                   5831:        synchronous event has happened: */
                   5832:     else if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {
                   5833: 
                   5834:       /* after the currently executing instruction finishes, check
                   5835:          for external resets, halts, or interrupts: */
                   5836:       ic->_tme_m68k_instruction_burst_remaining = 0;
                   5837:     }
                   5838: 
1.1       root     5839:     /* otherwise, any other error might be a bus error: */
                   5840:     else if (err != TME_OK) {
                   5841:       err = tme_bus_tlb_fault(&tlb->tme_m68k_tlb_bus_tlb, &cycle, err);
                   5842:       if (err != TME_OK) {
1.1.1.3   root     5843:         exception = TME_M68K_EXCEPTION_BERR;
1.1       root     5844:         break;
                   5845:       }
                   5846:     }
                   5847: 
                   5848:     /* update: */
                   5849:     linear_address += cycle.tme_bus_cycle_size;
                   5850:     transferred += cycle.tme_bus_cycle_size;
                   5851:   }
                   5852: 
1.1.1.6 ! root     5853: #if 1
        !          5854:     {
        !          5855:            extern int printf(const char *format, ...);
        !          5856:            if ((int)ic->tme_m68k_ireg_pc == 0x3c3bc) {
        !          5857:                    if (0) printf("tme_m68k_write; not returning\n");
        !          5858:                    if (should_fault)  {
        !          5859:                            printf("tme_m68k_write; faulting\n");
        !          5860:                            exception = TME_M68K_EXCEPTION_BERR;
        !          5861:                    }
        !          5862:            }
        !          5863:     }
        !          5864: #endif
1.1.1.4   root     5865:   /* NB: there is no need to explicitly unlock
                   5866:      a device.  if a locked bus cycle to a device
                   5867:      faults, the lock must be automatically unlocked: */
1.1       root     5868: 
                   5869:   /* if we faulted, stash the information the fault stacker
                   5870:      will need and start exception processing: */
                   5871:   if (exception != TME_M68K_EXCEPTION_NONE) {
                   5872:     ic->_tme_m68k_group0_flags = flags;
                   5873:     ic->_tme_m68k_group0_function_code = function_code;
                   5874:     ic->_tme_m68k_group0_address = linear_address;
                   5875:     ic->_tme_m68k_group0_sequence = ic->_tme_m68k_sequence;
                   5876:     ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted_after = transferred;
                   5877:     ic->_tme_m68k_group0_buffer_write_size = cycle_size;
                   5878: #ifdef WORDS_BIGENDIAN
                   5879:     memcpy(ic->_tme_m68k_group0_buffer_write,
                   5880:            reg + transferred,
                   5881:            ic->_tme_m68k_group0_buffer_write_size);
                   5882: #else  /* !WORDS_BIGENDIAN */
                   5883:       reg_p = (reg + reg_size - 1) - transferred;
                   5884:       for (buffer_i = 0;
                   5885:            buffer_i < ic->_tme_m68k_group0_buffer_write_size;
                   5886:            buffer_i++) {
                   5887:         ic->_tme_m68k_group0_buffer_write[buffer_i] = *(reg_p--);
                   5888:       }
                   5889: #endif /* !WORDS_BIGENDIAN */
                   5890:     if (ic->_tme_m68k_group0_hook != NULL) {
                   5891:       (*ic->_tme_m68k_group0_hook)(ic);
                   5892:     }
                   5893:     ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_faulted = 
                   5894:       ic->_tme_m68k_group0_sequence._tme_m68k_sequence_transfer_next;
1.1.1.4   root     5895:     tme_m68k_tlb_unbusy(tlb);
1.1       root     5896:     tme_m68k_exception(ic, exception);
                   5897:   }
                   5898: 
                   5899:   /* otherwise, this transfer has now completed: */
                   5900:   TME_M68K_SEQUENCE_TRANSFER_STEP;
1.1.1.6 ! root     5901: 
        !          5902: #if 0
        !          5903:     {
        !          5904:            extern int printf(const char *format, ...);
        !          5905:            if ((int)ic->tme_m68k_ireg_pc == 0x3c3bc) {
        !          5906:                    printf("tme_m68k_write; end\n");
        !          5907:            }
        !          5908:     }
        !          5909: #endif
1.1       root     5910: }
                   5911: 
                   5912: TME_M68K_INSN(tme_m68k_abcd)
                   5913: {
                   5914:   tme_uint8_t dst, dst_msd, dst_lsd;
                   5915:   tme_uint8_t src, src_msd, src_lsd;
                   5916:   tme_uint8_t res, res_msd, res_lsd;
                   5917:   tme_uint8_t flags;
                   5918:   int memory;
                   5919:   int rx, ry, function_code;
                   5920: 
                   5921:   /* load the operands: */
                   5922:   rx = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   5923:   ry = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   5924:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)) != 0;
                   5925:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   5926:   if (memory) {
1.1.1.4   root     5927:     TME_M68K_INSN_CANFAULT;
1.1       root     5928:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     5929:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx) -= sizeof(tme_uint8_t) + ((rx + 1) >> 3);
1.1       root     5930:       ic->_tme_m68k_ea_function_code = function_code;
                   5931:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx);
                   5932:     }
                   5933:     tme_m68k_read_memx8(ic);
                   5934:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     5935:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry) -= sizeof(tme_uint8_t) + ((ry + 1) >> 3);
1.1       root     5936:       ic->_tme_m68k_ea_function_code = function_code;
                   5937:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry);
                   5938:     }
                   5939:     tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY32);
                   5940:     src = ic->tme_m68k_ireg_memx8;
                   5941:     dst = ic->tme_m68k_ireg_memy8;
                   5942:   }
                   5943:   else {
                   5944:     src = ic->tme_m68k_ireg_uint8(rx << 2);
                   5945:     dst = ic->tme_m68k_ireg_uint8(ry << 2);
                   5946:   }
                   5947:   dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4);
                   5948:   dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4);
                   5949:   src_lsd = TME_FIELD_EXTRACTU(src, 0, 4);
                   5950:   src_msd = TME_FIELD_EXTRACTU(src, 4, 4);
                   5951: 
                   5952:   /* perform the operation: */
                   5953:   res_lsd = dst_lsd + src_lsd + ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0);
                   5954:   res_msd = dst_msd + src_msd;
                   5955:   flags = 0;
                   5956:   if (res_lsd > 9) {
                   5957:     res_lsd -= 10;
                   5958:     res_msd += 1;
                   5959:   }
                   5960:   if (res_msd > 9) {
                   5961:     res_msd -= 10;
                   5962:     flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   5963:   }
                   5964:   res = (res_msd << 4) + (res_lsd & 0xf);
                   5965:   if (res == 0) flags |= TME_M68K_FLAG_N;
                   5966: 
                   5967:   /* store the result and set the flags: */
                   5968:   if (memory) {
                   5969:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   5970:       ic->tme_m68k_ireg_memx8 = res;
                   5971:       ic->_tme_m68k_ea_function_code = function_code;
                   5972:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry);
                   5973:       ic->tme_m68k_ireg_ccr = flags;
                   5974:      }
                   5975:      tme_m68k_write_memx8(ic);
                   5976:   }
                   5977:   else {
                   5978:     ic->tme_m68k_ireg_uint8(ry << 2) = res;
                   5979:     ic->tme_m68k_ireg_ccr = flags;
                   5980:   }
                   5981: 
                   5982:   TME_M68K_INSN_OK;
                   5983: }
                   5984: 
                   5985: TME_M68K_INSN(tme_m68k_sbcd)
                   5986: {
                   5987:   tme_uint8_t dst, dst_msd, dst_lsd;
                   5988:   tme_uint8_t src, src_msd, src_lsd;
                   5989:   tme_uint8_t res, res_msd, res_lsd;
                   5990:   tme_uint8_t flags;
                   5991:   int memory;
                   5992:   int rx, ry, function_code;
                   5993: 
                   5994:   /* load the operands: */
                   5995:   rx = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3);
                   5996:   ry = TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 9, 3);
                   5997:   memory = (TME_M68K_INSN_OPCODE & TME_BIT(3)) != 0;
                   5998:   function_code = TME_M68K_FUNCTION_CODE_DATA(ic);
                   5999:   if (memory) {
1.1.1.4   root     6000:     TME_M68K_INSN_CANFAULT;
1.1       root     6001:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     6002:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx) -= sizeof(tme_uint8_t) + ((rx + 1) >> 3);
1.1       root     6003:       ic->_tme_m68k_ea_function_code = function_code;
                   6004:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + rx);
                   6005:     }
                   6006:     tme_m68k_read_memx8(ic);
                   6007:     if (!TME_M68K_SEQUENCE_RESTARTING) {
1.1.1.4   root     6008:       ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry) -= sizeof(tme_uint8_t) + ((ry + 1) >> 3);
1.1       root     6009:       ic->_tme_m68k_ea_function_code = function_code;
                   6010:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry);
                   6011:     }
                   6012:     tme_m68k_read_mem8(ic, TME_M68K_IREG_MEMY32);
                   6013:     src = ic->tme_m68k_ireg_memx8;
                   6014:     dst = ic->tme_m68k_ireg_memy8;
                   6015:   }
                   6016:   else {
                   6017:     src = ic->tme_m68k_ireg_uint8(rx << 2);
                   6018:     dst = ic->tme_m68k_ireg_uint8(ry << 2);
                   6019:   }
                   6020:   dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4);
                   6021:   dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4);
                   6022:   src_lsd = TME_FIELD_EXTRACTU(src, 0, 4);
                   6023:   src_msd = TME_FIELD_EXTRACTU(src, 4, 4);
                   6024: 
                   6025:   /* perform the operation: */
                   6026:   res_lsd = dst_lsd - src_lsd - ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0);
                   6027:   res_msd = dst_msd - src_msd;
                   6028:   flags = 0;
                   6029:   if (res_lsd > 9) {
                   6030:     res_lsd += 10;
                   6031:     res_msd -= 1;
                   6032:   }
                   6033:   if (res_msd > 9) {
                   6034:     res_msd += 10;
                   6035:     flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   6036:   }
                   6037:   res = (res_msd << 4) + (res_lsd & 0xf);
                   6038:   if (res == 0) flags |= TME_M68K_FLAG_N;
                   6039: 
                   6040:   /* store the result and set the flags: */
                   6041:   if (memory) {
                   6042:     if (!TME_M68K_SEQUENCE_RESTARTING) {
                   6043:       ic->tme_m68k_ireg_memx8 = res;
                   6044:       ic->_tme_m68k_ea_function_code = function_code;
                   6045:       ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_uint32(TME_M68K_IREG_A0 + ry);
                   6046:       ic->tme_m68k_ireg_ccr = flags;
                   6047:      }
                   6048:      tme_m68k_write_memx8(ic);
                   6049:   }
                   6050:   else {
                   6051:     ic->tme_m68k_ireg_uint8(ry << 2) = res;
                   6052:     ic->tme_m68k_ireg_ccr = flags;
                   6053:   }
                   6054: 
                   6055:   TME_M68K_INSN_OK;
                   6056: }
                   6057: 
                   6058: TME_M68K_INSN(tme_m68k_nbcd)
                   6059: {
                   6060:   tme_uint8_t dst, dst_msd, dst_lsd;
                   6061:   tme_uint8_t src, src_msd, src_lsd;
                   6062:   tme_uint8_t res, res_msd, res_lsd;
                   6063:   tme_uint8_t flags;
                   6064: 
                   6065:   dst = 0x00;
                   6066:   src = TME_M68K_INSN_OP1(tme_uint8_t);
                   6067:   dst_lsd = TME_FIELD_EXTRACTU(dst, 0, 4);
                   6068:   dst_msd = TME_FIELD_EXTRACTU(dst, 4, 4);
                   6069:   src_lsd = TME_FIELD_EXTRACTU(src, 0, 4);
                   6070:   src_msd = TME_FIELD_EXTRACTU(src, 4, 4);
                   6071: 
                   6072:   /* perform the operation: */
                   6073:   res_lsd = dst_lsd - src_lsd - ((ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X) != 0);
                   6074:   res_msd = dst_msd - src_msd;
                   6075:   flags = 0;
                   6076:   if (res_lsd > 9) {
                   6077:     res_lsd += 10;
                   6078:     res_msd -= 1;
                   6079:   }
                   6080:   if (res_msd > 9) {
                   6081:     res_msd += 10;
                   6082:     flags |= TME_M68K_FLAG_C | TME_M68K_FLAG_X;
                   6083:   }
                   6084:   res = (res_msd << 4) + (res_lsd & 0xf);
                   6085:   if (res == 0) flags |= TME_M68K_FLAG_N;
                   6086: 
                   6087:   /* store the result and set the flags: */
                   6088:   TME_M68K_INSN_OP1(tme_uint8_t) = res;
                   6089:   ic->tme_m68k_ireg_ccr = flags;
                   6090: 
                   6091:   TME_M68K_INSN_OK;
                   6092: }
                   6093: 
                   6094: TME_M68K_INSN(tme_m68k_ori_ccr)
                   6095: {
                   6096:   tme_uint8_t reg;
                   6097:   reg = ic->tme_m68k_ireg_ccr | (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR);
                   6098:   ic->tme_m68k_ireg_ccr = reg;
                   6099:   TME_M68K_INSN_OK;
                   6100: }
                   6101: 
                   6102: TME_M68K_INSN(tme_m68k_andi_ccr)
                   6103: {
                   6104:   tme_uint8_t reg;
                   6105:   reg = ic->tme_m68k_ireg_ccr & (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR);
                   6106:   ic->tme_m68k_ireg_ccr = reg;
                   6107:   TME_M68K_INSN_OK;
                   6108: }
                   6109: 
                   6110: TME_M68K_INSN(tme_m68k_eori_ccr)
                   6111: {
                   6112:   tme_uint8_t reg;
                   6113:   reg = ic->tme_m68k_ireg_ccr ^ (TME_M68K_INSN_OP0(tme_uint8_t) & TME_M68K_FLAG_CCR);
                   6114:   ic->tme_m68k_ireg_ccr = reg;
                   6115:   TME_M68K_INSN_OK;
                   6116: }
                   6117: 
                   6118: TME_M68K_INSN(tme_m68k_move_to_ccr)
                   6119: {
                   6120:   tme_uint8_t reg;
                   6121:   reg = (TME_M68K_INSN_OP1(tme_uint16_t) & TME_M68K_FLAG_CCR);
                   6122:   ic->tme_m68k_ireg_ccr = reg;
                   6123:   TME_M68K_INSN_OK;
                   6124: }
                   6125: 
                   6126: TME_M68K_INSN(tme_m68k_ori_sr)
                   6127: {
                   6128:   tme_uint16_t reg;
                   6129:   reg = ic->tme_m68k_ireg_sr | (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR);
                   6130:   TME_M68K_INSN_PRIV;
                   6131:   TME_M68K_INSN_CHANGE_SR(reg);
                   6132:   TME_M68K_INSN_OK;
                   6133: }
                   6134: 
                   6135: TME_M68K_INSN(tme_m68k_andi_sr)
                   6136: {
                   6137:   tme_uint16_t reg;
                   6138:   reg = ic->tme_m68k_ireg_sr & (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR);
                   6139:   TME_M68K_INSN_PRIV;
                   6140:   TME_M68K_INSN_CHANGE_SR(reg);
                   6141:   TME_M68K_INSN_OK;
                   6142: }
                   6143: 
                   6144: TME_M68K_INSN(tme_m68k_eori_sr)
                   6145: {
                   6146:   tme_uint16_t reg;
                   6147:   reg = ic->tme_m68k_ireg_sr ^ (TME_M68K_INSN_OP0(tme_uint16_t) & TME_M68K_FLAG_SR);
                   6148:   TME_M68K_INSN_PRIV;
                   6149:   TME_M68K_INSN_CHANGE_SR(reg);
                   6150:   TME_M68K_INSN_OK;
                   6151: }
                   6152: 
                   6153: TME_M68K_INSN(tme_m68k_move_to_sr)
                   6154: {
                   6155:   tme_uint16_t reg;
                   6156:   reg = (TME_M68K_INSN_OP1(tme_uint16_t) & TME_M68K_FLAG_SR);
                   6157:   TME_M68K_INSN_PRIV;
                   6158:   TME_M68K_INSN_CHANGE_SR(reg);
                   6159:   TME_M68K_INSN_OK;
                   6160: }
                   6161: 
                   6162: TME_M68K_INSN(tme_m68k_mulu)
                   6163: {
                   6164:   int ireg_dl;
                   6165:   tme_uint32_t res;
                   6166:   tme_uint8_t flags;
                   6167: 
                   6168:   /* get the register containing the factor: */
                   6169:   ireg_dl = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t);
                   6170: 
                   6171:   /* perform the multiplication: */
                   6172:   res = (((tme_uint32_t) ic->tme_m68k_ireg_uint16(ireg_dl << 1))
                   6173:          * TME_M68K_INSN_OP1(tme_uint16_t));
                   6174: 
                   6175:   /* store the result: */
                   6176:   ic->tme_m68k_ireg_uint32(ireg_dl) = (tme_uint32_t) res;
                   6177: 
                   6178:   /* set the flags: */
                   6179:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   6180:   if (((tme_int32_t) res) < 0) flags |= TME_M68K_FLAG_N;
                   6181:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   6182:   ic->tme_m68k_ireg_ccr = flags;
                   6183: 
                   6184:   TME_M68K_INSN_OK;
                   6185: }
                   6186: 
                   6187: TME_M68K_INSN(tme_m68k_divu)
                   6188: {
                   6189:   int ireg_dq;
                   6190:   tme_uint32_t dividend, quotient;
                   6191:   tme_uint16_t divisor, remainder;
                   6192:   tme_uint8_t flags;
                   6193: 
                   6194:   /* get the register(s): */
                   6195:   ireg_dq = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t);
                   6196: 
                   6197:   /* form the dividend and the divisor: */
                   6198:   dividend = (tme_uint32_t) ic->tme_m68k_ireg_uint32(ireg_dq);
                   6199:   divisor = TME_M68K_INSN_OP1(tme_uint16_t);
                   6200:   if (divisor == 0) {
1.1.1.3   root     6201:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root     6202:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3   root     6203:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0));
1.1       root     6204:   }
                   6205: 
                   6206:   /* do the division: */
                   6207:   quotient = dividend / divisor;
                   6208:   remainder = dividend % divisor;
                   6209: 
                   6210:   /* set the flags and return the quotient and remainder: */
                   6211:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   6212:   if (quotient > 0xffff) {
                   6213:     flags |= TME_M68K_FLAG_V;
                   6214:   }
                   6215:   else {
                   6216:     if (((tme_int16_t) quotient) < 0) flags |= TME_M68K_FLAG_N;
                   6217:     if (quotient == 0) flags |= TME_M68K_FLAG_Z;
                   6218:     ic->tme_m68k_ireg_uint16(ireg_dq << 1) = (tme_uint16_t) quotient;
                   6219:     ic->tme_m68k_ireg_uint16((ireg_dq << 1) + 1) = remainder;
                   6220:   }
                   6221:   ic->tme_m68k_ireg_ccr = flags;
                   6222: 
                   6223:   TME_M68K_INSN_OK;
                   6224: }
                   6225: 
                   6226: TME_M68K_INSN(tme_m68k_mulul)
                   6227: {
1.1.1.2   root     6228: #ifndef TME_HAVE_INT64_T
1.1       root     6229:   abort();
1.1.1.2   root     6230: #else /* TME_HAVE_INT64_T */
1.1       root     6231:   unsigned int flag_v;
                   6232:   int ireg_dh;
                   6233:   int ireg_dl;
                   6234:   tme_uint64_t res;
                   6235:   tme_uint8_t flags;
                   6236: 
                   6237:   /* get the register containing the factor: */
                   6238:   ireg_dl = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3);
                   6239: 
                   6240:   /* perform the multiplication: */
                   6241:   res = (((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dl))
                   6242:          * TME_M68K_INSN_OP1(tme_uint32_t));
                   6243: 
                   6244:   /* store the result: */
                   6245:   ic->tme_m68k_ireg_uint32(ireg_dl) = (tme_uint32_t) res;
                   6246:   flag_v = TME_M68K_FLAG_V;
                   6247:   if (TME_M68K_INSN_SPECOP & TME_BIT(10)) {
                   6248:     flag_v = 0;
                   6249:     ireg_dh = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
                   6250:     ic->tme_m68k_ireg_uint32(ireg_dh) = (tme_uint32_t) (res >> 32);
                   6251:   }
                   6252: 
                   6253:   /* set the flags: */
                   6254:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   6255:   if (((tme_int64_t) res) < 0) flags |= TME_M68K_FLAG_N;
                   6256:   if (res == 0) flags |= TME_M68K_FLAG_Z;
1.1.1.2   root     6257:   if (res > 0xffffffffUL) flags |= flag_v;
1.1       root     6258:   ic->tme_m68k_ireg_ccr = flags;
                   6259: 
                   6260:   TME_M68K_INSN_OK;
1.1.1.2   root     6261: #endif /* TME_HAVE_INT64_T */
1.1       root     6262: }
                   6263: 
                   6264: TME_M68K_INSN(tme_m68k_divul)
                   6265: {
1.1.1.2   root     6266: #ifndef TME_HAVE_INT64_T
1.1       root     6267:   abort();
1.1.1.2   root     6268: #else /* TME_HAVE_INT64_T */
1.1       root     6269:   int ireg_dr;
                   6270:   int ireg_dq;
                   6271:   tme_uint64_t dividend, quotient;
                   6272:   tme_uint32_t divisor, remainder;
                   6273:   tme_uint8_t flags;
                   6274: 
                   6275:   /* get the register(s): */
                   6276:   ireg_dq = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3);
                   6277:   ireg_dr = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
                   6278: 
                   6279:   /* form the dividend and the divisor: */
                   6280:   if (TME_M68K_INSN_SPECOP & TME_BIT(10)) {
                   6281:     dividend = (tme_uint64_t)
                   6282:                ((((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dr)) << 32)
                   6283:                 | ic->tme_m68k_ireg_uint32(ireg_dq));
                   6284:   }
                   6285:   else
                   6286:     dividend = (tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dq);
                   6287:   divisor = TME_M68K_INSN_OP1(tme_uint32_t);
                   6288:   if (divisor == 0) {
1.1.1.3   root     6289:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root     6290:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3   root     6291:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0));
1.1       root     6292:   }
                   6293: 
                   6294:   /* do the division: */
                   6295:   quotient = dividend / divisor;
                   6296:   remainder = dividend % divisor;
                   6297: 
                   6298:   /* set the flags and return the quotient and remainder: */
                   6299:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
1.1.1.2   root     6300:   if (quotient > 0xffffffffUL) {
1.1       root     6301:     flags |= TME_M68K_FLAG_V;
                   6302:   }
                   6303:   else {
                   6304:     if (((tme_int32_t) quotient) < 0) flags |= TME_M68K_FLAG_N;
                   6305:     if (quotient == 0) flags |= TME_M68K_FLAG_Z;
                   6306:     ic->tme_m68k_ireg_uint32(ireg_dq) = (tme_uint32_t) quotient;
                   6307:     if (ireg_dr != ireg_dq) {
                   6308:       ic->tme_m68k_ireg_uint32(ireg_dr) = remainder;
                   6309:     }
                   6310:   }
                   6311:   ic->tme_m68k_ireg_ccr = flags;
                   6312: 
                   6313:   TME_M68K_INSN_OK;
1.1.1.2   root     6314: #endif /* TME_HAVE_INT64_T */
1.1       root     6315: }
                   6316: 
                   6317: TME_M68K_INSN(tme_m68k_muls)
                   6318: {
                   6319:   int ireg_dl;
                   6320:   tme_int32_t res;
                   6321:   tme_uint8_t flags;
                   6322: 
                   6323:   /* get the register containing the factor: */
                   6324:   ireg_dl = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t);
                   6325: 
                   6326:   /* perform the multiplication: */
                   6327:   res = (((tme_int32_t) ic->tme_m68k_ireg_int16(ireg_dl << 1))
                   6328:          * TME_M68K_INSN_OP1(tme_int16_t));
                   6329: 
                   6330:   /* store the result: */
                   6331:   ic->tme_m68k_ireg_int32(ireg_dl) = (tme_int32_t) res;
                   6332: 
                   6333:   /* set the flags: */
                   6334:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   6335:   if (((tme_int32_t) res) < 0) flags |= TME_M68K_FLAG_N;
                   6336:   if (res == 0) flags |= TME_M68K_FLAG_Z;
                   6337:   ic->tme_m68k_ireg_ccr = flags;
                   6338: 
                   6339:   TME_M68K_INSN_OK;
                   6340: }
                   6341: 
                   6342: TME_M68K_INSN(tme_m68k_divs)
                   6343: {
                   6344:   int ireg_dq;
                   6345:   tme_int32_t dividend, quotient;
                   6346:   tme_int16_t divisor, remainder;
                   6347:   tme_uint8_t flags;
                   6348: 
                   6349:   /* get the register(s): */
                   6350:   ireg_dq = TME_M68K_IREG_D0 + TME_M68K_INSN_OP0(tme_uint32_t);
                   6351: 
                   6352:   /* form the dividend and the divisor: */
                   6353:   dividend = (tme_int32_t) ic->tme_m68k_ireg_int32(ireg_dq);
                   6354:   divisor = TME_M68K_INSN_OP1(tme_int16_t);
                   6355:   if (divisor == 0) {
1.1.1.3   root     6356:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root     6357:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3   root     6358:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0));
1.1       root     6359:   }
                   6360: 
                   6361:   /* do the division: */
                   6362:   quotient = dividend / divisor;
                   6363:   remainder = dividend % divisor;
                   6364: 
                   6365:   /* set the flags and return the quotient and remainder: */
                   6366:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
1.1.1.2   root     6367:   if (quotient > 0x7fff || quotient < -32768) {
1.1       root     6368:     flags |= TME_M68K_FLAG_V;
                   6369:   }
                   6370:   else {
                   6371:     if (((tme_int16_t) quotient) < 0) flags |= TME_M68K_FLAG_N;
                   6372:     if (quotient == 0) flags |= TME_M68K_FLAG_Z;
                   6373:     ic->tme_m68k_ireg_int16(ireg_dq << 1) = (tme_int16_t) quotient;
                   6374:     ic->tme_m68k_ireg_int16((ireg_dq << 1) + 1) = remainder;
                   6375:   }
                   6376:   ic->tme_m68k_ireg_ccr = flags;
                   6377: 
                   6378:   TME_M68K_INSN_OK;
                   6379: }
                   6380: 
                   6381: TME_M68K_INSN(tme_m68k_mulsl)
                   6382: {
1.1.1.2   root     6383: #ifndef TME_HAVE_INT64_T
1.1       root     6384:   abort();
1.1.1.2   root     6385: #else /* TME_HAVE_INT64_T */
1.1       root     6386:   unsigned int flag_v;
                   6387:   int ireg_dh;
                   6388:   int ireg_dl;
                   6389:   tme_int64_t res;
                   6390:   tme_uint8_t flags;
                   6391: 
                   6392:   /* get the register containing the factor: */
                   6393:   ireg_dl = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3);
                   6394: 
                   6395:   /* perform the multiplication: */
                   6396:   res = (((tme_int64_t) ic->tme_m68k_ireg_int32(ireg_dl))
                   6397:          * TME_M68K_INSN_OP1(tme_int32_t));
                   6398: 
                   6399:   /* store the result: */
                   6400:   ic->tme_m68k_ireg_int32(ireg_dl) = (tme_int32_t) res;
                   6401:   flag_v = TME_M68K_FLAG_V;
                   6402:   if (TME_M68K_INSN_SPECOP & TME_BIT(10)) {
                   6403:     flag_v = 0;
                   6404:     ireg_dh = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
                   6405:     ic->tme_m68k_ireg_int32(ireg_dh) = (tme_int32_t) (res >> 32);
                   6406:   }
                   6407: 
                   6408:   /* set the flags: */
                   6409:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
                   6410:   if (((tme_int64_t) res) < 0) flags |= TME_M68K_FLAG_N;
                   6411:   if (res == 0) flags |= TME_M68K_FLAG_Z;
1.1.1.2   root     6412:   if (res > 0x7fffffffL || res < ((0L - 0x7fffffffL) - 1L)) flags |= flag_v;
1.1       root     6413:   ic->tme_m68k_ireg_ccr = flags;
                   6414: 
                   6415:   TME_M68K_INSN_OK;
1.1.1.2   root     6416: #endif /* TME_HAVE_INT64_T */
1.1       root     6417: }
                   6418: 
                   6419: TME_M68K_INSN(tme_m68k_divsl)
                   6420: {
1.1.1.2   root     6421: #ifndef TME_HAVE_INT64_T
1.1       root     6422:   abort();
1.1.1.2   root     6423: #else /* TME_HAVE_INT64_T */
1.1       root     6424:   int ireg_dr;
                   6425:   int ireg_dq;
                   6426:   tme_int64_t dividend, quotient;
                   6427:   tme_int32_t divisor, remainder;
                   6428:   tme_uint8_t flags;
                   6429: 
                   6430:   /* get the register(s): */
                   6431:   ireg_dq = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 3);
                   6432:   ireg_dr = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 0, 3);
                   6433: 
                   6434:   /* form the dividend and the divisor: */
                   6435:   if (TME_M68K_INSN_SPECOP & TME_BIT(10)) {
                   6436:     dividend = (tme_int64_t)
                   6437:                ((((tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dr)) << 32)
                   6438:                 | ic->tme_m68k_ireg_uint32(ireg_dq));
                   6439:   }
                   6440:   else
                   6441:     dividend = (tme_int64_t) ic->tme_m68k_ireg_int32(ireg_dq);
                   6442:   divisor = TME_M68K_INSN_OP1(tme_int32_t);
                   6443:   if (divisor == 0) {
1.1.1.3   root     6444:     ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc;
1.1       root     6445:     ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next;
1.1.1.3   root     6446:     TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0));
1.1       root     6447:   }
                   6448: 
                   6449:   /* do the division: */
                   6450:   quotient = dividend / divisor;
                   6451:   remainder = dividend % divisor;
                   6452: 
                   6453:   /* set the flags and return the quotient and remainder: */
                   6454:   flags = ic->tme_m68k_ireg_ccr & TME_M68K_FLAG_X;
1.1.1.2   root     6455:   if (quotient > 0x7fffffffL || quotient < ((0L - 0x7fffffffL) - 1L)) {
1.1       root     6456:     flags |= TME_M68K_FLAG_V;
                   6457:   }
                   6458:   else {
                   6459:     if (((tme_int32_t) quotient) < 0) flags |= TME_M68K_FLAG_N;
                   6460:     if (quotient == 0) flags |= TME_M68K_FLAG_Z;
                   6461:     ic->tme_m68k_ireg_int32(ireg_dq) = (tme_int32_t) quotient;
                   6462:     if (ireg_dr != ireg_dq) {
                   6463:       ic->tme_m68k_ireg_int32(ireg_dr) = remainder;
                   6464:     }
                   6465:   }
                   6466:   ic->tme_m68k_ireg_ccr = flags;
                   6467: 
                   6468:   TME_M68K_INSN_OK;
1.1.1.2   root     6469: #endif /* TME_HAVE_INT64_T */
1.1       root     6470: }
                   6471: /* automatically generated by m68k-misc-auto.sh, do not edit! */
                   6472: 
                   6473: /* the flags->conditions mapping: */
                   6474: const tme_uint16_t _tme_m68k_conditions[32] = {
                   6475: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
                   6476: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
                   6477: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6478: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6479: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
                   6480: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
                   6481: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6482: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6483: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6484: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6485: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
                   6486: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
                   6487: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6488: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6489: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
                   6490: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
                   6491: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
                   6492: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
                   6493: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6494: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6495: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
                   6496: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
                   6497: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6498: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_PL) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6499: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6500: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6501: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_HI) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
                   6502: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_NE) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_GT),
                   6503: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6504: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VC) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_LT) | TME_BIT(TME_M68K_C_LE),
                   6505: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CC) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
                   6506: TME_BIT(TME_M68K_C_T) | TME_BIT(TME_M68K_C_LS) | TME_BIT(TME_M68K_C_CS) | TME_BIT(TME_M68K_C_EQ) | TME_BIT(TME_M68K_C_VS) | TME_BIT(TME_M68K_C_MI) | TME_BIT(TME_M68K_C_GE) | TME_BIT(TME_M68K_C_LE),
                   6507: };

unix.superglobalmegacorp.com

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