static void fpu_op_illg (uae_u32 opcode, int pcoffset) { if ((currprefs.cpu_model == 68060 && (currprefs.fpu_model == 0 || (regs.pcr & 2))) || (currprefs.cpu_model == 68040 && currprefs.fpu_model == 0)) { /* 68040 unimplemented/68060 FPU disabled exception. * Line F exception with different stack frame.. */ uaecptr newpc = m68k_getpc (); uaecptr oldpc = newpc - pcoffset; MakeSR (); if (!regs.s) { regs.usp = m68k_areg (regs, 7); m68k_areg (regs, 7) = regs.isp; } regs.s = 1; m68k_areg (regs, 7) -= 4; put_long (m68k_areg (regs, 7), oldpc); m68k_areg (regs, 7) -= 4; put_long (m68k_areg (regs, 7), oldpc); m68k_areg (regs, 7) -= 2; put_word (m68k_areg (regs, 7), 0x4000 + 11 * 4); m68k_areg (regs, 7) -= 4; put_long (m68k_areg (regs, 7), newpc); m68k_areg (regs, 7) -= 2; put_word (m68k_areg (regs, 7), regs.sr); write_log ("68040/060 FPU disabled exception PC=%x\n", newpc); newpc = get_long (regs.vbr + 11 * 4); m68k_setpc (newpc); return; } op_illg (opcode); }
static void REGPARAM2 dummy_bput2 (uaecptr addr, uae_u32 b) { enforcer_display_hit (_T("BYTE WRITE to"), m68k_getpc (), addr); if (enforcermode & 1) { set_special (SPCFLAG_TRAP); return; } }
static void REGPARAM2 dummy_wput2 (uaecptr addr, uae_u32 w) { special_mem_w; enforcer_display_hit (_T("WORD WRITE to"), m68k_getpc (), addr); if (enforcermode & 1) { set_special (SPCFLAG_TRAP); return; } }
static uae_u32 REGPARAM2 dummy_wget2 (uaecptr addr) { #ifdef JIT if (addr >= 0x00F10000 && addr <= 0x00F7FFFF) { if (!warned_JIT_0xF10000) { warned_JIT_0xF10000 = 1; enforcer_display_hit (_T("LONG READ from"), m68k_getpc (), addr); } return 0; } #endif enforcer_display_hit (_T("WORD READ from"), m68k_getpc (), addr); if (enforcermode & 1) { set_special (SPCFLAG_TRAP); return 0; } return 0xbadf; }
static uae_u32 REGPARAM2 dummy_bget2 (uaecptr addr) { enforcer_display_hit (_T("BYTE READ from"), m68k_getpc (), addr); if (enforcermode & 1) { set_special (SPCFLAG_TRAP); return 0; } return 0xbadedeef; }
static uint32_t REGPARAM2 dummy_lget2 (uaecptr addr) { special_mem_r; enforcer_display_hit (_T("LONG READ from"), m68k_getpc (), addr); if (enforcermode & 1) { set_special (SPCFLAG_TRAP); return 0; } return 0xbadedeef; }
void map_overlay (int chip) { int i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32; addrbank *cb; cb = &chipmem_bank; if (chip) map_banks (cb, 0, i, allocated_chipmem); else map_banks (&kickmem_bank, 0, i, 0x80000); if (savestate_state != STATE_RESTORE) m68k_setpc (m68k_getpc ()); }
static uae_u32 REGPARAM2 chipmem_bget2 (uaecptr addr) { addr -= chipmem_start_addr & chipmem_bank.mask; addr &= chipmem_bank.mask; if (ISILLEGAL_BYTE (addr)) { enforcer_display_hit (_T("BYTE READ from"), m68k_getpc (), addr); if (enforcermode & 1) set_special (SPCFLAG_TRAP); } return chipmem_bank.baseaddr[addr]; }
static void REGPARAM2 chipmem_bput2 (uaecptr addr, uae_u32 b) { addr -= chipmem_start_addr & chipmem_bank.mask; addr &= chipmem_bank.mask; if (ISILLEGAL_BYTE (addr)) { enforcer_display_hit (_T("BYTE WRITE to"), m68k_getpc (), addr); if (enforcermode & 1) set_special (SPCFLAG_TRAP); } if (ISEXEC (addr)) return; chipmem_bank.baseaddr[addr] = b; }
static uint32_t REGPARAM2 chipmem_lget2 (uaecptr addr) { uint32_t *m; addr -= chipmem_start_addr & chipmem_bank.mask; addr &= chipmem_bank.mask; m = (uint32_t *)(chipmem_bank.baseaddr + addr); if (ISILLEGAL_LONG (addr)) { enforcer_display_hit (_T("LONG READ from"), m68k_getpc (), addr); if (enforcermode & 1) set_special (SPCFLAG_TRAP); } return do_get_mem_long (m); }
STATIC_INLINE void ciab_checkalarm (int inc) { // hack: do not trigger alarm interrupt if KS code and both // tod and alarm == 0. This incorrectly triggers on non-cycle exact // modes. Real hardware value written to ciabtod by KS is always // at least 1 or larger due to bus cycle delays when reading // old value. if ((munge24 (m68k_getpc ()) & 0xFFF80000) == 0xF80000) { if (ciabtod == 0 && ciabalarm == 0) return; } if (checkalarm (ciabtod, ciabalarm, inc)) { ciabicr |= 4; RethinkICRB (); } }
static uae_u32 REGPARAM2 chipmem_wget2(uaecptr addr) { uae_u16 *m; addr -= chipmem_start_addr & chipmem_bank.mask; addr &= chipmem_bank.mask; m = (uae_u16 *)(chipmem_bank.baseaddr + addr); if (ISILLEGAL_WORD (addr)) { enforcer_display_hit (_T("WORD READ from"), m68k_getpc (), addr); if (enforcermode & 1) set_special (SPCFLAG_TRAP); } return do_get_mem_word (m); }
static void REGPARAM2 chipmem_wput2 (uaecptr addr, uae_u32 w) { uae_u16 *m; addr -= chipmem_start_addr & chipmem_bank.mask; addr &= chipmem_bank.mask; m = (uae_u16 *)(chipmem_bank.baseaddr + addr); if (ISILLEGAL_WORD (addr)) { enforcer_display_hit (_T("WORD WRITE to"), m68k_getpc (), addr); if (enforcermode & 1) set_special (SPCFLAG_TRAP); } if (ISEXEC (addr) || ISEXEC (addr + 1)) return; do_put_mem_word (m, w); }
static void REGPARAM2 chipmem_lput2 (uaecptr addr, uae_u32 l) { uae_u32 *m; addr -= chipmem_start_addr & chipmem_bank.mask; addr &= chipmem_bank.mask; m = (uae_u32 *)(chipmem_bank.baseaddr + addr); if (ISILLEGAL_LONG (addr)) { enforcer_display_hit (_T("LONG WRITE to"), m68k_getpc (), addr); if (enforcermode & 1) if (addr != 0x100) set_special (SPCFLAG_TRAP); } if (ISEXEC (addr) || ISEXEC (addr + 1) || ISEXEC (addr + 2) || ISEXEC (addr + 3)) return; do_put_mem_long (m, l); }
unsigned long IllegalOpcode(uint32_t opcode) { #if 0 uint32_t pc = m68k_getpc (); #endif if ((opcode & 0xF000) == 0xF000) { Exception(0x0B, 0, M68000_EXC_SRC_CPU); // LineF exception... return 4; } else if ((opcode & 0xF000) == 0xA000) { Exception(0x0A, 0, M68000_EXC_SRC_CPU); // LineA exception... return 4; } #if 0 write_log ("Illegal instruction: %04x at %08lx\n", opcode, (long)pc); #endif Exception(0x04, 0, M68000_EXC_SRC_CPU); // Illegal opcode exception... return 4; }
/* This function saves the state of the calculator. Can be called at any time. Return an error code if an error occured, 0 otherwise */ int ti68k_state_save(char *filename) { FILE *f; IMG_INFO *img = &img_infos; SAV_INFO sav; int i; if(!strlen(filename)) return ERR_CANT_OPEN; // Open file printl(0, "Saving state image (TiEmu v2.00 format): %s\n", filename); f = fopen(filename, "wb"); if(f == NULL) return ERR_CANT_OPEN; // Save current image infos fwrite(img, 1, sizeof(IMG_INFO), f); // Fill state image infos sav.revision = SAV_REVISION; sav.size = sizeof(SAV_INFO); sav.regs_offset = sizeof(IMG_INFO) + sizeof(SAV_INFO); sav.io_offset = sav.regs_offset + sizeof(regs); sav.ram_offset = sav.io_offset + 2*tihw.io_size; sav.misc_offset = sav.ram_offset + tihw.ram_size; #if 1 sav.rom_offset = sav.misc_offset + sizeof(Ti68kHardware); sav.bkpts_offset = sav.rom_offset + wsm.nblocks*sizeof(int) + hw_flash_nblocks()*65536; #else sav.bkpts_offset = sav.misc_offset + sizeof(Ti68kHardware); #endif fwrite(&sav, 1, sizeof(SAV_INFO), f); // Update UAE structures MakeSR(); m68k_setpc(m68k_getpc()); // Save registers and special flags fwrite(®s, sizeof(regs), 1, f); // Save I/O ports state fwrite(tihw.io , tihw.io_size, 1, f); fwrite(tihw.io2, tihw.io_size, 1, f); // Save RAM content fwrite(tihw.ram, tihw.ram_size, 1, f); // Save misc informations fwrite(&tihw, sizeof(Ti68kHardware), 1, f); // Save modified FLASH segments for(i=0; i<wsm.nblocks; i++) { fwrite(&wsm.changed[i], sizeof(int), 1, f); if(wsm.changed[i]) fwrite(&tihw.rom[i<<16], 1, 65536, f); } // Save breakpoints (address, access, range, exception) save_bkpt(f, bkpts.code); save_bkpt(f, bkpts.exception); save_bkpt(f, bkpts.pgmentry); save_bkpt(f, bkpts.mem_rb); save_bkpt(f, bkpts.mem_rw); save_bkpt(f, bkpts.mem_rl); save_bkpt(f, bkpts.mem_wb); save_bkpt(f, bkpts.mem_ww); save_bkpt(f, bkpts.mem_wl); save_bkpt2(f, bkpts.mem_rng_r); save_bkpt2(f, bkpts.mem_rng_w); fclose(f); return 0; }
// Pulse the RESET line on the CPU void m68k_pulse_reset(void) { static uint32_t emulation_initialized = 0; // The first call to this function initializes the opcode handler jump table if (!emulation_initialized) { #if 0 m68ki_build_opcode_table(); m68k_set_int_ack_callback(NULL); m68k_set_bkpt_ack_callback(NULL); m68k_set_reset_instr_callback(NULL); m68k_set_pc_changed_callback(NULL); m68k_set_fc_callback(NULL); m68k_set_instr_hook_callback(NULL); #else // Build opcode handler table here... read_table68k(); do_merges(); BuildCPUFunctionTable(); #endif emulation_initialized = 1; } // if (CPU_TYPE == 0) /* KW 990319 */ // m68k_set_cpu_type(M68K_CPU_TYPE_68000); #if 0 /* Clear all stop levels and eat up all remaining cycles */ CPU_STOPPED = 0; SET_CYCLES(0); /* Turn off tracing */ FLAG_T1 = FLAG_T0 = 0; m68ki_clear_trace(); /* Interrupt mask to level 7 */ FLAG_INT_MASK = 0x0700; /* Reset VBR */ REG_VBR = 0; /* Go to supervisor mode */ m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR); /* Invalidate the prefetch queue */ #if M68K_EMULATE_PREFETCH /* Set to arbitrary number since our first fetch is from 0 */ CPU_PREF_ADDR = 0x1000; #endif /* M68K_EMULATE_PREFETCH */ /* Read the initial stack pointer and program counter */ m68ki_jump(0); REG_SP = m68ki_read_imm_32(); REG_PC = m68ki_read_imm_32(); m68ki_jump(REG_PC); #else regs.spcflags = 0; regs.stopped = 0; regs.remainingCycles = 0; regs.intmask = 0x07; regs.s = 1; // Supervisor mode ON // Read initial SP and PC m68k_areg(regs, 7) = m68k_read_memory_32(0); m68k_setpc(m68k_read_memory_32(4)); refill_prefetch(m68k_getpc(), 0); #endif }
static int REGPARAM2 dummy_check2 (uaecptr addr, uae_u32 size) { special_mem_r; enforcer_display_hit (_T("CHECK from "), m68k_getpc (), addr); return 0; }
static uae_u8 ReadCIAA (unsigned int addr) { unsigned int tmp; compute_passed_time (); #ifdef CIA_DEBUG write_log("R_CIAA: %02.2X %08.8X\n", addr, m68k_getpc()); #endif switch (addr & 0xf) { case 0: #ifdef ACTION_REPLAY action_replay_ciaread(); #endif tmp = DISK_status() & 0x3c; tmp |= handle_joystick_buttons (ciaadra); tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03; if (ciaadra & 0x40) tmp = (tmp & ~0x40) | (ciaapra & 0x40); if (ciaadra & 0x80) tmp = (tmp & ~0x80) | (ciaapra & 0x80); #ifdef DONGLE_DEBUG if (notinrom()) write_log ("BFE001 R %02.2X %s\n", tmp, debuginfo(0)); #endif return tmp; case 1: #ifdef PARALLEL_PORT if (isprinter () > 0) { tmp = ciaaprb; } else if (isprinter () < 0) { uae_u8 v; parallel_direct_read_data (&v); tmp = v; } else { tmp = handle_parport_joystick (0, ciaaprb, ciaadrb); } #else tmp = handle_parport_joystick (0, ciaaprb, ciaadrb); #ifdef DONGLE_DEBUG if (notinrom()) write_log ("BFE101 R %02.2X %s\n", tmp, debuginfo(0)); #endif #endif return tmp; case 2: #ifdef DONGLE_DEBUG if (notinrom ()) write_log ("BFE201 R %02.2X %s\n", ciaadra, debuginfo(0)); #endif return ciaadra; case 3: #ifdef DONGLE_DEBUG if (notinrom ()) write_log ("BFE301 R %02.2X %s\n", ciaadrb, debuginfo(0)); #endif return ciaadrb; case 4: return (uae_u8)((ciaata - ciaata_passed) & 0xff); case 5: return (uae_u8)((ciaata - ciaata_passed) >> 8); case 6: return (uae_u8)((ciaatb - ciaatb_passed) & 0xff); case 7: return (uae_u8)((ciaatb - ciaatb_passed) >> 8); case 8: if (ciaatlatch) { ciaatlatch = 0; return (uae_u8)ciaatol; } else return (uae_u8)ciaatod; case 9: if (ciaatlatch) return (uae_u8)(ciaatol >> 8); else return (uae_u8)(ciaatod >> 8); case 10: ciaatlatch = 1; ciaatol = ciaatod; /* ??? only if not already latched? */ return (uae_u8)(ciaatol >> 16); case 12: if (ciaasdr_unread == 1) ciaasdr_unread = 2; return ciaasdr; case 13: tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); return tmp; case 14: return ciaacra; case 15: return ciaacrb; }
/* Do 'n' instructions. return ERR_NONE if successful, a negative value if an error occured, a positive value if a breakpoint has been encountered. */ int hw_m68k_run(int n) { #if 1 int i; GList *l; static FILE *flog; for(i=0; i<n; i++) { UWORD opcode; if(flog != NULL) { //fprintf(flog, "0x%06lx\n", m68k_getpc()); } else flog = fopen("C:\\tiemu.log", "wt"); if(bkpts.pc_log_size > 1) bkpts.pc_log[bkpts.pc_wr_ptr++ % bkpts.pc_log_size] = m68k_getpc(); opcode = nextiword(); (*cpufunctbl[opcode])(opcode); do_cycles(); if((l = bkpts.code) != NULL) { bkpts.id = 0; while(l) { if(GPOINTER_TO_INT(l->data) == (int)regs.pc) { bkpts.type = BK_TYPE_CODE; specialflags |= SPCFLAG_BRK; } bkpts.id++; l = g_list_next(l); } } /* Debug purposes */ #if 0 if (bInstructionsDisplay) { disasm(getPcRegister(), inst); printf("disasm: %s\n", inst); } #endif /* Flag management */ if(specialflags) { if(specialflags & SPCFLAG_ADRERR) { Exception(3); specialflags &= ~SPCFLAG_ADRERR; } if (specialflags & SPCFLAG_DOTRACE) { Exception(9); } while (specialflags & SPCFLAG_STOP) { do_cycles(); if (specialflags & (SPCFLAG_INT | SPCFLAG_DOINT)) { int intr = intlev(); specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT); if (intr != -1 && intr > regs.intmask) { Interrupt(intr); regs.stopped = 0; specialflags &= ~SPCFLAG_STOP; } } } if (specialflags & SPCFLAG_TRACE) { specialflags &= ~SPCFLAG_TRACE; specialflags |= SPCFLAG_DOTRACE; } if (specialflags & SPCFLAG_DOINT) { int intr = intlev(); specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT); if (intr != -1 && intr > regs.intmask) { Interrupt(intr); regs.stopped = 0; } } if (specialflags & SPCFLAG_INT) { specialflags &= ~SPCFLAG_INT; specialflags |= SPCFLAG_DOINT; } if (specialflags & SPCFLAG_BRK) { specialflags &= ~SPCFLAG_BRK; return 1; // DBG_BREAK } if(specialflags & SPCFLAG_DBTRACE) { specialflags &= ~SPCFLAG_DBTRACE; return 2; // DBG_TRACE } } } #endif return 0; }
/* This function saves the state of the calculator. Can be called at any time. Return an error code if an error occured, 0 otherwise */ int ti68k_state_save(const char *filename) { FILE *f; IMG_INFO *img = &img_infos; SAV_INFO sav; int i; long len; long bkpts_size; if(!strlen(filename)) return ERR_CANT_OPEN_STATE; // Open file tiemu_info(_("saving state image (TiEmu v2.00 format): %s"), filename); f = fopen(filename, "wb"); if(f == NULL) return ERR_CANT_OPEN_STATE; // Save current image infos fwrite(img, 1, sizeof(IMG_INFO), f); // Fill state image infos sav.revision = SAV_REVISION; sav.size = sizeof(SAV_INFO); sav.regs_offset = sizeof(IMG_INFO) + sizeof(SAV_INFO); sav.io_offset = sav.regs_offset + sizeof(regs); sav.ram_offset = sav.io_offset + tihw.io_size + tihw.io2_size + tihw.io3_size; sav.misc_offset = sav.ram_offset + tihw.ram_size; sav.rom_offset = sav.misc_offset + sizeof(Ti68kHardware); sav.bkpts_offset = sav.rom_offset + wsm.nblocks*sizeof(int) + hw_flash_nblocks()*65536; bkpts_size = g_list_length(bkpts.code) * sizeof(long) + sizeof(long) + g_list_length(bkpts.exception) * sizeof(long) + sizeof(long) + g_list_length(bkpts.pgmentry) * sizeof(long) + sizeof(long) + g_list_length(bkpts.mem_rb) * sizeof(long) + sizeof(long) + g_list_length(bkpts.mem_rw) * sizeof(long) + sizeof(long) + g_list_length(bkpts.mem_rl) * sizeof(long) + sizeof(long) + g_list_length(bkpts.mem_wb) * sizeof(long) + sizeof(long) + g_list_length(bkpts.mem_ww) * sizeof(long) + sizeof(long) + g_list_length(bkpts.mem_wl) * sizeof(long) + sizeof(long) + g_list_length(bkpts.mem_rng_r) * sizeof(ADDR_RANGE) + sizeof(long) + g_list_length(bkpts.mem_rng_w) * sizeof(ADDR_RANGE) + sizeof(long) + g_list_length(bkpts.bits) * sizeof(ADDR_BIT) + sizeof(long) ; sav.str_offset = sav.bkpts_offset + bkpts_size; fwrite(&sav, 1, sizeof(SAV_INFO), f); // Update UAE structures MakeSR(); m68k_setpc(m68k_getpc()); // Save registers and special flags fwrite(®s, sizeof(regs), 1, f); // Save I/O ports state fwrite(tihw.io , tihw.io_size, 1, f); fwrite(tihw.io2, tihw.io2_size, 1, f); fwrite(tihw.io3, tihw.io3_size, 1, f); // Save RAM content fwrite(tihw.ram, tihw.ram_size, 1, f); // Save misc informations rtc3_state_save(); fwrite(&tihw, sizeof(Ti68kHardware), 1, f); // Save modified FLASH segments for(i=0; i<wsm.nblocks; i++) { fwrite(&wsm.changed[i], sizeof(int), 1, f); if(wsm.changed[i]) fwrite(&tihw.rom[i<<16], 1, 65536, f); } // Save breakpoints save_bkpt(f, bkpts.code); save_bkpt(f, bkpts.exception); save_bkpt(f, bkpts.pgmentry); save_bkpt(f, bkpts.mem_rb); save_bkpt(f, bkpts.mem_rw); save_bkpt(f, bkpts.mem_rl); save_bkpt(f, bkpts.mem_wb); save_bkpt(f, bkpts.mem_ww); save_bkpt(f, bkpts.mem_wl); save_bkpt2(f, bkpts.mem_rng_r); save_bkpt2(f, bkpts.mem_rng_w); save_bkpt3(f, bkpts.bits); // Save image location associated with this state image len = strlen(params.rom_file) + 1; fwrite(&len, 1, sizeof(len), f); fwrite(params.rom_file, len, 1, f); len = strlen(params.tib_file) + 1; fwrite(&len, 1, sizeof(len), f); fwrite(params.tib_file, len, 1, f); fclose(f); return 0; }
/* Must be done between init_hardware and M68000_run. Typically called after initLib68k. This function (re)load the state of the calculator. It automagically determine the state file format. Return an error code if an error occured, 0 otherwise */ int ti68k_state_load(char *filename) { FILE *f; IMG_INFO img; SAV_INFO sav; Ti68kHardware thw; int ret; long pos; int i; // No filename, exits if(!strcmp(filename, "")) return 0; // Open file printl(0, "loading state image: %s\n", g_basename(filename)); f = fopen(filename, "rb"); if(f == NULL) return ERR_CANT_OPEN; // Compare image infos with current image fread(&img, 1, sizeof(IMG_INFO), f); if(memcmp(&img, &img_infos, sizeof(IMG_INFO) - sizeof(char *))) return ERR_INVALID_STATE; // Determine state image revision for backwards compatibility pos = ftell(f); fread(&sav.revision, sizeof(sav.revision), 1, f); fread(&sav.size, sizeof(sav.revision), 1, f); fseek(f, pos, SEEK_SET); if(sav.revision != SAV_REVISION) return ERR_INVALID_STATE; // Load state image infos fread(&sav, 1, sizeof(SAV_INFO), f); // Load internal hardware (registers and special flags) ret = fseek(f, sav.regs_offset, SEEK_SET); fread(®s, sizeof(regs), 1, f); // Load I/O ports state ret = fseek(f, sav.io_offset, SEEK_SET); fread(tihw.io , tihw.io_size, 1, f); fread(tihw.io2, tihw.io_size, 1, f); // Load RAM content ret = fseek(f, sav.ram_offset, SEEK_SET); fread(tihw.ram, tihw.ram_size, 1, f); // Load extra infos ret = fseek(f, sav.misc_offset, SEEK_SET); fread(&thw, sizeof(Ti68kHardware), 1, f); tihw.on_off = thw.on_off; tihw.lcd_adr = thw.lcd_adr; tihw.contrast = thw.contrast; tihw.protect = thw.protect; tihw.archive_limit = thw.archive_limit; memcpy(tihw.ram_exec, thw.ram_exec, 32); // Load modified FLASH segments ret = fseek(f, sav.rom_offset, SEEK_SET); for(i=0; i<wsm.nblocks; i++) { fread(&wsm.changed[i], sizeof(int), 1, f); if(wsm.changed[i]) fread(&tihw.rom[i<<16], 1, 65536, f); } // Load bkpts ti68k_bkpt_clear_access(); ti68k_bkpt_clear_range(); ti68k_bkpt_clear_address(); ti68k_bkpt_clear_exception(); ti68k_bkpt_clear_pgmentry(); ret = fseek(f, sav.bkpts_offset, SEEK_SET); load_bkpt(f, &bkpts.code); load_bkpt(f, &bkpts.exception); load_bkpt(f, &bkpts.pgmentry); load_bkpt(f, &bkpts.mem_rb); load_bkpt(f, &bkpts.mem_rw); load_bkpt(f, &bkpts.mem_rl); load_bkpt(f, &bkpts.mem_wb); load_bkpt(f, &bkpts.mem_ww); load_bkpt(f, &bkpts.mem_wl); load_bkpt2(f, &bkpts.mem_rng_r); load_bkpt2(f, &bkpts.mem_rng_w); // Update UAE structures m68k_setpc(m68k_getpc()); MakeFromSR(); fclose(f); return 0; }
void comp_fpp_opp (uae_u32 opcode, uae_u16 extra) { int reg; int sreg, prec = 0; int dreg = (extra >> 7) & 7; int source = (extra >> 13) & 7; int opmode = extra & 0x7f; if (!currprefs.compfpu) { FAIL(1); return; } switch (source) { case 3: /* FMOVE FPx, <EA> */ if (comp_fp_put(opcode,extra) < 0) FAIL(1); return; case 4: /* FMOVE.L <EA>, ControlReg */ if (!(opcode & 0x30)) { /* Dn or An */ if (extra & 0x1000) { /* FPCR */ mov_l_mr((uae_u32)®s.fpcr,opcode & 15); #if USE_X86_FPUCW mov_l_rr(S1,opcode & 15); and_l_ri(S1,0xf0); fldcw_m_indexed(S1,(uae_u32)x86_fpucw); #endif return; } if (extra & 0x0800) { /* FPSR */ FAIL(1); return; // set_fpsr(m68k_dreg (regs, opcode & 15)); } if (extra & 0x0400) { /* FPIAR */ mov_l_mr((uae_u32)®s.fpiar,opcode & 15); return; } } else if ((opcode & 0x3f) == 0x3c) { if (extra & 0x1000) { /* FPCR */ uae_u32 val=comp_get_ilong((m68k_pc_offset+=4)-4); mov_l_mi((uae_u32)®s.fpcr,val); #if USE_X86_FPUCW mov_l_ri(S1,val&0xf0); fldcw_m_indexed(S1,(uae_u32)x86_fpucw); #endif return; } if (extra & 0x0800) { /* FPSR */ FAIL(1); return; } if (extra & 0x0400) { /* FPIAR */ uae_u32 val=comp_get_ilong((m68k_pc_offset+=4)-4); mov_l_mi((uae_u32)®s.fpiar,val); return; } } FAIL(1); return; case 5: /* FMOVE.L ControlReg, <EA> */ if (!(opcode & 0x30)) { /* Dn or An */ if (extra & 0x1000) { /* FPCR */ mov_l_rm(opcode & 15,(uae_u32)®s.fpcr); return; } if (extra & 0x0800) { /* FPSR */ FAIL(1); return; } if (extra & 0x0400) { /* FPIAR */ mov_l_rm(opcode & 15,(uae_u32)®s.fpiar); return; } } FAIL(1); return; case 6: case 7: { uae_u32 list = 0; int incr = 0; if (extra & 0x2000) { uae_u32 ad; /* FMOVEM FPP->memory */ switch ((extra >> 11) & 3) { /* Get out early if failure */ case 0: case 2: break; case 1: case 3: default: FAIL(1); return; } ad = comp_fp_adr (opcode); if (ad < 0) { m68k_setpc (m68k_getpc () - 4); op_illg (opcode); return; } switch ((extra >> 11) & 3) { case 0: /* static pred */ list = extra & 0xff; incr = -1; break; case 2: /* static postinc */ list = extra & 0xff; incr = 1; break; case 1: /* dynamic pred */ case 3: /* dynamic postinc */ abort(); } if (incr < 0) { /* Predecrement */ for (reg = 7; reg >= 0; reg--) { if (list & 0x80) { fmov_ext_mr((uintptr)temp_fp,reg); sub_l_ri(ad,4); mov_l_rm(S2,(uintptr)temp_fp); writelong_clobber(ad,S2,S3); sub_l_ri(ad,4); mov_l_rm(S2,(uintptr)temp_fp+4); writelong_clobber(ad,S2,S3); sub_l_ri(ad,4); mov_w_rm(S2,(uintptr)temp_fp+8); writeword_clobber(ad,S2,S3); } list <<= 1; } } else { /* Postincrement */ for (reg = 0; reg <= 7; reg++) { if (list & 0x80) { fmov_ext_mr((uintptr)temp_fp,reg); mov_w_rm(S2,(uintptr)temp_fp+8); writeword_clobber(ad,S2,S3); add_l_ri(ad,4); mov_l_rm(S2,(uintptr)temp_fp+4); writelong_clobber(ad,S2,S3); add_l_ri(ad,4); mov_l_rm(S2,(uintptr)temp_fp); writelong_clobber(ad,S2,S3); add_l_ri(ad,4); } list <<= 1; } } if ((opcode & 0x38) == 0x18) mov_l_rr((opcode & 7)+8,ad); if ((opcode & 0x38) == 0x20) mov_l_rr((opcode & 7)+8,ad); } else { /* FMOVEM memory->FPP */ uae_u32 ad; switch ((extra >> 11) & 3) { /* Get out early if failure */ case 0: case 2: break; case 1: case 3: default: FAIL(1); return; } ad=comp_fp_adr (opcode); if (ad < 0) { m68k_setpc (m68k_getpc () - 4); op_illg (opcode); return; } switch ((extra >> 11) & 3) { case 0: /* static pred */ list = extra & 0xff; incr = -1; break; case 2: /* static postinc */ list = extra & 0xff; incr = 1; break; case 1: /* dynamic pred */ case 3: /* dynamic postinc */ abort(); } if (incr < 0) { // not reached for (reg = 7; reg >= 0; reg--) { if (list & 0x80) { sub_l_ri(ad,4); readlong(ad,S2,S3); mov_l_mr((uintptr)(temp_fp),S2); sub_l_ri(ad,4); readlong(ad,S2,S3); mov_l_mr((uintptr)(temp_fp)+4,S2); sub_l_ri(ad,4); readword(ad,S2,S3); mov_w_mr(((uintptr)temp_fp)+8,S2); fmov_ext_rm(reg,(uintptr)(temp_fp)); } list <<= 1; } } else { for (reg = 0; reg <= 7; reg++) { if (list & 0x80) { readword(ad,S2,S3); mov_w_mr(((uintptr)temp_fp)+8,S2); add_l_ri(ad,4); readlong(ad,S2,S3); mov_l_mr((uintptr)(temp_fp)+4,S2); add_l_ri(ad,4); readlong(ad,S2,S3); mov_l_mr((uintptr)(temp_fp),S2); add_l_ri(ad,4); fmov_ext_rm(reg,(uintptr)(temp_fp)); } list <<= 1; } } if ((opcode & 0x38) == 0x18) mov_l_rr((opcode & 7)+8,ad); if ((opcode & 0x38) == 0x20) mov_l_rr((opcode & 7)+8,ad); } }
static void copytocpucontext(struct TrapCPUContext *cpu) { memcpy (cpu->regs, regs.regs, sizeof (regs.regs)); cpu->intmask = regs.intmask; cpu->pc = m68k_getpc (); }
STATIC_INLINE int isinrom (void) { return (munge24 (m68k_getpc ()) & 0xFFF80000) == 0xF80000 && !currprefs.mmu_model; }
Uint8 tmc_scr1_read2(void) { Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200002 PC=$%08x\n",m68k_getpc()); return (tmc.scr1>>8); }
/* Must be done between init_hardware and M68000_run. Typically called after initLib68k. This function (re)load the state of the calculator. It automagically determine the state file format. Return an error code if an error occured, 0 otherwise */ int ti68k_state_load(const char *filename) { FILE *f; IMG_INFO img; SAV_INFO sav; Ti68kHardware thw; int ret; long pos; int i; gchar *rf=NULL, *tf=NULL; // No filename, exits if(!strcmp(filename, "")) return 0; // Open file tiemu_info(_("loading state image: %s"), g_basename(filename)); f = fopen(filename, "rb"); if(f == NULL) return ERR_CANT_OPEN_STATE; // Load ROM image header fread(&img, 1, sizeof(IMG_INFO), f); // Determine state image revision and load state image header pos = ftell(f); fread(&sav.revision, sizeof(sav.revision), 1, f); fread(&sav.size, sizeof(sav.revision), 1, f); fseek(f, pos, SEEK_SET); fread(&sav, 1, sav.size, f); if(sav.revision < SAV_MINI) { fclose(f); return ERR_REVISION_MATCH; } // Does not accept state image different of emulator image if(ti68k_state_parse(filename, &rf, &tf) < 0) { if (rf) g_free(rf); if (tf) g_free(tf); return ERR_STATE_MATCH; } if (rf) g_free(rf); if (tf) g_free(tf); // Compare image infos with current image if(memcmp(&img, &img_infos, sizeof(IMG_INFO) - sizeof(char *))) return ERR_HEADER_MATCH; // Load internal hardware (registers and special flags) ret = fseek(f, sav.regs_offset, SEEK_SET); fread(®s, sizeof(regs), 1, f); // Load I/O ports state ret = fseek(f, sav.io_offset, SEEK_SET); fread(tihw.io , tihw.io_size, 1, f); fread(tihw.io2, tihw.io2_size, 1, f); fread(tihw.io3, tihw.io3_size, 1, f); // Load RAM content ret = fseek(f, sav.ram_offset, SEEK_SET); fread(tihw.ram, tihw.ram_size, 1, f); // Load extra infos ret = fseek(f, sav.misc_offset, SEEK_SET); fread(&thw, sizeof(Ti68kHardware), 1, f); tihw.on_off = thw.on_off; tihw.lcd_adr = thw.lcd_adr; tihw.contrast = thw.contrast; tihw.protect = thw.protect; tihw.archive_limit = thw.archive_limit; memcpy(tihw.ram_exec, thw.ram_exec, sizeof(tihw.ram_exec)); tihw.rtc3_beg = thw.rtc3_beg; tihw.rtc3_load = thw.rtc3_load; rtc3_state_load(); // Load modified FLASH segments ret = fseek(f, sav.rom_offset, SEEK_SET); for(i=0; i<wsm.nblocks; i++) { fread(&wsm.changed[i], sizeof(int), 1, f); if(wsm.changed[i]) fread(&tihw.rom[i<<16], 1, 65536, f); } // Load bkpts ti68k_bkpt_clear_access(); ti68k_bkpt_clear_range(); ti68k_bkpt_clear_address(); ti68k_bkpt_clear_exception(); ti68k_bkpt_clear_pgmentry(); ret = fseek(f, sav.bkpts_offset, SEEK_SET); load_bkpt(f, &bkpts.code); load_bkpt(f, &bkpts.exception); load_bkpt(f, &bkpts.pgmentry); load_bkpt(f, &bkpts.mem_rb); load_bkpt(f, &bkpts.mem_rw); load_bkpt(f, &bkpts.mem_rl); load_bkpt(f, &bkpts.mem_wb); load_bkpt(f, &bkpts.mem_ww); load_bkpt(f, &bkpts.mem_wl); load_bkpt2(f, &bkpts.mem_rng_r); load_bkpt2(f, &bkpts.mem_rng_w); if(sav.revision >= 21) load_bkpt3(f, &bkpts.bits); // Update UAE structures m68k_setpc(m68k_getpc()); MakeFromSR(); fclose(f); // Update SAV file to latest revision if(sav.revision < SAV_REVISION) { ti68k_state_save(filename); } return 0; }
Uint8 tmc_scr1_read3(void) { Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200003 PC=$%08x\n",m68k_getpc()); return tmc.scr1; }
static void dummy_bput(uaecptr addr, uae_u32 b) { illegal_trace(write_log ("Illegal bput at %08lx PC=%08x\n", (long)addr,m68k_getpc())); }
void comp_fscc_opp (uae_u32 opcode, uae_u16 extra) { uae_u32 ad; int cc; int reg; if (!currprefs.compfpu) { FAIL(1); return; } #if DEBUG_FPP write_log (_T("JIT: fscc_opp at %08lx\n"), M68K_GETPC); #endif if (extra & 0x20) { /* only cc from 00 to 1f are defined */ FAIL(1); return; } if ((opcode & 0x38) != 0) { /* We can only do to integer register */ FAIL(1); return; } fflags_into_flags(S2); reg = (opcode & 7); mov_l_ri(S1,255); mov_l_ri(S4,0); switch (extra & 0x0f) { /* according to fpp.c, the 0x10 bit is ignored */ case 0: break; /* set never */ case 1: mov_l_rr(S2,S4); cmov_l_rr(S4,S1,4); cmov_l_rr(S4,S2,10); break; case 2: cmov_l_rr(S4,S1,7); break; case 3: cmov_l_rr(S4,S1,3); break; case 4: mov_l_rr(S2,S4); cmov_l_rr(S4,S1,2); cmov_l_rr(S4,S2,10); break; case 5: mov_l_rr(S2,S4); cmov_l_rr(S4,S1,6); cmov_l_rr(S4,S2,10); break; case 6: cmov_l_rr(S4,S1,5); break; case 7: cmov_l_rr(S4,S1,11); break; case 8: cmov_l_rr(S4,S1,10); break; case 9: cmov_l_rr(S4,S1,4); break; case 10: cmov_l_rr(S4,S1,10); cmov_l_rr(S4,S1,7); break; case 11: cmov_l_rr(S4,S1,4); cmov_l_rr(S4,S1,3); break; case 12: cmov_l_rr(S4,S1,2); break; case 13: cmov_l_rr(S4,S1,6); break; case 14: cmov_l_rr(S4,S1,5); cmov_l_rr(S4,S1,10); break; case 15: mov_l_rr(S4,S1); break; } if (!(opcode & 0x38)) mov_b_rr(reg,S4); #if 0 else { abort(); if (!comp_fp_adr (opcode)) { m68k_setpc (m68k_getpc () - 4); op_illg (opcode, regs); } else put_byte (ad, cc ? 0xff : 0x00); } #endif }