|
|
1.1.1.2 ! root 1: /* $Id: m68020.c,v 1.7 2007/02/16 01:40:56 fredette Exp $ */ 1.1 root 2: 3: /* ic/m68k/m68020.c - implementation of Motorola 68020 emulation: */ 4: 5: /* 6: * Copyright (c) 2002, 2003, 2004 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> 1.1.1.2 ! root 37: _TME_RCSID("$Id: m68020.c,v 1.7 2007/02/16 01:40:56 fredette Exp $"); 1.1 root 38: 39: /* includes: */ 40: #include "m68k-impl.h" 41: 42: /* macros: */ 43: #define TME_M68K_SSWB_FC (0x8000) 44: #define TME_M68K_SSWB_FB (0x4000) 45: #define TME_M68K_SSWB_RC (0x2000) 46: #define TME_M68K_SSWB_RB (0x1000) 47: #define TME_M68K_SSWB_DF (0x0100) 48: #define TME_M68K_SSWB_RM (0x0080) 49: #define TME_M68K_SSWB_RW (0x0040) 50: #define TME_M68K_SSWB_SIZE_MASK (0x0030) 51: #define TME_M68K_SSWB_SIZE_4 (0x0000) 52: #define TME_M68K_SSWB_SIZE_1 (0x0010) 53: #define TME_M68K_SSWB_SIZE_2 (0x0020) 54: #define TME_M68K_SSWB_SIZE_3 (0x0030) 55: 56: /* structures: */ 57: 58: /* the format 0xB stack frame: */ 59: /* XXX we assume that this will pack: */ 60: struct tme_m68k_fmtB { 61: 62: /* an unused word: */ 63: tme_uint8_t tme_m68k_fmtB_state0[1 * sizeof(tme_uint16_t)]; 64: 65: /* the special status word: */ 66: tme_uint16_t tme_m68k_fmtB_ssw; 67: 68: /* the instruction pipe stage C: */ 69: tme_uint16_t tme_m68k_fmtB_ipipe_C; 70: 71: /* the instruction pipe stage B: */ 72: tme_uint16_t tme_m68k_fmtB_ipipe_B; 73: 74: /* the data cycle fault address: */ 75: tme_uint32_t tme_m68k_fmtB_addr; 76: 77: /* two unused words: */ 78: tme_uint8_t tme_m68k_fmtB_state1[2 * sizeof(tme_uint16_t)]; 79: 80: /* the data output buffer: */ 81: tme_uint8_t tme_m68k_fmtB_dob[4]; 82: 83: /* four unused words: */ 84: tme_uint8_t tme_m68k_fmtB_state2[4 * sizeof(tme_uint16_t)]; 85: 86: /* the stage B address: */ 87: tme_uint32_t tme_m68k_fmtB_addr_B; 88: 89: /* two unused words: */ 90: tme_uint8_t tme_m68k_fmtB_state3[2 * sizeof(tme_uint16_t)]; 91: 92: /* the data input buffer: */ 93: tme_uint8_t tme_m68k_fmtB_dib[4]; 94: 95: /* three unused words: */ 96: tme_uint8_t tme_m68k_fmtB_state4[3 * sizeof(tme_uint16_t)]; 97: 98: /* the version number and internal information: */ 99: tme_uint16_t tme_m68k_fmtB_version_info; 100: 101: /* eighteen unused words: */ 102: tme_uint8_t tme_m68k_fmtB_state5[18 * sizeof(tme_uint16_t)]; 103: }; 104: 105: /* both executors are for the 68020: */ 106: #define _TME_M68K_EXECUTE_CPU TME_M68K_M68020 107: #define _TME_M68K_EXECUTE_OPMAP tme_m68k_opcodes_m68020 108: 109: /* create the slow executor: */ 110: #define _TME_M68K_EXECUTE_NAME _tme_m68020_execute_slow 111: #undef _TME_M68K_EXECUTE_FAST 112: #undef _TME_M68K_EXECUTE_SLOW 113: #include "m68k-execute.c" 114: #undef _TME_M68K_EXECUTE_NAME 115: #undef _TME_M68K_EXECUTE_FAST 116: #undef _TME_M68K_EXECUTE_SLOW 117: 118: /* create the fast executor: */ 119: #define _TME_M68K_EXECUTE_NAME _tme_m68020_execute 120: #define _TME_M68K_EXECUTE_FAST 121: #define _TME_M68K_EXECUTE_SLOW _tme_m68020_execute_slow 122: #include "m68k-execute.c" 123: #undef _TME_M68K_EXECUTE_NAME 124: #undef _TME_M68K_EXECUTE_FAST 125: #undef _TME_M68K_EXECUTE_SLOW 126: 127: #undef _TME_M68K_EXECUTE_CPU 128: 129: /* m68020 exception processing: */ 130: static void 131: _tme_m68020_exception(struct tme_m68k *ic) 132: { 133: tme_uint32_t exceptions; 134: /* one 16-bit word for each 16-bit internal register word in the format 0xB frame: */ 135: tme_uint8_t raw_state[(1 + 2 + 4 + 2 + 3 + 18) * sizeof(tme_uint16_t)], *raw; 136: unsigned int raw_avail, raw_used; 137: struct tme_m68k_fmtB fmtB; 138: unsigned int flags; 139: tme_uint8_t function_code; 140: tme_uint16_t ssw; 141: 142: /* get the set of exceptions: */ 143: exceptions = ic->_tme_m68k_exceptions; 144: 145: /* a reset exception: */ 146: if (exceptions & TME_M68K_EXCEPTION_RESET) { 147: 148: /* do the common reset processing: */ 149: tme_m68k_do_reset(ic); 150: /* NOTREACHED */ 151: } 152: 153: /* an address or bus error: */ 154: else if (exceptions & (TME_M68K_EXCEPTION_AERR 155: | TME_M68K_EXCEPTION_BERR)) { 156: 157: /* start the exception processing: */ 158: tme_m68k_exception_process_start(ic, 0); 159: 160: /* start assembling the raw data: */ 161: raw = raw_state; 162: raw_avail = sizeof(raw_state); 163: #define RAW_PUT(v) \ 164: do { \ 165: assert(raw_avail >= sizeof(v)); \ 166: memcpy(raw, &v, sizeof(v)); \ 167: raw += sizeof(v); \ 168: raw_avail -= sizeof(v); \ 169: } while (/* CONSTCOND */ 0) 170: 171: /* put in the sequence: */ 172: raw_used = tme_m68k_sequence_empty(ic, raw, raw_avail); 173: raw += raw_used; 174: raw_avail -= raw_used; 175: 176: /* dispatch on the mode: */ 177: switch (ic->_tme_m68k_group0_sequence._tme_m68k_sequence_mode) { 178: 179: case TME_M68K_MODE_EXECUTION: 180: 181: /* put in the instruction buffer: */ 182: raw_used = tme_m68k_insn_buffer_empty(ic, raw, raw_avail); 183: raw += raw_used; 184: raw_avail -= raw_used; 185: 186: /* put in the EA address: */ 187: function_code = ic->_tme_m68k_ea_function_code; 188: RAW_PUT(function_code); 189: RAW_PUT(ic->_tme_m68k_ea_address); 190: 191: /* put in the memory X, Y, and Z buffers: */ 192: RAW_PUT(ic->tme_m68k_ireg_memx32); 193: RAW_PUT(ic->tme_m68k_ireg_memy32); 194: RAW_PUT(ic->tme_m68k_ireg_memz32); 195: 196: /* done: */ 197: break; 198: 199: case TME_M68K_MODE_EXCEPTION: 200: 201: /* put in the exceptions set: */ 202: RAW_PUT(ic->_tme_m68k_exceptions); 203: 204: /* put in the shadow status register: */ 205: RAW_PUT(ic->tme_m68k_ireg_shadow_sr); 206: 207: /* put in the last PC: */ 208: RAW_PUT(ic->tme_m68k_ireg_pc_last); 209: 210: /* done: */ 211: break; 212: 213: case TME_M68K_MODE_RTE: 214: 215: /* put in the shadow status register: */ 216: RAW_PUT(ic->tme_m68k_ireg_shadow_sr); 217: 218: /* put in the next program counter: */ 219: RAW_PUT(ic->tme_m68k_ireg_pc_next); 220: 221: /* put in the format/offset word: */ 222: RAW_PUT(ic->tme_m68k_ireg_format_offset); 223: 224: break; 225: 226: default: abort(); 227: } 228: 229: /* put in the internal state: */ 230: raw_avail = raw - raw_state; 231: raw = raw_state; 232: #undef RAW_PUT 233: #define RAW_PUT(f) \ 234: do { \ 235: raw_used = TME_MIN(sizeof(f), raw_avail); \ 236: memcpy(f, raw, raw_used); \ 237: raw += raw_used; \ 238: raw_avail -= raw_used; \ 239: } while (/* CONSTCOND */ 0) 240: 241: /* use all of the reserved regions: */ 242: RAW_PUT(fmtB.tme_m68k_fmtB_state0); 243: RAW_PUT(fmtB.tme_m68k_fmtB_state1); 244: RAW_PUT(fmtB.tme_m68k_fmtB_state2); 245: RAW_PUT(fmtB.tme_m68k_fmtB_state3); 246: RAW_PUT(fmtB.tme_m68k_fmtB_state4); 247: RAW_PUT(fmtB.tme_m68k_fmtB_state5); 248: #undef RAW_PUT 249: 250: /* put in the special status word and the data output buffer: */ 251: ssw = 0; 252: flags = ic->_tme_m68k_group0_flags; 253: 254: /* if this was an instruction fetch: */ 255: if (flags & TME_M68K_BUS_CYCLE_FETCH) { 256: 257: /* we always ask for a rerun of at least the stage C word, so we 258: associate the fault address with the stage C word. the 259: address of the stage C word is the address of the stage B 260: word minus sizeof(stage C word): */ 261: ssw |= TME_M68K_SSWB_RC; 262: fmtB.tme_m68k_fmtB_addr_B = tme_htobe_u32(ic->_tme_m68k_group0_address + sizeof(fmtB.tme_m68k_fmtB_ipipe_C)); 263: 264: /* if this is an address fault: */ 265: if (exceptions & TME_M68K_EXCEPTION_AERR) { 266: 267: /* nothing to do */ 268: } 269: 270: /* otherwise, this is a bus fault: */ 271: else { 272: 273: /* mark stage C as faulted: */ 274: ssw |= TME_M68K_SSWB_FC; 275: 276: /* if this is a 32-bit fetch: */ 277: if (ic->_tme_m68k_group0_buffer_read_size == sizeof(tme_uint32_t)) { 278: 279: /* a 32-bit fetch additionally faults "prefetching" the stage B word: */ 280: ssw |= (TME_M68K_SSWB_FB | TME_M68K_SSWB_RB); 281: } 282: } 283: } 284: 285: /* otherwise, this was not an instruction fetch: */ 286: else { 287: 288: /* this is a data fault: */ 289: ssw |= TME_M68K_SSWB_DF; 290: 291: /* put in the function code and address: */ 292: ssw |= ic->_tme_m68k_group0_function_code; 293: fmtB.tme_m68k_fmtB_addr = tme_htobe_u32(ic->_tme_m68k_group0_address); 294: 295: /* if this was part of a read/modify/write cycle: */ 296: if (flags & TME_M68K_BUS_CYCLE_RMW) { 297: ssw |= TME_M68K_SSWB_RM; 298: } 299: 300: /* if this was a read: */ 301: if (flags & TME_M68K_BUS_CYCLE_READ) { 302: ssw |= TME_M68K_SSWB_RW; 303: 304: /* put in the size indication: */ 305: switch (ic->_tme_m68k_group0_buffer_read_size) { 306: default: assert(FALSE); 307: case 1: ssw |= TME_M68K_SSWB_SIZE_1; break; 308: case 2: ssw |= TME_M68K_SSWB_SIZE_2; break; 309: case 3: ssw |= TME_M68K_SSWB_SIZE_3; break; 310: case 4: ssw |= TME_M68K_SSWB_SIZE_4; break; 311: } 312: 313: } 314: 315: /* otherwise, this is a write: */ 316: else { 317: 318: /* put in the size indication: */ 319: switch (ic->_tme_m68k_group0_buffer_write_size) { 320: default: assert(FALSE); 321: case 1: ssw |= TME_M68K_SSWB_SIZE_1; break; 322: case 2: ssw |= TME_M68K_SSWB_SIZE_2; break; 323: case 3: ssw |= TME_M68K_SSWB_SIZE_3; break; 324: case 4: ssw |= TME_M68K_SSWB_SIZE_4; break; 325: } 326: 327: /* put in the data output buffer: */ 328: memcpy(fmtB.tme_m68k_fmtB_dob 329: + sizeof(fmtB.tme_m68k_fmtB_dob) 330: - ic->_tme_m68k_group0_buffer_write_size, 331: ic->_tme_m68k_group0_buffer_write, 332: ic->_tme_m68k_group0_buffer_write_size); 333: } 334: } 335: 336: /* put in the SSW: */ 337: fmtB.tme_m68k_fmtB_ssw = tme_htobe_u16(ssw); 338: 339: /* push the format 0xB contents. we don't need to worry about 340: restarting here, because any fault is a double fault: */ 341: ic->tme_m68k_ireg_a7 -= sizeof(fmtB); 342: ic->_tme_m68k_ea_address = ic->tme_m68k_ireg_a7; 343: ic->_tme_m68k_ea_function_code = TME_M68K_FC_SD; /* XXX right? */ 344: tme_m68k_write_mem(ic, (tme_uint8_t *) &fmtB, sizeof(fmtB)); 345: 346: /* now finish the processing for this exception: */ 347: tme_m68k_exception_process_finish(ic, TME_M68K_FORMAT_B, 348: ((exceptions & TME_M68K_EXCEPTION_BERR) 349: ? TME_M68K_VECTOR_BERR 350: : TME_M68K_VECTOR_AERR)); 351: ic->_tme_m68k_exceptions = (exceptions &= ~ (TME_M68K_EXCEPTION_AERR 352: | TME_M68K_EXCEPTION_BERR)); 353: } 354: 355: /* do normal exception processing: */ 356: tme_m68020_exception_process(ic); 357: /* NOTREACHED */ 358: } 359: 360: /* m68020 RTE processing: */ 361: static void 362: _tme_m68020_rte(struct tme_m68k *ic) 363: { 364: tme_uint16_t format; 365: struct tme_m68k_fmtB fmtB; 366: tme_uint32_t fmtB_address; 367: /* one 16-bit word for each 16-bit internal register word in the format 0xB frame: */ 368: tme_uint8_t raw_state[(1 + 2 + 4 + 2 + 3 + 18) * sizeof(tme_uint16_t)], *raw; 369: unsigned int raw_avail, raw_used; 370: tme_uint8_t function_code; 371: tme_uint16_t ssw; 372: unsigned int flags; 373: const tme_uint8_t *ib; 374: unsigned int buffer_size; 375: 376: /* start the RTE: */ 377: format = tme_m68k_rte_start(ic); 378: 379: /* if this is a format 0 or format two stack frame, finish it now: */ 380: if (format == TME_M68K_FORMAT_0 381: || format == TME_M68K_FORMAT_2) { 382: ic->_tme_m68k_mode = TME_M68K_MODE_EXECUTION; 383: TME_M68K_SEQUENCE_START; 384: tme_m68k_rte_finish(ic, (format == TME_M68K_FORMAT_2 385: ? sizeof(ic->tme_m68k_ireg_pc_last) 386: : 0)); 387: /* NOTREACHED */ 388: } 389: 390: /* if this is a format one stack frame: */ 391: if (format == TME_M68K_FORMAT_1) { 392: 393: /* "For the throwaway four-word frame, the processor reads the SR 394: value from the frame, increments the active stack pointer by 8, 395: updates the SR with the value read from the stack, and then 396: begins RTE processing again" */ 397: ic->tme_m68k_ireg_a7 += 8; 398: tme_m68k_change_sr(ic, ic->tme_m68k_ireg_shadow_sr); 399: TME_M68K_SEQUENCE_START; 400: tme_m68k_redispatch(ic); 401: /* NOTREACHED */ 402: } 403: 404: /* whenever we detect a format error, begin exception processing 405: for a format error. we have to back the PC up by the size of the 406: RTE instruction so the PC points to it: */ 407: #define FORMAT_ERROR_IF(e) \ 408: do { \ 409: if (e) { \ 410: ic->tme_m68k_ireg_pc -= sizeof(tme_uint16_t); \ 411: tme_m68k_exception(ic, TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_FORMAT));\ 412: /* NOTREACHED */ \ 413: } \ 414: } while (/* CONSTCOND */ 0) 415: 416: /* this frame must be a format 0xB frame: */ 417: FORMAT_ERROR_IF(format != TME_M68K_FORMAT_B); 418: 419: /* do a read of the last word in the stack frame to determine 420: accessibility. we rely on tme_m68k_rte_start leaving 421: ic->_tme_m68k_ea_address pointing after the format/offset word: */ 422: fmtB_address = ic->_tme_m68k_ea_address; 423: ic->_tme_m68k_ea_address += sizeof(fmtB) - sizeof(tme_uint32_t); 424: tme_m68k_read_memx32(ic); 425: 426: /* read in the format 0xB information. if we get a bus error 427: during this operation it's a double fault: */ 428: assert(ic->_tme_m68k_exceptions == 0); 429: ic->_tme_m68k_exceptions = TME_M68K_EXCEPTION_BERR; 430: ic->_tme_m68k_ea_address = fmtB_address; 431: tme_m68k_read_mem(ic, (tme_uint8_t *) &fmtB, sizeof(fmtB)); 432: ic->_tme_m68k_exceptions = 0; 433: 434: /* reset the input and output buffers: */ 435: ic->_tme_m68k_group0_buffer_read_size = 0; 436: ic->_tme_m68k_group0_buffer_read_softrr = 0; 437: ic->_tme_m68k_group0_buffer_write_size = 0; 438: ic->_tme_m68k_group0_buffer_write_softrr = 0; 439: 440: /* get out the SSW: */ 441: ssw = tme_betoh_u16(fmtB.tme_m68k_fmtB_ssw); 442: 443: /* initialize the flags: */ 444: flags = 0; 445: 446: /* initialize the buffer size: */ 447: buffer_size = 0; 448: 449: /* initialize the input buffer: */ 450: ib = NULL; 451: 452: /* if this was an instruction fetch: */ 453: if (ssw & (TME_M68K_SSWB_FC | TME_M68K_SSWB_FB)) { 454: 455: /* we don't generate bus errors that only fault on stage B: */ 456: if ((ssw & (TME_M68K_SSWB_FC | TME_M68K_SSWB_FB)) == TME_M68K_SSWB_FB) { 457: abort(); 458: } 459: 460: /* if we faulted on both stages, we must be rerunning both or not 461: rerunning both. since we already know we either faulted only on 462: stage C, or we faulted on both, if we faulted on stage B check 463: that both RB and RC have the same value: */ 464: if ((ssw & TME_M68K_SSWB_FB) 465: && !(ssw & TME_M68K_SSWB_RC) != !(ssw & TME_M68K_SSWB_RB)) { 466: abort(); 467: } 468: 469: /* note that this was an instruction fetch: */ 470: flags |= TME_M68K_BUS_CYCLE_FETCH; 471: 472: /* get out the function code: */ 473: ic->_tme_m68k_group0_function_code 474: = ((ic->tme_m68k_ireg_shadow_sr & TME_M68K_FLAG_S) 475: ? TME_M68K_FC_SP 476: : TME_M68K_FC_UP); 477: 478: /* get out the fault address: */ 479: ic->_tme_m68k_group0_address = tme_betoh_u32(fmtB.tme_m68k_fmtB_addr_B) - sizeof(fmtB.tme_m68k_fmtB_ipipe_C); 480: 481: /* if the user reran this cycle: */ 482: if (!(ssw & TME_M68K_SSWB_RC)) { 483: 484: /* set the input buffer pointer: */ 485: /* NB that for 32-bit fetches, this relies on the fact that the 486: stage B word comes immediately after the stage C word in the 487: frame: */ 488: ib = (const tme_uint8_t *) &fmtB.tme_m68k_fmtB_ipipe_C; 489: } 490: 491: /* if this is a fault only on stage C: */ 492: if (!(ssw & TME_M68K_SSWB_FB)) { 493: 494: /* set the input buffer size: */ 495: buffer_size = sizeof(tme_uint16_t); 496: } 497: 498: /* otherwise, if this is a fault on stages C and B: */ 499: else { 500: 501: /* set the input buffer size: */ 502: buffer_size = sizeof(tme_uint32_t); 503: } 504: } 505: 506: /* otherwise, this was a data access: */ 507: else { 508: 509: /* get out the function code: */ 510: ic->_tme_m68k_group0_function_code = ssw & TME_M68K_FC_7; 511: 512: /* get out the fault address: */ 513: ic->_tme_m68k_group0_address = tme_betoh_u32(fmtB.tme_m68k_fmtB_addr); 514: 515: /* get out the size: */ 516: switch (ssw & TME_M68K_SSWB_SIZE_MASK) { 517: case TME_M68K_SSWB_SIZE_1: buffer_size = 1; break; 518: case TME_M68K_SSWB_SIZE_2: buffer_size = 2; break; 519: case TME_M68K_SSWB_SIZE_3: buffer_size = 3; break; 520: case TME_M68K_SSWB_SIZE_4: buffer_size = 4; break; 521: } 522: 523: /* if this was a read cycle: */ 524: if (ssw & TME_M68K_SSWB_RW) { 525: 526: /* mark that this was a read cycle: */ 527: flags |= TME_M68K_BUS_CYCLE_READ; 528: 529: /* if the user reran this cycle: */ 530: if (!(ssw & TME_M68K_SSWB_DF)) { 531: 532: /* set the input buffer pointer: */ 533: ib = &fmtB.tme_m68k_fmtB_dib[0]; 534: } 535: } 536: 537: /* otherwise, this was a write cycle: */ 538: else { 539: 540: /* if the user reran this cycle, note that, otherwise 541: copy in the data output buffer: */ 542: if (!(ssw & TME_M68K_SSWB_DF)) { 543: ic->_tme_m68k_group0_buffer_write_softrr = buffer_size; 544: } 545: else { 546: memcpy(ic->_tme_m68k_group0_buffer_write, 547: fmtB.tme_m68k_fmtB_dob + sizeof(fmtB.tme_m68k_fmtB_dob) - buffer_size, 548: buffer_size); 549: ic->_tme_m68k_group0_buffer_write_size = buffer_size; 550: } 551: } 552: } 553: 554: /* if the user reran this instruction fetch or data read cycle, read 555: in the appropriate input buffer: */ 556: if (ib != NULL) { 557: memcpy(ic->_tme_m68k_group0_buffer_read, 558: ib + sizeof(fmtB.tme_m68k_fmtB_dib) - buffer_size, 559: buffer_size); 560: ic->_tme_m68k_group0_buffer_read_softrr = buffer_size; 561: ic->_tme_m68k_group0_buffer_read_size = buffer_size; 562: } 563: 564: /* get out our internal state: */ 565: raw = raw_state; 566: raw_avail = sizeof(raw_state); 567: #define RAW_GET(f) \ 568: do { \ 569: raw_used = TME_MIN(sizeof(f), raw_avail); \ 570: memcpy(raw, f, raw_used); \ 571: raw += raw_used; \ 572: raw_avail -= raw_used; \ 573: } while (/* CONSTCOND */ 0) 574: 575: /* use all of the reserved regions: */ 576: RAW_GET(fmtB.tme_m68k_fmtB_state0); 577: RAW_GET(fmtB.tme_m68k_fmtB_state1); 578: RAW_GET(fmtB.tme_m68k_fmtB_state2); 579: RAW_GET(fmtB.tme_m68k_fmtB_state3); 580: RAW_GET(fmtB.tme_m68k_fmtB_state4); 581: RAW_GET(fmtB.tme_m68k_fmtB_state5); 582: #undef RAW_GET 583: 584: /* take apart the internal state: */ 585: raw = raw_state; 586: raw_avail = sizeof(raw_state) - raw_avail; 587: #define RAW_GET(v) \ 588: do { \ 589: FORMAT_ERROR_IF(raw_avail < sizeof(v)); \ 590: memcpy(&v, raw, sizeof(v)); \ 591: raw += sizeof(v); \ 592: raw_avail -= sizeof(v); \ 593: } while (/* CONSTCOND */ 0) 594: 595: /* get out the sequence: */ 596: raw_used = tme_m68k_sequence_fill(ic, raw, raw_avail); 1.1.1.2 ! root 597: FORMAT_ERROR_IF(raw_used <= 0); 1.1 root 598: raw += raw_used; 599: raw_avail -= raw_used; 600: 601: /* dispatch on the mode: */ 602: switch (ic->_tme_m68k_group0_sequence._tme_m68k_sequence_mode) { 603: 604: case TME_M68K_MODE_EXECUTION: 605: 606: /* get out the instruction buffer: */ 607: raw_used = tme_m68k_insn_buffer_fill(ic, raw, raw_avail); 1.1.1.2 ! root 608: FORMAT_ERROR_IF(raw_used <= 0); 1.1 root 609: raw += raw_used; 610: raw_avail -= raw_used; 611: 612: /* get out the EA address: */ 613: RAW_GET(function_code); 614: ic->_tme_m68k_ea_function_code = function_code; 615: RAW_GET(ic->_tme_m68k_ea_address); 616: 617: /* get out the memory X, Y, and Z buffers: */ 618: RAW_GET(ic->tme_m68k_ireg_memx32); 619: RAW_GET(ic->tme_m68k_ireg_memy32); 620: RAW_GET(ic->tme_m68k_ireg_memz32); 621: 622: /* done: */ 623: break; 624: 625: case TME_M68K_MODE_EXCEPTION: 626: 627: /* get out the exceptions set: */ 628: RAW_GET(ic->_tme_m68k_exceptions); 629: 630: /* get out the shadow status register: */ 631: RAW_GET(ic->tme_m68k_ireg_shadow_sr); 632: 633: /* get out the last PC: */ 634: RAW_GET(ic->tme_m68k_ireg_pc_last); 635: 636: /* done: */ 637: break; 638: 639: case TME_M68K_MODE_RTE: 640: 641: /* get out the shadow status register: */ 642: RAW_GET(ic->tme_m68k_ireg_shadow_sr); 643: 644: /* get out the next program counter: */ 645: RAW_GET(ic->tme_m68k_ireg_pc_next); 646: 647: /* get out the format/offset word: */ 648: RAW_GET(ic->tme_m68k_ireg_format_offset); 649: 650: break; 651: 652: default: FORMAT_ERROR_IF(TRUE); 653: } 654: 655: /* finish the RTE: */ 656: ic->_tme_m68k_sequence = ic->_tme_m68k_group0_sequence; 657: TME_M68K_SEQUENCE_RESTART; 658: tme_m68k_rte_finish(ic, sizeof(fmtB)); 659: /* NOTREACHED */ 660: } 661: 662: /* this creates and returns a new m68020: */ 663: TME_ELEMENT_X_NEW_DECL(tme_ic_,m68k,m68020) { 664: struct tme_m68k *ic; 665: 666: /* allocate the m68k structure: */ 667: ic = tme_new0(struct tme_m68k, 1); 668: ic->tme_m68k_element = element; 669: 670: /* fill in the m68020-specific parts of the structure: */ 671: ic->tme_m68k_type = TME_M68K_M68020; 672: ic->_tme_m68k_mode_execute = _tme_m68020_execute; 673: ic->_tme_m68k_mode_exception = _tme_m68020_exception; 674: ic->_tme_m68k_mode_rte = _tme_m68020_rte; 675: tme_m68k_opcodes_init_m68020(tme_m68k_opcodes_m68020); 676: 677: /* call the common m68k new function: */ 678: return (tme_m68k_new(ic, args, extra, _output)); 679: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.