Annotation of tme/ic/m68k/m68010.c, revision 1.1

1.1     ! root        1: /* $Id: m68010.c,v 1.5 2003/05/16 21:48:10 fredette Exp $ */
        !             2: 
        !             3: /* ic/m68k/m68010.c - implementation of Motorola 68010 emulation: */
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 2002, 2003 Matt Fredette
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. All advertising materials mentioning features or use of this software
        !            18:  *    must display the following acknowledgement:
        !            19:  *      This product includes software developed by Matt Fredette.
        !            20:  * 4. The name of the author may not be used to endorse or promote products
        !            21:  *    derived from this software without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            33:  * POSSIBILITY OF SUCH DAMAGE.
        !            34:  */
        !            35: 
        !            36: #include <tme/common.h>
        !            37: _TME_RCSID("$Id: m68010.c,v 1.5 2003/05/16 21:48:10 fredette Exp $");
        !            38: 
        !            39: /* includes: */
        !            40: #include "m68k-impl.h"
        !            41: 
        !            42: /* macros: */
        !            43: #define TME_M68K_SSW8_RR         0x8000  
        !            44: #define TME_M68K_SSW8_IF         0x2000
        !            45: #define TME_M68K_SSW8_DF         0x1000
        !            46: #define TME_M68K_SSW8_RM         0x0800  
        !            47: #define TME_M68K_SSW8_HI         0x0400
        !            48: #define TME_M68K_SSW8_BX         0x0200  
        !            49: #define TME_M68K_SSW8_RW         0x0100
        !            50: 
        !            51: /* structures: */
        !            52: 
        !            53: /* the format 8 stack frame: */
        !            54: /* XXX we assume that this will pack: */
        !            55: struct tme_m68k_fmt8 {
        !            56: 
        !            57:   /* the special status word: */
        !            58:   tme_uint16_t tme_m68k_fmt8_ssw;
        !            59: 
        !            60:   /* the faulting address: */
        !            61:   tme_uint16_t tme_m68k_fmt8_addr_high;
        !            62:   tme_uint16_t tme_m68k_fmt8_addr_low;
        !            63: 
        !            64:   /* the first unused word: */
        !            65:   tme_uint8_t tme_m68k_fmt8_state0[2];
        !            66: 
        !            67:   /* the data output buffer: */
        !            68:   tme_uint8_t tme_m68k_fmt8_dob[2];
        !            69: 
        !            70:   /* the second unused word: */
        !            71:   tme_uint8_t tme_m68k_fmt8_state1[2];
        !            72: 
        !            73:   /* the data input buffer: */
        !            74:   tme_uint8_t tme_m68k_fmt8_dib[2];
        !            75: 
        !            76:   /* the third unused word: */
        !            77:   tme_uint8_t tme_m68k_fmt8_state2[2];
        !            78: 
        !            79:   /* the instruction input buffer: */
        !            80:   tme_uint8_t tme_m68k_fmt8_iib[2];
        !            81: 
        !            82:   /* the internal information: */
        !            83:   tme_uint8_t tme_m68k_fmt8_state3[32];
        !            84: };
        !            85: 
        !            86: /* both executors are for the 68010: */
        !            87: #define _TME_M68K_EXECUTE_CPU TME_M68K_M68010
        !            88: 
        !            89: /* create the slow executor: */
        !            90: #define _TME_M68K_EXECUTE_NAME _tme_m68010_execute_slow
        !            91: #undef _TME_M68K_EXECUTE_FAST
        !            92: #undef _TME_M68K_EXECUTE_SLOW
        !            93: #include "m68k-execute.c"
        !            94: #undef _TME_M68K_EXECUTE_NAME
        !            95: #undef _TME_M68K_EXECUTE_FAST
        !            96: #undef _TME_M68K_EXECUTE_SLOW
        !            97: 
        !            98: /* create the fast executor: */
        !            99: #define _TME_M68K_EXECUTE_NAME _tme_m68010_execute
        !           100: #define _TME_M68K_EXECUTE_FAST
        !           101: #define _TME_M68K_EXECUTE_SLOW _tme_m68010_execute_slow
        !           102: #include "m68k-execute.c"
        !           103: #undef _TME_M68K_EXECUTE_NAME
        !           104: #undef _TME_M68K_EXECUTE_FAST
        !           105: #undef _TME_M68K_EXECUTE_SLOW
        !           106: 
        !           107: #undef _TME_M68K_EXECUTE_CPU
        !           108: 
        !           109: /* m68010 exception processing: */
        !           110: static void
        !           111: _tme_m68010_exception(struct tme_m68k *ic)
        !           112: {
        !           113:   tme_uint32_t exceptions;
        !           114:   tme_uint8_t raw_state[19 * sizeof(tme_uint16_t)], *raw;
        !           115:   unsigned int raw_avail, raw_used;
        !           116:   struct tme_m68k_fmt8 fmt8;
        !           117:   unsigned int flags;
        !           118:   tme_uint8_t function_code;
        !           119:   tme_uint16_t ssw;
        !           120: 
        !           121:   /* get the set of exceptions: */
        !           122:   exceptions = ic->_tme_m68k_exceptions;
        !           123: 
        !           124:   /* a reset exception: */
        !           125:   if (exceptions & TME_M68K_EXCEPTION_GROUP0_RESET) {
        !           126: 
        !           127:     /* do the common reset processing: */
        !           128:     tme_m68k_do_reset(ic);
        !           129:     /* NOTREACHED */
        !           130:   }
        !           131: 
        !           132:   /* an address or bus error: */
        !           133:   else if (exceptions & (TME_M68K_EXCEPTION_GROUP0_AERR
        !           134:                         | TME_M68K_EXCEPTION_GROUP0_BERR)) {
        !           135: 
        !           136:     /* start the exception processing: */
        !           137:     tme_m68k_exception_process_start(ic, 0);
        !           138: 
        !           139:     /* start assembling the raw data: */
        !           140:     raw = raw_state;
        !           141:     raw_avail = sizeof(raw_state);
        !           142: #define RAW_PUT(v)                     \
        !           143: do {                                   \
        !           144:   assert(raw_avail >= sizeof(v));      \
        !           145:   memcpy(raw, &v, sizeof(v));          \
        !           146:   raw += sizeof(v);                    \
        !           147:   raw_avail -= sizeof(v);              \
        !           148: } while (/* CONSTCOND */ 0)
        !           149: 
        !           150:     /* put in the sequence: */
        !           151:     raw_used = tme_m68k_sequence_empty(ic, raw, raw_avail);
        !           152:     raw += raw_used;
        !           153:     raw_avail -= raw_used;
        !           154: 
        !           155:     /* dispatch on the mode: */
        !           156:     switch (ic->_tme_m68k_group0_sequence._tme_m68k_sequence_mode) {
        !           157: 
        !           158:     case TME_M68K_MODE_EXECUTION:
        !           159:       
        !           160:       /* put in the instruction buffer: */
        !           161:       raw_used = tme_m68k_insn_buffer_empty(ic, raw, raw_avail);
        !           162:       raw += raw_used;
        !           163:       raw_avail -= raw_used;
        !           164: 
        !           165:       /* put in the EA address: */
        !           166:       function_code = ic->_tme_m68k_ea_function_code;
        !           167:       RAW_PUT(function_code);
        !           168:       RAW_PUT(ic->_tme_m68k_ea_address);
        !           169: 
        !           170:       /* put in the memory X and Y buffers: */
        !           171:       RAW_PUT(ic->tme_m68k_ireg_memx32);
        !           172:       RAW_PUT(ic->tme_m68k_ireg_memy32);
        !           173:       
        !           174:       /* done: */
        !           175:       break;
        !           176: 
        !           177:     case TME_M68K_MODE_EXCEPTION:
        !           178: 
        !           179:       /* put in the exceptions set: */
        !           180:       RAW_PUT(ic->_tme_m68k_exceptions);
        !           181: 
        !           182:       /* put in the shadow status register: */
        !           183:       RAW_PUT(ic->tme_m68k_ireg_shadow_sr);
        !           184:       
        !           185:       /* done: */
        !           186:       break;
        !           187: 
        !           188:     case TME_M68K_MODE_RTE:
        !           189:       
        !           190:       /* put in the shadow status register: */
        !           191:       RAW_PUT(ic->tme_m68k_ireg_shadow_sr);
        !           192: 
        !           193:       /* put in the next program counter: */
        !           194:       RAW_PUT(ic->tme_m68k_ireg_pc_next);
        !           195: 
        !           196:       /* put in the format/offset word: */
        !           197:       RAW_PUT(ic->tme_m68k_ireg_format_offset);
        !           198: 
        !           199:       break;
        !           200: 
        !           201:     default: abort();
        !           202:     }
        !           203: 
        !           204:     /* put in the internal state: */
        !           205:     raw_avail = raw - raw_state;
        !           206:     raw = raw_state;
        !           207: #undef RAW_PUT
        !           208: #define RAW_PUT(f)                             \
        !           209: do {                                           \
        !           210:     raw_used = TME_MIN(sizeof(f), raw_avail);  \
        !           211:     memcpy(f, raw, raw_used);                  \
        !           212:     raw += raw_used;                           \
        !           213:     raw_avail -= raw_used;                     \
        !           214: } while (/* CONSTCOND */ 0)
        !           215: 
        !           216:     /* use all of the reserved regions: */
        !           217:     RAW_PUT(fmt8.tme_m68k_fmt8_state0);
        !           218:     RAW_PUT(fmt8.tme_m68k_fmt8_state1);
        !           219:     RAW_PUT(fmt8.tme_m68k_fmt8_state2);
        !           220:     RAW_PUT(fmt8.tme_m68k_fmt8_state3);
        !           221: #undef RAW_PUT
        !           222: 
        !           223:     /* put in the special status word and the data output buffer: */
        !           224:     ssw = 0;
        !           225:     flags = ic->_tme_m68k_group0_flags;
        !           226:     if (flags & TME_M68K_BUS_CYCLE_READ) {
        !           227:       ssw |= (TME_M68K_SSW8_RW
        !           228:              | ((flags & TME_M68K_BUS_CYCLE_FETCH)
        !           229:                 ? TME_M68K_SSW8_IF
        !           230:                 : TME_M68K_SSW8_DF));
        !           231:       assert(ic->_tme_m68k_group0_buffer_read_size <= sizeof(tme_uint16_t));
        !           232:       if (ic->_tme_m68k_group0_buffer_read_size == sizeof(tme_uint8_t)) {
        !           233:        ssw |= TME_M68K_SSW8_BX;
        !           234:       }
        !           235:     }
        !           236:     else {
        !           237:       assert(ic->_tme_m68k_group0_buffer_write_size <= sizeof(tme_uint16_t));
        !           238:       if (ic->_tme_m68k_group0_buffer_write_size == sizeof(tme_uint8_t)) {
        !           239:        ssw |= TME_M68K_SSW8_BX;
        !           240:       }
        !           241:       memcpy(fmt8.tme_m68k_fmt8_dob
        !           242:             + sizeof(fmt8.tme_m68k_fmt8_dob)
        !           243:             - ic->_tme_m68k_group0_buffer_write_size,
        !           244:             ic->_tme_m68k_group0_buffer_write,
        !           245:             ic->_tme_m68k_group0_buffer_write_size);
        !           246:     }
        !           247:     if (flags & TME_M68K_BUS_CYCLE_RMW) {
        !           248:       ssw |= TME_M68K_SSW8_RM;
        !           249:     }
        !           250:     ssw |= ic->_tme_m68k_group0_function_code;
        !           251:     fmt8.tme_m68k_fmt8_ssw = tme_htobe_u16(ssw);
        !           252: 
        !           253:     /* put in the fault address: */
        !           254:     fmt8.tme_m68k_fmt8_addr_high = tme_htobe_u16(ic->_tme_m68k_group0_address >> 16);
        !           255:     fmt8.tme_m68k_fmt8_addr_low = tme_htobe_u16(ic->_tme_m68k_group0_address & 0xffff);
        !           256: 
        !           257:     /* push the format 8 contents.  we don't need to worry about
        !           258:        restarting here, because any fault is a double fault: */
        !           259:     ic->tme_m68k_ireg_a7 -= sizeof(fmt8);
        !           260:     ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_a7;
        !           261:     ic->_tme_m68k_ea_function_code = TME_M68K_FC_SD; /* XXX right? */
        !           262:     tme_m68k_write_mem(ic, (tme_uint8_t *) &fmt8, sizeof(fmt8));
        !           263: 
        !           264:     /* now finish the processing for this exception: */
        !           265:     tme_m68k_exception_process_finish(ic, TME_M68K_FORMAT_8, 
        !           266:                                      ((exceptions & TME_M68K_EXCEPTION_GROUP0_BERR)
        !           267:                                       ? 2
        !           268:                                       : 3));
        !           269:     ic->_tme_m68k_exceptions = (exceptions &= ~ (TME_M68K_EXCEPTION_GROUP0_AERR
        !           270:                                                 | TME_M68K_EXCEPTION_GROUP0_BERR));
        !           271:   }
        !           272: 
        !           273:   /* do normal exception processing: */
        !           274:   tme_m68k_exception_process(ic);
        !           275:   /* NOTREACHED */
        !           276: }
        !           277: 
        !           278: /* m68010 RTE processing: */
        !           279: static void
        !           280: _tme_m68010_rte(struct tme_m68k *ic)
        !           281: {
        !           282:   tme_uint16_t format;
        !           283:   struct tme_m68k_fmt8 fmt8;
        !           284:   tme_uint32_t fmt8_address;
        !           285:   tme_uint8_t raw_state[19 * sizeof(tme_uint16_t)], *raw;
        !           286:   unsigned int raw_avail, raw_used;
        !           287:   tme_uint8_t function_code;
        !           288:   tme_uint16_t ssw;
        !           289:   unsigned int flags;
        !           290:   tme_uint8_t *ib;
        !           291:   unsigned int buffer_size;
        !           292: 
        !           293:   /* start the RTE: */
        !           294:   format = tme_m68k_rte_start(ic);
        !           295: 
        !           296:   /* if this is a format 0 stack frame, finish it now: */
        !           297:   if (format == TME_M68K_FORMAT_0) {
        !           298:     ic->_tme_m68k_mode = TME_M68K_MODE_EXECUTION;
        !           299:     TME_M68K_SEQUENCE_START;
        !           300:     tme_m68k_rte_finish(ic, 0);
        !           301:     /* NOTREACHED */
        !           302:   }
        !           303: 
        !           304:   /* whenever we detect a format error, begin exception processing
        !           305:      for a format error.  we have to back the PC up by the size of the
        !           306:      RTE instruction so the PC points to it: */
        !           307: #define FORMAT_ERROR_IF(e)                                     \
        !           308: do {                                                           \
        !           309:   if (e) {                                                     \
        !           310:     ic->tme_m68k_ireg_pc -= sizeof(tme_uint16_t);              \
        !           311:     tme_m68k_exception(ic, TME_M68K_EXCEPTION_GROUP2(0xE));    \
        !           312:     /* NOTREACHED */                                           \
        !           313:   }                                                            \
        !           314: } while (/* CONSTCOND */ 0)
        !           315: 
        !           316:   /* this frame must be a format 8 frame: */
        !           317:   FORMAT_ERROR_IF(format != TME_M68K_FORMAT_8);
        !           318: 
        !           319:   /* do a read of the last word in the stack frame to determine
        !           320:      accessibility.  we rely on tme_m68k_rte_start leaving
        !           321:      ic->_tme_m68k_ea_address pointing after the format/offset word: */
        !           322:   fmt8_address = ic->_tme_m68k_ea_address;
        !           323:   ic->_tme_m68k_ea_address += sizeof(fmt8) - sizeof(tme_uint16_t);
        !           324:   tme_m68k_read_memx16(ic);
        !           325: 
        !           326:   /* read in the format 8 information.  if we get a bus error
        !           327:      during this operation it's a double fault: */
        !           328:   assert(ic->_tme_m68k_exceptions == 0);
        !           329:   ic->_tme_m68k_exceptions = TME_M68K_EXCEPTION_GROUP0_BERR;
        !           330:   ic->_tme_m68k_ea_address = fmt8_address;
        !           331:   tme_m68k_read_mem(ic, (tme_uint8_t *) &fmt8, sizeof(fmt8));
        !           332:   ic->_tme_m68k_exceptions = 0;
        !           333: 
        !           334:   /* get out the fault address: */
        !           335:   ic->_tme_m68k_group0_address = ((((tme_uint32_t) tme_betoh_u16(fmt8.tme_m68k_fmt8_addr_high)) << 16)
        !           336:                                  | tme_betoh_u16(fmt8.tme_m68k_fmt8_addr_low));
        !           337:   
        !           338:   /* get out the special status word and either the data/instruction
        !           339:      input buffer or the data output buffer: */
        !           340:   ssw = tme_betoh_u16(fmt8.tme_m68k_fmt8_ssw);
        !           341:   FORMAT_ERROR_IF(ssw & TME_M68K_SSW8_HI);
        !           342:   flags = 0;
        !           343:   ic->_tme_m68k_group0_buffer_read_size = 0;
        !           344:   ic->_tme_m68k_group0_buffer_read_softrr = 0;
        !           345:   ic->_tme_m68k_group0_buffer_write_size = 0;
        !           346:   ic->_tme_m68k_group0_buffer_write_softrr = 0;
        !           347:   buffer_size = ((ssw & TME_M68K_SSW8_BX)
        !           348:                 ? sizeof(tme_uint8_t)
        !           349:                 : sizeof(tme_uint16_t));
        !           350: 
        !           351:   /* if this was a read cycle: */
        !           352:   if (ssw & TME_M68K_SSW8_RW) {
        !           353:     flags |= TME_M68K_BUS_CYCLE_READ;
        !           354: 
        !           355:     /* if this was an instruction fetch cycle: */
        !           356:     if (ssw & TME_M68K_SSW8_IF) {
        !           357:       flags |= TME_M68K_BUS_CYCLE_FETCH;
        !           358:       FORMAT_ERROR_IF(ssw & TME_M68K_SSW8_DF);
        !           359:       ib = fmt8.tme_m68k_fmt8_iib;
        !           360:     }
        !           361: 
        !           362:     /* otherwise, this was a data fetch cycle: */
        !           363:     else {
        !           364:       FORMAT_ERROR_IF((ssw & (TME_M68K_SSW8_IF
        !           365:                              | TME_M68K_SSW8_DF))
        !           366:                      != TME_M68K_SSW8_DF);
        !           367:       ib = fmt8.tme_m68k_fmt8_dib;
        !           368:     }
        !           369: 
        !           370:     /* if the user reran this cycle, read in the appropriate
        !           371:        input buffer: */
        !           372:     if (ssw & TME_M68K_SSW8_RR) {
        !           373:       memcpy(ic->_tme_m68k_group0_buffer_read,
        !           374:             ib + sizeof(tme_uint16_t) - buffer_size,
        !           375:             buffer_size);
        !           376:       ic->_tme_m68k_group0_buffer_read_softrr = buffer_size;
        !           377:       ic->_tme_m68k_group0_buffer_read_size = buffer_size;
        !           378:     }
        !           379:   }
        !           380: 
        !           381:   /* otherwise, this was a write cycle: */
        !           382:   else {
        !           383: 
        !           384:     /* if the user reran this cycle, note that, otherwise
        !           385:        copy in the data output buffer: */
        !           386:     if (ssw & TME_M68K_SSW8_RR) {
        !           387:       ic->_tme_m68k_group0_buffer_write_softrr = buffer_size;
        !           388:     }
        !           389:     else {
        !           390:       memcpy(ic->_tme_m68k_group0_buffer_write,
        !           391:             fmt8.tme_m68k_fmt8_dob + sizeof(tme_uint16_t) - buffer_size,
        !           392:             buffer_size);
        !           393:       ic->_tme_m68k_group0_buffer_write_size = buffer_size;
        !           394:     }
        !           395:   }
        !           396: 
        !           397:   /* get the fault function code and address: */
        !           398:   ic->_tme_m68k_group0_function_code = ssw & TME_M68K_FC_7;
        !           399:   ic->_tme_m68k_group0_address =
        !           400:     ((((tme_uint32_t) tme_betoh_u16(fmt8.tme_m68k_fmt8_addr_high)) << 16)
        !           401:      | tme_betoh_u16(fmt8.tme_m68k_fmt8_addr_low));
        !           402: 
        !           403:   /* get out our internal state: */
        !           404:   raw = raw_state;
        !           405:   raw_avail = sizeof(raw_state);
        !           406: #define RAW_GET(f)                             \
        !           407: do {                                           \
        !           408:     raw_used = TME_MIN(sizeof(f), raw_avail);  \
        !           409:     memcpy(raw, f, raw_used);                  \
        !           410:     raw += raw_used;                           \
        !           411:     raw_avail -= raw_used;                     \
        !           412: } while (/* CONSTCOND */ 0)
        !           413: 
        !           414:   /* use all of the reserved regions: */
        !           415:   RAW_GET(fmt8.tme_m68k_fmt8_state0);
        !           416:   RAW_GET(fmt8.tme_m68k_fmt8_state1);
        !           417:   RAW_GET(fmt8.tme_m68k_fmt8_state2);
        !           418:   RAW_GET(fmt8.tme_m68k_fmt8_state3);
        !           419: #undef RAW_GET
        !           420: 
        !           421:   /* take apart the internal state: */
        !           422:   raw = raw_state;
        !           423:   raw_avail = sizeof(raw_state) - raw_avail;
        !           424: #define RAW_GET(v)                             \
        !           425: do {                                           \
        !           426:   FORMAT_ERROR_IF(raw_avail < sizeof(v));      \
        !           427:   memcpy(&v, raw, sizeof(v));                  \
        !           428:   raw += sizeof(v);                            \
        !           429:   raw_avail -= sizeof(v);                      \
        !           430: } while (/* CONSTCOND */ 0)
        !           431: 
        !           432:   /* get out the sequence: */
        !           433:   raw_used = tme_m68k_sequence_fill(ic, raw, raw_avail);
        !           434:   FORMAT_ERROR_IF(raw_used < 0);
        !           435:   raw += raw_used;
        !           436:   raw_avail -= raw_used;
        !           437:   
        !           438:   /* dispatch on the mode: */
        !           439:   switch (ic->_tme_m68k_group0_sequence._tme_m68k_sequence_mode) {
        !           440:     
        !           441:   case TME_M68K_MODE_EXECUTION:
        !           442:     
        !           443:     /* get out the instruction buffer: */
        !           444:     raw_used = tme_m68k_insn_buffer_fill(ic, raw, raw_avail);
        !           445:     FORMAT_ERROR_IF(raw_used < 0);
        !           446:     raw += raw_used;
        !           447:     raw_avail -= raw_used;
        !           448:     
        !           449:     /* get out the EA address: */
        !           450:     RAW_GET(function_code);
        !           451:     ic->_tme_m68k_ea_function_code = function_code;
        !           452:     RAW_GET(ic->_tme_m68k_ea_address);
        !           453:     
        !           454:     /* get out the memory X and Y buffers: */
        !           455:     RAW_GET(ic->tme_m68k_ireg_memx32);
        !           456:     RAW_GET(ic->tme_m68k_ireg_memy32);
        !           457:     
        !           458:     /* done: */
        !           459:     break;
        !           460:     
        !           461:   case TME_M68K_MODE_EXCEPTION:
        !           462:     
        !           463:     /* get out the exceptions set: */
        !           464:     RAW_GET(ic->_tme_m68k_exceptions);
        !           465:     
        !           466:     /* get out the shadow status register: */
        !           467:     RAW_GET(ic->tme_m68k_ireg_shadow_sr);
        !           468:     
        !           469:     /* done: */
        !           470:     break;
        !           471:     
        !           472:   case TME_M68K_MODE_RTE:
        !           473:     
        !           474:     /* get out the shadow status register: */
        !           475:     RAW_GET(ic->tme_m68k_ireg_shadow_sr);
        !           476:     
        !           477:     /* get out the next program counter: */
        !           478:     RAW_GET(ic->tme_m68k_ireg_pc_next);
        !           479:     
        !           480:     /* get out the format/offset word: */
        !           481:     RAW_GET(ic->tme_m68k_ireg_format_offset);
        !           482:     
        !           483:     break;
        !           484:     
        !           485:   default: FORMAT_ERROR_IF(TRUE);
        !           486:   }
        !           487: 
        !           488:   /* finish the RTE: */
        !           489:   ic->_tme_m68k_sequence = ic->_tme_m68k_group0_sequence;
        !           490:   TME_M68K_SEQUENCE_RESTART;
        !           491:   tme_m68k_rte_finish(ic, sizeof(fmt8));
        !           492:   /* NOTREACHED */
        !           493: }
        !           494: 
        !           495: /* this creates and returns a new m68010: */
        !           496: TME_ELEMENT_X_NEW_DECL(tme_ic_,m68k,m68010) {
        !           497:   struct tme_m68k *ic;
        !           498: 
        !           499:   /* allocate the m68k structure: */
        !           500:   ic = tme_new0(struct tme_m68k, 1);
        !           501:   ic->tme_m68k_element = element;
        !           502: 
        !           503:   /* fill in the m68010-specific parts of the structure: */
        !           504:   ic->tme_m68k_type = TME_M68K_M68010;
        !           505:   ic->_tme_m68k_mode_execute = _tme_m68010_execute;
        !           506:   ic->_tme_m68k_mode_exception = _tme_m68010_exception;
        !           507:   ic->_tme_m68k_mode_rte = _tme_m68010_rte;
        !           508:   _tme_m68010_decoder_map_init(ic);
        !           509: 
        !           510:   /* call the common m68k new function: */
        !           511:   return (tme_m68k_new(ic, args, extra, _output));
        !           512: }

unix.superglobalmegacorp.com

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