From 6c6a62a0e0912e4f63ddd87e2cbc88b6582d7f50 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 9 Sep 2009 18:44:14 +0300 Subject: [PATCH] imported winuaesrc2000b14.zip --- audio.c | 2 +- blitter.c | 15 +- bsdsocket.c | 6 +- cia.c | 6 +- custom.c | 15 +- debug.c | 25 ++- filesys.c | 14 +- fpp.c | 22 +- gencpu.c | 119 ++++++---- include/blitter.h | 1 + include/debug.h | 1 + include/newcpu.h | 24 +- include/savestate.h | 3 + inputdevice.c | 4 +- newcpu.c | 127 +++++++---- od-win32/ahidsound_dsonly.c | 19 ++ od-win32/bsdsock.c | 122 +++++------ od-win32/dinput.c | 4 +- od-win32/win32.h | 4 +- od-win32/winuaechangelog.txt | 21 ++ savestate.c | 14 +- table68k | 414 ++++++++++++++++++----------------- zfile.c | 49 ++++- 23 files changed, 635 insertions(+), 396 deletions(-) diff --git a/audio.c b/audio.c index ce1bd6a3..aef04935 100644 --- a/audio.c +++ b/audio.c @@ -1638,7 +1638,7 @@ void audio_hsync (int hpos) write_log (L"%d:>5: LEN=%d PT=%08X\n", nr, cdp->wlen, cdp->pt); #endif } - cdp->dat2 = chipmem_agnus_wget (cdp->pt); + cdp->dat2 = last_custom_value1 = chipmem_agnus_wget (cdp->pt); if (cdp->request_word >= 2) handle2 = 1; if (chan_ena) { diff --git a/blitter.c b/blitter.c index b12d3488..92b6db1b 100644 --- a/blitter.c +++ b/blitter.c @@ -268,6 +268,11 @@ STATIC_INLINE int channel_pos (int cycles) return cycles; } +int blitter_channel_state (void) +{ + return channel_state (blit_cyclecounter); +} + extern int is_bitplane_dma (int hpos); STATIC_INLINE int canblit (int hpos) { @@ -296,7 +301,7 @@ static void blitter_interrupt (int hpos, int done) static void blitter_done (int hpos) { ddat1use = ddat2use = 0; - bltstate = blit_startcycles == 0 ? BLT_done : BLT_init; + bltstate = blit_startcycles == 0 || !currprefs.blitter_cycle_exact ? BLT_done : BLT_init; blitter_interrupt (hpos, 1); blitter_done_notify (hpos); if (debug_dma) @@ -641,6 +646,8 @@ static void decide_blitter_line (int hsync, int hpos) for (;;) { int v = canblit (last_blitter_hpos); + blitter_nasty++; + if (!v) { blit_misscyclecounter++; break; @@ -648,6 +655,7 @@ static void decide_blitter_line (int hsync, int hpos) if ((!dmaen (DMA_BLITTER) || v <= 0) && (c == 3 || c == 4)) { blit_misscyclecounter++; + blitter_nasty++; break; } @@ -752,7 +760,6 @@ void blitter_handler (uae_u32 data) blitter_stuck = 0; if (blit_slowdown > 0 && !currprefs.immediate_blits) { event2_newevent (ev2_blitter, blit_slowdown); - blit_misscyclecounter = blit_slowdown; blit_slowdown = -1; return; } @@ -1317,7 +1324,7 @@ static void do_blitter2 (int hpos, int copper) if (currprefs.immediate_blits) cycles = 1; - blit_cyclecounter = cycles * blit_diag[0]; + blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1)); event2_newevent (ev2_blitter, blit_cyclecounter); } @@ -1351,7 +1358,7 @@ void maybe_blit (int hpos, int hack) #ifdef BLITTER_DEBUG_NOWAIT warned = 10; write_log (L"program does not wait for blitter PC=%08x\n", M68K_GETPC); - activate_debugger (); + //activate_debugger (); //blitter_done (hpos); #endif } diff --git a/bsdsocket.c b/bsdsocket.c index daeb7647..583bb43d 100644 --- a/bsdsocket.c +++ b/bsdsocket.c @@ -160,7 +160,7 @@ BOOL checksd(SB, int sd) return TRUE; } } - BSDTRACE(("checksd FALSE s 0x%x sd %d\n",s,sd)); + BSDTRACE((L"checksd FALSE s 0x%x sd %d\n",s,sd)); return FALSE; } @@ -1210,8 +1210,8 @@ static uae_u32 REGPARAM2 bsdsocklib_SocketBaseTagList (TrapContext *context) default: if (currtag & TAG_USER) { BSDTRACE ((L"SBTM_")); - BSDTRACE ((currtag & 0x0001 ? "SET" : "GET")); - BSDTRACE ((currtag & 0x8000 ? "REF(" : "VAL(")); + BSDTRACE ((currtag & 0x0001 ? L"SET" : L"GET")); + BSDTRACE ((currtag & 0x8000 ? L"REF(" : L"VAL(")); switch ((currtag >> 1) & SBTS_CODE) { case SBTC_BREAKMASK: diff --git a/cia.c b/cia.c index 0817bc45..a95b7b13 100644 --- a/cia.c +++ b/cia.c @@ -943,18 +943,18 @@ static void WriteCIAA (uae_u16 addr,uae_u8 val) CIA_calctimers (); break; case 13: - setclr(&ciaaimask,val); + setclr (&ciaaimask,val); break; case 14: CIA_update (); val &= 0x7f; /* bit 7 is unused */ + if (!(ciaacra & 0x40) && (val & 0x40)) + kback = 1; ciaacra = val; if (ciaacra & 0x10) { ciaacra &= ~0x10; ciaata = ciaala; } - if (ciaacra & 0x40) - kback = 1; CIA_calctimers (); break; case 15: diff --git a/custom.c b/custom.c index 274005d1..ed8893a4 100644 --- a/custom.c +++ b/custom.c @@ -4254,7 +4254,7 @@ static void update_copper (int until_hpos) vp1 = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); hp1 = c_hpos & (cop_state.saved_i2 & 0xFE); - if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || ! (DMACONR (old_hpos) & 0x4000))) + if ((vp1 > vcmp || (vp1 == vcmp && hp1 >= hcmp)) && ((cop_state.saved_i2 & 0x8000) != 0 || bltstate == BLT_done)) cop_state.ignore_next = 1; cop_state.state = COP_read1; @@ -5794,6 +5794,8 @@ STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (int hpos, uaecptr addr, int noput * and finally returns either all ones or something weird if DMA happens * in next (or previous) cycle.. FIXME. * + * OCS-only special case: DFF000 (BLTDAT) will always return whatever was left in bus + * * AGA: * only writes to custom registers change last value, read returns * last value which then changes to all ones (following read will return @@ -5811,8 +5813,17 @@ STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (int hpos, uaecptr addr, int noput if (currprefs.chipset_mask & CSMASK_AGA) { v = l; last_custom_value1 = 0xffff; - } else { + } else if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { v = old; + } else { + if ((addr & 0x1fe) == 0) { + if (is_cycle_ce ()) + v = old; + else + v = l; + } else { + v = old; + } } #if CUSTOM_DEBUG > 0 write_log (L"%08X read = %04X. Value written=%04X PC=%08x\n", 0xdff000 | addr, v, l, M68K_GETPC); diff --git a/debug.c b/debug.c index 5ff9a1c8..6d5a4f6d 100644 --- a/debug.c +++ b/debug.c @@ -118,7 +118,7 @@ static TCHAR help[] = { L" D[idxzs <[max diff]>] Deep trainer. i=new value must be larger, d=smaller,\n" L" x = must be same, z = must be different, s = restart.\n" L" W
Write into Amiga memory\n" - L" w
[] (read/write/opcode/freeze)\n" + L" w
[] (read/write/opcode/freeze/mustchange)\n" L" Add/remove memory watchpoints\n" L" wd [<0-1>] Enable illegal access logger. 1 = enable break.\n" L" S Save a block of Amiga memory\n" @@ -1508,6 +1508,8 @@ static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp) uaecptr addr2 = m->addr; uaecptr addr3 = addr2 + m->size; int rwi2 = m->rwi; + uae_u32 oldval = 0; + int isoldval = 0; brk = 0; if (m->size == 0) @@ -1523,6 +1525,16 @@ static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp) if (!brk) continue; + if (mem_banks[addr >> 16]->check (addr, size)) { + uae_u8 *p = mem_banks[addr >> 16]->xlateaddr (addr); + if (size == 1) + oldval = p[0]; + else if (size == 2) + oldval = (p[0] << 8) | p[1]; + else + oldval = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0); + isoldval = 1; + } if (!m->frozen && m->val_enabled) { int trigger = 0; @@ -1547,6 +1559,11 @@ static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp) continue; } + if (m->mustchange && rwi == 2 && isoldval) { + if (oldval == *valp) + continue; + } + if (m->modval_written) { if (!rwi) { brk = 0; @@ -1866,6 +1883,8 @@ void memwatch_dump2 (TCHAR *buf, int bufsize, int num) buf = buf_out (buf, &bufsize, L" =%X", mwn->val); if (mwn->modval_written) buf = buf_out (buf, &bufsize, L" =M"); + if (mwn->mustchange) + buf = buf_out (buf, &bufsize, L" C"); buf = buf_out (buf, &bufsize, L"\n"); } } @@ -1977,8 +1996,10 @@ static void memwatch (TCHAR **c) } ignore_ws (c); if (more_params (c)) { - if (_totupper(**c) == 'M') { + if (_totupper (**c) == 'M') { mwn->modval_written = 1; + } else if (_totupper (**c) == 'C') { + mwn->mustchange = 1; } else { mwn->val = readhex (c); mwn->val_enabled = 1; diff --git a/filesys.c b/filesys.c index 771a67ca..9a6bf3d8 100644 --- a/filesys.c +++ b/filesys.c @@ -2769,7 +2769,7 @@ get_fileinfo (Unit *unit, dpacket packet, uaecptr info, a_inode *aino) put_byte (info + i, 0), i++; xfree (x2); - put_long (info + 116, fsdb_can ? aino->amigaos_mode : fsdb_mode_supported(aino)); + put_long (info + 116, fsdb_can ? aino->amigaos_mode : fsdb_mode_supported (aino)); put_long (info + 124, statbuf.st_size > MAXFILESIZE32 ? MAXFILESIZE32 : statbuf.st_size); #ifdef HAVE_ST_BLOCKS put_long (info + 128, statbuf.st_blocks); @@ -4140,7 +4140,7 @@ static int relock_do(Unit *unit, a_inode *a1) return wehavekeys; } -static void relock_re(Unit *unit, a_inode *a1, a_inode *a2, int failed) +static void relock_re (Unit *unit, a_inode *a1, a_inode *a2, int failed) { Key *k1, *knext; @@ -4334,11 +4334,11 @@ action_rename_object (Unit *unit, dpacket packet) int ret = -1; /* maybe we have open file handles that caused failure? */ write_log (L"rename '%s' -> '%s' failed, trying relocking..\n", a1->nname, a2->nname); - wehavekeys = relock_do(unit, a1); + wehavekeys = relock_do (unit, a1); /* try again... */ ret = my_rename (a1->nname, a2->nname); /* restore locks */ - relock_re(unit, a1, a2, ret == -1 ? 1 : 0); + relock_re (unit, a1, a2, ret == -1 ? 1 : 0); if (ret == -1) { delete_aino (unit, a2); PUT_PCK_RES1 (packet, DOS_FALSE); @@ -4414,7 +4414,7 @@ action_flush (Unit *unit, dpacket packet) { TRACE((L"ACTION_FLUSH()\n")); PUT_PCK_RES1 (packet, DOS_TRUE); - flush_cache(unit, 0); + flush_cache (unit, 0); } static void @@ -4423,14 +4423,14 @@ action_more_cache (Unit *unit, dpacket packet) TRACE((L"ACTION_MORE_CACHE()\n")); PUT_PCK_RES1 (packet, 50); /* bug but AmigaOS expects it */ if (GET_PCK_ARG1 (packet) != 0) - flush_cache(unit, 0); + flush_cache (unit, 0); } static void action_inhibit (Unit *unit, dpacket packet) { PUT_PCK_RES1 (packet, DOS_TRUE); - flush_cache(unit, 0); + flush_cache (unit, 0); unit->inhibited = GET_PCK_ARG1 (packet); TRACE((L"ACTION_INHIBIT(%d:%d)\n", unit->unit, unit->inhibited)); } diff --git a/fpp.c b/fpp.c index e991d669..11ce071e 100644 --- a/fpp.c +++ b/fpp.c @@ -30,7 +30,7 @@ STATIC_INLINE int isinrom (void) { - return (munge24 (m68k_getpc ()) & 0xFFF80000) == 0xF80000; + return (munge24 (m68k_getpc ()) & 0xFFF80000) == 0xF80000 && !currprefs.mmu_model; } static uae_u32 xhex_pi[] ={0x2168c235, 0xc90fdaa2, 0x4000}; @@ -764,7 +764,7 @@ STATIC_INLINE int get_fp_ad (uae_u32 opcode, uae_u32 * ad) return 1; } -STATIC_INLINE int fpp_cond (uae_u32 opcode, int contition) +STATIC_INLINE int fpp_cond (int condition) { int N = (regs.fp_result < 0.0); int Z = (regs.fp_result == 0.0); @@ -777,7 +777,7 @@ STATIC_INLINE int fpp_cond (uae_u32 opcode, int contition) if (NotANumber) N=Z=0; - switch (contition) { + switch (condition) { case 0x00: return 0; case 0x01: @@ -860,7 +860,7 @@ void fpuop_dbcc (uae_u32 opcode, uae_u16 extra) return; disp = (uae_s32) (uae_s16) next_iword_fpu (); - cc = fpp_cond (opcode, extra & 0x3f); + cc = fpp_cond (extra & 0x3f); if (cc == -1) { fpu_op_illg (opcode, 4); } else if (!cc) { @@ -885,7 +885,7 @@ void fpuop_scc (uae_u32 opcode, uae_u16 extra) if (fault_if_no_fpu (opcode, 4)) return; - cc = fpp_cond (opcode, extra & 0x3f); + cc = fpp_cond (extra & 0x3f); if (cc == -1) { fpu_op_illg (opcode, 4); } else if ((opcode & 0x38) == 0) { @@ -899,7 +899,7 @@ void fpuop_scc (uae_u32 opcode, uae_u16 extra) } } -void fpuop_trapcc (uae_u32 opcode, uaecptr oldpc) +void fpuop_trapcc (uae_u32 opcode, uaecptr oldpc, uae_u16 extra) { int cc; @@ -910,7 +910,7 @@ void fpuop_trapcc (uae_u32 opcode, uaecptr oldpc) if (fault_if_no_fpu (opcode, m68k_getpc() - oldpc)) return; - cc = fpp_cond (opcode, opcode & 0x3f); + cc = fpp_cond (extra & 0x3f); if (cc == -1) { fpu_op_illg (opcode, m68k_getpc () - oldpc); } @@ -929,7 +929,7 @@ void fpuop_bcc (uae_u32 opcode, uaecptr pc, uae_u32 extra) if (fault_if_no_fpu (opcode, m68k_getpc () - pc)) return; - cc = fpp_cond (opcode, opcode & 0x3f); + cc = fpp_cond (opcode & 0x3f); if (cc == -1) { fpu_op_illg (opcode, m68k_getpc () - pc); } else if (cc) { @@ -1708,7 +1708,7 @@ uae_u8 *restore_fpu (uae_u8 *src) int i; uae_u32 flags; - changed_prefs.fpu_model = currprefs.fpu_model = restore_u32(); + changed_prefs.fpu_model = currprefs.fpu_model = restore_u32 (); flags = restore_u32 (); for (i = 0; i < 8; i++) { uae_u32 w1 = restore_u32 (); @@ -1724,7 +1724,7 @@ uae_u8 *restore_fpu (uae_u8 *src) restore_u32(); restore_u32(); } - write_log (L"FPU=%d\n", currprefs.fpu_model); + write_log (L"FPU: %d\n", currprefs.fpu_model); return src; } @@ -1739,7 +1739,7 @@ uae_u8 *save_fpu (int *len, uae_u8 *dstptr) if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = (uae_u8*)malloc(4+4+8*10+4+4+4+4+4); + dstbak = dst = malloc (4+4+8*10+4+4+4+4+4); save_u32 (currprefs.fpu_model); save_u32 (0x80000000); for (i = 0; i < 8; i++) { diff --git a/gencpu.c b/gencpu.c index 5e852b89..f5aad0cd 100644 --- a/gencpu.c +++ b/gencpu.c @@ -41,8 +41,6 @@ static int count_read_ea, count_write_ea, count_cycles_ea; static int optimized_flags; -static int cpulengths[65536]; - #define GF_APDI 1 #define GF_AD8R 2 #define GF_PC8R 4 @@ -62,6 +60,13 @@ static int *opcode_last_postfix; static unsigned long *counts; static int generate_stbl; +#define GENA_GETV_NO_FETCH 0 +#define GENA_GETV_FETCH 1 +#define GENA_GETV_FETCH_ALIGN 2 +#define GENA_MOVEM_DO_INC 0 +#define GENA_MOVEM_NO_INC 1 +#define GENA_MOVEM_MOVE16 2 + static void read_counts (void) { FILE *file; @@ -103,7 +108,7 @@ static int endlabelno = 0; static int need_endlabel; static int n_braces, limit_braces; -static int m68k_pc_offset, m68k_pc_offset_sum; +static int m68k_pc_offset; static int insn_n_cycles, insn_n_cycles020; static void fpulimit (void) @@ -440,6 +445,21 @@ static void fill_prefetch_finish (void) fill_prefetch_1 (m68k_pc_offset); } +static void setpc (const char *format, ...) +{ + va_list parms; + char buffer[1000]; + + va_start (parms, format); + _vsnprintf (buffer, 1000 - 1, format, parms); + va_end (parms); + + if (using_mmu) + printf ("\tm68k_setpc_mmu (%s);\n", buffer); + else + printf ("\tm68k_setpc (%s);\n", buffer); +} + static void incpc (const char *format, ...) { va_list parms; @@ -460,7 +480,15 @@ static void sync_m68k_pc (void) if (m68k_pc_offset == 0) return; incpc ("%d", m68k_pc_offset); - m68k_pc_offset_sum += m68k_pc_offset; + m68k_pc_offset = 0; +} + +static void gen_set_fault_pc (void) +{ + if (!using_mmu) + return; + sync_m68k_pc (); + printf ("\tregs.fault_pc = m68k_getpci ();\n"); m68k_pc_offset = 0; } @@ -839,6 +867,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha case absl: case PC16: case PC8r: + gen_set_fault_pc (); if (using_ce020) { switch (size) { case sz_byte: @@ -1474,7 +1503,6 @@ static void gen_opcode (unsigned long int opcode) insn_n_cycles020 = 0; start_brace (); - m68k_pc_offset_sum = 0; m68k_pc_offset = 2; switch (curi->plev) { case 0: /* not privileged */ @@ -1816,8 +1844,9 @@ static void gen_opcode (unsigned long int opcode) genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); break; case i_CMPM: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); + genamodex (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + genamodef (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); fill_prefetch_next (); start_brace (); genflags (flag_cmp, curi->size, "newv", "src", "dst"); @@ -1968,6 +1997,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_TRAP: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + gen_set_fault_pc (); sync_m68k_pc (); printf ("\tException (src + 32, 0);\n"); did_prefetch = 1; @@ -2024,7 +2054,8 @@ static void gen_opcode (unsigned long int opcode) if (cpu_level == 0) { genamode (Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL); genamode (Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL); - printf ("\tregs.sr = sr; m68k_setpc (pc);\n"); + printf ("\tregs.sr = sr;\n"); + setpc ("pc"); printf ("\tMakeFromSR ();\n"); } else { int old_brace_level = n_braces; @@ -2040,25 +2071,41 @@ static void gen_opcode (unsigned long int opcode) fill_prefetch_full (); break; case i_RTD: - genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); - genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0); - printf ("\tm68k_areg (regs, 7) += offs;\n"); - printf ("\tif (pc & 1)\n"); - printf ("\t\texception3 (0x%04X, m68k_getpc (), pc);\n", opcode); - printf ("\telse\n"); - printf ("\t\tm68k_setpc (pc);\n"); + if (using_mmu) { + genamode (curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); + genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); + printf ("\tm68k_areg(regs, 7) += offs;\n"); + setpc ("pc"); + } else { + genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0); + printf ("\tm68k_areg (regs, 7) += offs;\n"); + printf ("\tif (pc & 1)\n"); + printf ("\t\texception3 (0x%04X, m68k_getpc (), pc);\n", opcode); + printf ("\telse\n"); + setpc ("pc"); + } /* PC is set and prefetch filled. */ m68k_pc_offset = 0; fill_prefetch_full (); break; case i_LINK: - genamode (Apdi, "7", sz_long, "old", 2, 0, GF_AA); - genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA); - genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0); - genastore ("src", Apdi, "7", sz_long, "old"); - genastore ("m68k_areg (regs, 7)", curi->smode, "srcreg", sz_long, "src"); - printf ("\tm68k_areg (regs, 7) += offs;\n"); - fill_prefetch_next (); + if (using_mmu) { + genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); + genamode (Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, 0); + genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); + genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src"); + printf ("\tm68k_areg(regs, 7) += offs;\n"); + genastore ("src", Apdi, "7", sz_long, "old"); + } else { + genamode (Apdi, "7", sz_long, "old", 2, 0, GF_AA); + genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0); + genastore ("src", Apdi, "7", sz_long, "old"); + genastore ("m68k_areg (regs, 7)", curi->smode, "srcreg", sz_long, "src"); + printf ("\tm68k_areg (regs, 7) += offs;\n"); + fill_prefetch_next (); + } break; case i_UNLK: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); @@ -2095,7 +2142,8 @@ static void gen_opcode (unsigned long int opcode) genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); genamodef (Aipi, "7", sz_word, "sr", 1, 0, 0); printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n"); - printf ("\tregs.sr |= sr; m68k_setpc (pc);\n"); + printf ("\tregs.sr |= sr;\n"); + setpc ("pc"); printf ("\tMakeFromSR ();\n"); m68k_pc_offset = 0; fill_prefetch_full (); @@ -2113,7 +2161,7 @@ static void gen_opcode (unsigned long int opcode) } if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16) addcycles000 (2); - printf ("\tm68k_setpc (srca);\n"); + setpc ("srca"); m68k_pc_offset = 0; fill_prefetch_1 (0); if (curi->smode == Ad8r || curi->smode == PC8r) @@ -2139,8 +2187,7 @@ static void gen_opcode (unsigned long int opcode) } if (curi->smode == Ad16 || curi->smode == Ad8r || curi->smode == absw || curi->smode == PC16 || curi->smode == PC8r) addcycles000 (2); -// if (using_ce && (curi->smode == Ad8r || curi->smode == PC8r)) - printf ("\tm68k_setpc (srca);\n"); + setpc ("srca"); m68k_pc_offset = 0; fill_prefetch_full (); break; @@ -2276,7 +2323,7 @@ static void gen_opcode (unsigned long int opcode) addcycles000_2 ("\t\t", 2); addcycles_ce020 (3); printf ("\t}\n"); - printf ("\tm68k_setpc (oldpc + %d);\n", m68k_pc_offset); + setpc ("oldpc + %d", m68k_pc_offset); m68k_pc_offset = 0; fill_prefetch_full (); insn_n_cycles = 12; @@ -2997,8 +3044,8 @@ static void gen_opcode (unsigned long int opcode) printf ("\t} else {\n"); genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, ""); printf ("\t}\n"); - pop_braces (old_brace_level); sync_m68k_pc (); + pop_braces (old_brace_level); } } break; @@ -3022,8 +3069,6 @@ static void gen_opcode (unsigned long int opcode) need_endlabel = 1; break; case i_DIVL: - sync_m68k_pc (); - start_brace (); printf ("\tuaecptr oldpc = m68k_getpc ();\n"); genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); @@ -3140,6 +3185,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); printf ("\tval = (val | ((uae_u16)%s (m68k_areg (regs, srcreg)) << 8)) + %s;\n", srcb, gen_nextiword (0)); printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); + gen_set_fault_pc (); printf ("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb); } break; @@ -3161,6 +3207,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); printf ("\t%s (m68k_areg (regs, dstreg),val);\n", dstb); printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); + gen_set_fault_pc (); printf ("\t%s (m68k_areg (regs, dstreg),val >> 8);\n", dstb); } } @@ -3204,13 +3251,12 @@ static void gen_opcode (unsigned long int opcode) break; case i_FTRAPcc: fpulimit(); - sync_m68k_pc (); - start_brace (); printf ("\tuaecptr oldpc = m68k_getpc ();\n"); + printf ("\tuae_u16 extra = %s;\n", gen_nextiword (0)); if (curi->smode != am_unknown && curi->smode != am_illg) genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); sync_m68k_pc (); - printf ("\tfpuop_trapcc (opcode, oldpc);\n"); + printf ("\tfpuop_trapcc (opcode, oldpc, extra);\n"); break; case i_FBcc: fpulimit(); @@ -3479,10 +3525,10 @@ static void generate_one_opcode (int rp) if (opcode_next_clev[rp] != cpu_level) { char *name = ua (lookuptab[idx].name); if (generate_stbl) - fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d, %d }, /* %s */\n", + fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n", (using_ce || using_ce020) ? "(cpuop_func*)" : "", opcode, opcode_last_postfix[rp], - opcode, cpulengths[opcode], name); + opcode, name); xfree (name); return; } @@ -3580,15 +3626,14 @@ static void generate_one_opcode (int rp) printf("#endif\n"); opcode_next_clev[rp] = next_cpu_level; opcode_last_postfix[rp] = postfix; - cpulengths[opcode] = m68k_pc_offset_sum; if (generate_stbl) { char *name = ua (lookuptab[idx].name); if (i68000) fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n"); - fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d, %d }, /* %s */\n", + fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n", (using_ce || using_ce020) ? "(cpuop_func*)" : "", - opcode, postfix, opcode, m68k_pc_offset_sum, name); + opcode, postfix, opcode, name); if (i68000) fprintf (stblfile, "#endif\n"); xfree (name); diff --git a/include/blitter.h b/include/blitter.h index 8eaebd7d..ba3fe1dc 100644 --- a/include/blitter.h +++ b/include/blitter.h @@ -40,6 +40,7 @@ extern void decide_blitter (int hpos); extern int blitter_need (int hpos); extern void blitter_done_notify (int hpos); extern void blitter_slowdown (int, int, int, int); +extern int blitter_channel_state (void); typedef void blitter_func(uaecptr, uaecptr, uaecptr, uaecptr, struct bltinfo *); diff --git a/include/debug.h b/include/debug.h index 2e0c0821..2271081d 100644 --- a/include/debug.h +++ b/include/debug.h @@ -51,6 +51,7 @@ struct memwatch_node { int size; int rwi; uae_u32 val, valmask; + int mustchange; int val_enabled; uae_u32 modval; int modval_written; diff --git a/include/newcpu.h b/include/newcpu.h index e10d5ecd..07c96836 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -55,7 +55,6 @@ typedef void REGPARAM3 cpuop_func_ce (uae_u32) REGPARAM; struct cputbl { cpuop_func *handler; uae_u16 opcode; - int length; }; #ifdef JIT @@ -193,7 +192,7 @@ STATIC_INLINE void unset_special (uae_u32 x) STATIC_INLINE void m68k_setpc (uaecptr newpc) { regs.pc_p = regs.pc_oldp = get_real_address (newpc); - regs.pc = newpc; + regs.fault_pc = regs.pc = newpc; } STATIC_INLINE uaecptr m68k_getpc (void) @@ -209,9 +208,14 @@ STATIC_INLINE uaecptr m68k_getpc_p (uae_u8 *p) #define m68k_incpc(o) ((regs).pc_p += (o)) +STATIC_INLINE void m68k_setpc_mmu (uaecptr newpc) +{ + regs.fault_pc = regs.pc = newpc; + regs.pc_p = regs.pc_oldp = 0; +} STATIC_INLINE void m68k_setpci (uaecptr newpc) { - regs.pc = newpc; + regs.fault_pc = regs.pc = newpc; } STATIC_INLINE uaecptr m68k_getpci (void) { @@ -334,7 +338,7 @@ extern void mmu_op30 (uaecptr, uae_u32, int, uaecptr); extern void fpuop_arithmetic(uae_u32, uae_u16); extern void fpuop_dbcc(uae_u32, uae_u16); extern void fpuop_scc(uae_u32, uae_u16); -extern void fpuop_trapcc(uae_u32, uaecptr); +extern void fpuop_trapcc(uae_u32, uaecptr, uae_u16); extern void fpuop_bcc(uae_u32, uaecptr, uae_u32); extern void fpuop_save(uae_u32); extern void fpuop_restore(uae_u32); @@ -354,17 +358,17 @@ extern void fill_prefetch_slow (void); /* 68060 */ extern const struct cputbl op_smalltbl_0_ff[]; -extern const struct cputbl op_smalltbl_20_ff[]; +extern const struct cputbl op_smalltbl_20_ff[]; // CE /* 68040 */ extern const struct cputbl op_smalltbl_1_ff[]; -extern const struct cputbl op_smalltbl_21_ff[]; +extern const struct cputbl op_smalltbl_21_ff[]; // CE extern const struct cputbl op_smalltbl_31_ff[]; // MMU /* 68030 */ extern const struct cputbl op_smalltbl_2_ff[]; -extern const struct cputbl op_smalltbl_22_ff[]; +extern const struct cputbl op_smalltbl_22_ff[]; // CE /* 68020 */ extern const struct cputbl op_smalltbl_3_ff[]; -extern const struct cputbl op_smalltbl_23_ff[]; +extern const struct cputbl op_smalltbl_23_ff[]; // CE /* 68010 */ extern const struct cputbl op_smalltbl_4_ff[]; /* 68000 */ @@ -373,13 +377,9 @@ extern const struct cputbl op_smalltbl_5_ff[]; extern const struct cputbl op_smalltbl_11_ff[]; /* 68000 slow but compatible and cycle-exact. */ extern const struct cputbl op_smalltbl_12_ff[]; -/* 68020 slow but compatible */ -extern const struct cputbl op_smalltbl_13_ff[]; extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl"); -void newcpu_showstate (void); - #ifdef JIT extern void flush_icache (uaecptr, int n); extern void compemu_reset (void); diff --git a/include/savestate.h b/include/savestate.h index 6190f612..fe294f85 100644 --- a/include/savestate.h +++ b/include/savestate.h @@ -42,6 +42,9 @@ extern uae_u8 *restore_cpu (uae_u8 *); extern void restore_cpu_finish (void); extern uae_u8 *save_cpu (int *, uae_u8 *); +extern uae_u8 *restore_mmu (uae_u8 *); +extern uae_u8 *save_mmu (int *, uae_u8 *); + extern uae_u8 *restore_fpu (uae_u8 *); extern uae_u8 *save_fpu (int *, uae_u8 *); diff --git a/inputdevice.c b/inputdevice.c index 5a4fea4d..6af2855c 100644 --- a/inputdevice.c +++ b/inputdevice.c @@ -3007,8 +3007,8 @@ static void setcd32 (int joy, int n) joysticks[joy].eventid[ID_BUTTON_OFFSET + 1][0] = n ? INPUTEVENT_JOY2_CD32_BLUE : INPUTEVENT_JOY1_CD32_BLUE; joysticks[joy].eventid[ID_BUTTON_OFFSET + 2][0] = n ? INPUTEVENT_JOY2_CD32_GREEN : INPUTEVENT_JOY1_CD32_GREEN; joysticks[joy].eventid[ID_BUTTON_OFFSET + 3][0] = n ? INPUTEVENT_JOY2_CD32_YELLOW : INPUTEVENT_JOY1_CD32_YELLOW; - joysticks[joy].eventid[ID_BUTTON_OFFSET + 4][0] = n ? INPUTEVENT_JOY2_CD32_FFW : INPUTEVENT_JOY1_CD32_FFW; - joysticks[joy].eventid[ID_BUTTON_OFFSET + 5][0] = n ? INPUTEVENT_JOY2_CD32_RWD : INPUTEVENT_JOY1_CD32_RWD; + joysticks[joy].eventid[ID_BUTTON_OFFSET + 4][0] = n ? INPUTEVENT_JOY2_CD32_RWD : INPUTEVENT_JOY1_CD32_RWD; + joysticks[joy].eventid[ID_BUTTON_OFFSET + 5][0] = n ? INPUTEVENT_JOY2_CD32_FFW : INPUTEVENT_JOY1_CD32_FFW; joysticks[joy].eventid[ID_BUTTON_OFFSET + 6][0] = n ? INPUTEVENT_JOY2_CD32_PLAY : INPUTEVENT_JOY1_CD32_PLAY; } #endif diff --git a/newcpu.c b/newcpu.c index ba2cf1dd..5153b9db 100644 --- a/newcpu.c +++ b/newcpu.c @@ -67,7 +67,6 @@ int movem_index2[256]; int movem_next[256]; cpuop_func *cpufunctbl[65536]; -static int cpufunclen[65536]; struct mmufixup mmufixup; @@ -249,14 +248,11 @@ static void build_cpufunctbl (void) abort (); } - for (opcode = 0; opcode < 65536; opcode++) { + for (opcode = 0; opcode < 65536; opcode++) cpufunctbl[opcode] = op_illg_1; - cpufunclen[opcode] = -1; - } for (i = 0; tbl[i].handler != NULL; i++) { opcode = tbl[i].opcode; cpufunctbl[opcode] = tbl[i].handler; - cpufunclen[opcode] = tbl[i].length; } /* hack fpu to 68000/68010 mode */ @@ -287,7 +283,6 @@ static void build_cpufunctbl (void) if (f == op_illg_1) abort (); cpufunctbl[opcode] = f; - cpufunclen[opcode] = cpufunclen[idx]; opcnt++; } } @@ -1438,6 +1433,7 @@ static void Exception_mmu (int nr, uaecptr oldpc) mmu_set_super (1); } if (nr == 2) { + // bus error for (i = 0 ; i < 7 ; i++) { m68k_areg (regs, 7) -= 4; @@ -1768,18 +1764,21 @@ int movec_illg (int regno) return 0; return 1; } else if (currprefs.cpu_model == 68020) { - if (regno == 3) return 1; /* 68040/060 only */ + if (regno == 3) + return 1; /* 68040/060 only */ /* 4 is >=68040, but 0x804 is in 68020 */ if (regno2 < 4 || regno == 0x804) return 0; return 1; } else if (currprefs.cpu_model == 68030) { - if (regno2 <= 2) return 0; + if (regno2 <= 2) + return 0; if (regno == 0x803 || regno == 0x804) return 0; return 1; } else if (currprefs.cpu_model == 68040) { - if (regno == 0x802) return 1; /* 68020 only */ + if (regno == 0x802) + return 1; /* 68020 only */ if (regno2 < 8) return 0; return 1; } @@ -2299,6 +2298,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode) if ((opcode & 0xF000) == 0xF000) { if (warned < 20) { write_log (L"B-Trap %x at %x (%p)\n", opcode, pc, regs.pc_p); + activate_debugger (); warned++; } Exception (0xB, 0); @@ -2967,16 +2967,39 @@ static void m68k_run_2 (void) #else +static void opcodedebug (uae_u32 pc, uae_u16 opcode) +{ + struct mnemolookup *lookup; + struct instr *dp; + uae_u32 addr; + int fault; + + if (cpufunctbl[opcode] == op_illg_1) + opcode = 0x4AFC; + dp = table68k + opcode; + for (lookup = lookuptab;lookup->mnemo != dp->mnemo; lookup++) + ; + fault = 0; + TRY(prb) { + addr = mmu_translate (pc, (regs.mmu_ssw & 4) ? 1 : 0, 0, 0); + } CATCH (prb) { + fault = 1; + } + if (!fault) { + TCHAR buf[100]; + write_log (L"PC=%08x %04x %s\n", regs.fault_pc, opcode, lookup->name); + m68k_disasm_2 (buf, 100, addr, NULL, 1, NULL, NULL, 0); + write_log (L"%s\n", buf); + } +} + /* Aranym MMU 68040 */ static void m68k_run_mmu040 (void) { - uae_u32 opcode; - - for (;;) { -#ifdef _WIN32 - __try -#endif - { + uae_u32 opcode; +retry: + TRY (prb) { + for (;;) { regs.fault_pc = m68k_getpc (); opcode = get_iword_mmu (0); count_instr (opcode); @@ -2988,31 +3011,27 @@ static void m68k_run_mmu040 (void) if (do_specialties (cpu_cycles)) return; } -#ifdef _WIN32 - } __except (GetExceptionCode () == MMUEX) { - int nextpc = 0; - // write bus errors restart at next instruction - if (regs.wb3_status & 0x80) { - //write_log (L"PC=%08x %04x %d\n", regs.fault_pc, opcode, cpufunclen[opcode]); - nextpc = 1; - } - // movem to memory? always restart the instruction + } + } CATCH (prb) { + + //opcodedebug (regs.fault_pc, opcode); + + if (regs.wb3_status & 0x80) { + // movem to memory? if ((opcode & 0xff80) == 0x4880) { regs.mmu_ssw |= MMU_SSW_CM; //write_log (L"MMU_SSW_CM\n"); - nextpc = 0; - } - if (nextpc) - regs.fault_pc += cpufunclen[opcode]; - if (mmufixup.reg >= 0) { - m68k_areg (regs, mmufixup.reg) = mmufixup.value; - mmufixup.reg = -1; } - //activate_debugger (); - Exception (2, regs.fault_pc); } -#endif - } + if (mmufixup.reg >= 0) { + m68k_areg (regs, mmufixup.reg) = mmufixup.value; + mmufixup.reg = -1; + } + //activate_debugger (); + Exception (2, regs.fault_pc); + goto retry; + } + } /* "cycle exact" 68020 */ @@ -3732,7 +3751,7 @@ uae_u8 *restore_cpu (uae_u8 *src) regs.cacr = restore_u32 (); regs.msp = restore_u32 (); /* A500 speed in 68020 mode isn't too logical.. */ - if (changed_prefs.m68k_speed == 0) + if (changed_prefs.m68k_speed == 0 && !(currprefs.cpu_cycle_exact)) currprefs.m68k_speed = changed_prefs.m68k_speed = -1; } if (model >= 68030) { @@ -3762,7 +3781,7 @@ uae_u8 *restore_cpu (uae_u8 *src) if (khz > 0 && khz < 800000) currprefs.m68k_speed = changed_prefs.m68k_speed = 0; } - write_log (L"CPU %d%s%03d, PC=%08X\n", + write_log (L"CPU: %d%s%03d, PC=%08X\n", model / 1000, flags & 1 ? L"EC" : L"", model % 1000, regs.pc); return src; @@ -3783,7 +3802,7 @@ uae_u8 *save_cpu (int *len, uae_u8 *dstptr) if (dstptr) dstbak = dst = dstptr; else - dstbak = dst = (uae_u8*)malloc (1000); + dstbak = dst = xmalloc (1000); model = currprefs.cpu_model; save_u32 (model); /* MODEL */ save_u32 (0x80000000 | (currprefs.address_space_24 ? 1 : 0)); /* FLAGS */ @@ -3840,6 +3859,34 @@ uae_u8 *save_cpu (int *len, uae_u8 *dstptr) return dstbak; } +uae_u8 *save_mmu (int *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak, *dst; + int model; + + model = currprefs.mmu_model; + if (model != 68040) + return NULL; + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = xmalloc (1000); + save_u32 (model); /* MODEL */ + save_u32 (0); /* FLAGS */ + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *restore_mmu (uae_u8 *src) +{ + int flags, model; + + changed_prefs.mmu_model = model = restore_u32 (); + flags = restore_u32 (); + write_log (L"MMU: %d\n", model); + return src; +} + #endif /* SAVESTATE */ static void exception3f (uae_u32 opcode, uaecptr addr, uaecptr fault, int writeaccess, int instructionaccess) @@ -4213,7 +4260,7 @@ void m68k_do_bsr_mmu (uaecptr oldpc, uae_s32 offset) { put_long_mmu (m68k_areg (regs, 7) - 4, oldpc); m68k_areg (regs, 7) -= 4; - m68k_incpc (offset); + m68k_incpci (offset); } diff --git a/od-win32/ahidsound_dsonly.c b/od-win32/ahidsound_dsonly.c index 5bce158e..7cf81d27 100644 --- a/od-win32/ahidsound_dsonly.c +++ b/od-win32/ahidsound_dsonly.c @@ -859,6 +859,25 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) free (bswap_buffer); bswap_buffer = NULL; return 0; + + case 110: + { + LARGE_INTEGER p; + QueryPerformanceFrequency (&p); + put_long (m68k_areg (regs, 0), p.HighPart); + put_long (m68k_areg (regs, 0) + 4, p.LowPart); + } + return 1; + + case 111: + { + LARGE_INTEGER p; + QueryPerformanceCounter (&p); + put_long (m68k_areg (regs, 0), p.HighPart); + put_long (m68k_areg (regs, 0) + 4, p.LowPart); + } + return 1; + #endif case 200: diff --git a/od-win32/bsdsock.c b/od-win32/bsdsock.c index 624c0a06..d620d495 100644 --- a/od-win32/bsdsock.c +++ b/od-win32/bsdsock.c @@ -561,7 +561,7 @@ int host_dup2socket(SB, int fd1, int fd2) if (s1 != INVALID_SOCKET) { if (fd2 != -1) { if ((unsigned int) (fd2) >= (unsigned int) sb->dtablesize) { - BSDTRACE (("Bad file descriptor (%d)\n", fd2)); + BSDTRACE ((L"Bad file descriptor (%d)\n", fd2)); bsdsocklib_seterrno (sb, 9); /* EBADF */ } fd2++; @@ -833,54 +833,25 @@ static BOOL HandleStuff(void) switch(sockreq.packet_type) { case connect_req: - sockreq.sb->resultval = connect(sockreq.s,(struct sockaddr *)(sockreq.params.connect_s.buf),sockreq.params.connect_s.namelen); + sockreq.sb->resultval = connect(sockreq.s,(struct sockaddr *)(sockreq.params.connect_s.buf),sockreq.params.connect_s.namelen); break; case sendto_req: - if(sockreq.params.sendto_s.to) { - sockreq.sb->resultval = sendto(sockreq.s,sockreq.params.sendto_s.realpt,sockreq.params.sendto_s.len,sockreq.params.sendto_s.flags,(struct sockaddr *)(sockreq.params.sendto_s.buf),sockreq.params.sendto_s.tolen); - } else { - sockreq.sb->resultval = send(sockreq.s,sockreq.params.sendto_s.realpt,sockreq.params.sendto_s.len,sockreq.params.sendto_s.flags); - } + if(sockreq.params.sendto_s.to) { + sockreq.sb->resultval = sendto(sockreq.s,sockreq.params.sendto_s.realpt,sockreq.params.sendto_s.len,sockreq.params.sendto_s.flags,(struct sockaddr *)(sockreq.params.sendto_s.buf),sockreq.params.sendto_s.tolen); + } else { + sockreq.sb->resultval = send(sockreq.s,sockreq.params.sendto_s.realpt,sockreq.params.sendto_s.len,sockreq.params.sendto_s.flags); + } break; case recvfrom_req: - { - int len = sockreq.params.recvfrom_s.len; - uae_u8 *p = sockreq.params.recvfrom_s.realpt; - int flags = sockreq.params.recvfrom_s.flags; - int waitall = sockreq.params.recvfrom_s.flags & 0x40; - int result = -1; - int got = 0; - - if (waitall) - flags &= ~0x40; - for (;;) { - if (waitall && ((flags & MSG_PEEK) || (flags & MSG_OOB))) { - result = -1; - break; - } if(sockreq.params.recvfrom_s.addr) { - result = recvfrom(sockreq.s, p, len, - flags, sockreq.params.recvfrom_s.rp_addr, + sockreq.sb->resultval = recvfrom(sockreq.s, sockreq.params.recvfrom_s.realpt, sockreq.params.recvfrom_s.len, + sockreq.params.recvfrom_s.flags, sockreq.params.recvfrom_s.rp_addr, sockreq.params.recvfrom_s.hlen); } else { - result = recv(sockreq.s, p, len, flags); - } - if (!waitall) - break; - if (result < 0) - break; - got += result; - p += result; - len -= result; - if (len <= 0 || result == 0) { - result = got; - break; + sockreq.sb->resultval = recv(sockreq.s, sockreq.params.recvfrom_s.realpt, sockreq.params.recvfrom_s.len, + sockreq.params.recvfrom_s.flags); } - - } - sockreq.sb->resultval = result; - } break; case abort_req: *(sockreq.params.abort_s.newsock) = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); @@ -1214,6 +1185,7 @@ void host_recvfrom(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 le struct sockaddr *rp_addr = NULL; int hlen; unsigned int wMsg; + int waitall, waitallgot; #ifdef TRACING_ENABLED if (addr) @@ -1240,6 +1212,10 @@ void host_recvfrom(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 le BEGINBLOCKING; + waitall = flags & 0x40; + flags &= ~0x40; + waitallgot = 0; + for (;;) { PREPARE_THREAD; @@ -1255,34 +1231,54 @@ void host_recvfrom(TrapContext *context, SB, uae_u32 sd, uae_u32 msg, uae_u32 le sockreq.params.recvfrom_s.rp_addr = rp_addr; TRIGGER_THREAD; - if (sb->resultval == -1) { - if (sb->sb_errno == WSAEWOULDBLOCK - WSABASEERR && sb->ftable[sd-1] & SF_BLOCKING) - { - if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) { - if (sb->mtable[sd-1] == 0) { - WSAAsyncSelect(s, hWndSelector ? hAmigaWnd : bsd->hSockWnd, wMsg, FD_READ|FD_CLOSE); - } else { - setWSAAsyncSelect(sb, sd, s, FD_READ|FD_CLOSE); + + if (waitall) { + if (sb->resultval > 0) { + int l = sb->resultval; + realpt += l; + len -= l; + waitallgot += l; + if (len <= 0) { + sb->resultval = waitallgot; + break; + } else { + sb->sb_errno = WSAEWOULDBLOCK - WSABASEERR; + sb->resultval = -1; + } + } else if (sb->resultval == 0) { + sb->resultval = waitallgot; } + } - WAITSIGNAL; - if (sb->mtable[sd-1] == 0) { - cancelasyncmsg(context, wMsg); - } else { - setWSAAsyncSelect(sb, sd, s, 0); - } + if (sb->resultval == -1) { + if (sb->sb_errno == WSAEWOULDBLOCK - WSABASEERR && (sb->ftable[sd-1] & SF_BLOCKING)) { + if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) { + if (sb->mtable[sd-1] == 0) { + WSAAsyncSelect(s, hWndSelector ? hAmigaWnd : bsd->hSockWnd, wMsg, FD_READ|FD_CLOSE); + } else { + setWSAAsyncSelect(sb, sd, s, FD_READ|FD_CLOSE); + } - if (sb->eintr) { - BSDTRACE((L"[interrupted]\n")); - return; - } - } else + WAITSIGNAL; + + if (sb->mtable[sd-1] == 0) { + cancelasyncmsg(context, wMsg); + } else { + setWSAAsyncSelect(sb, sd, s, 0); + } + + if (sb->eintr) { + BSDTRACE((L"[interrupted]\n")); + return; + } + + } else + break; + } else + break; + } else break; - } else - break; - } else - break; } ENDBLOCKING; diff --git a/od-win32/dinput.c b/od-win32/dinput.c index 28a81243..24c84df9 100644 --- a/od-win32/dinput.c +++ b/od-win32/dinput.c @@ -2598,9 +2598,9 @@ int input_get_default_joystick (struct uae_input_device *uid, int i, int port, i if (isrealbutton (did, 3)) uid[i].eventid[ID_BUTTON_OFFSET + 3][0] = port ? INPUTEVENT_JOY2_CD32_YELLOW : INPUTEVENT_JOY1_CD32_YELLOW; if (isrealbutton (did, 4)) - uid[i].eventid[ID_BUTTON_OFFSET + 4][0] = port ? INPUTEVENT_JOY2_CD32_FFW : INPUTEVENT_JOY1_CD32_FFW; + uid[i].eventid[ID_BUTTON_OFFSET + 4][0] = port ? INPUTEVENT_JOY2_CD32_RWD : INPUTEVENT_JOY1_CD32_RWD; if (isrealbutton (did, 5)) - uid[i].eventid[ID_BUTTON_OFFSET + 5][0] = port ? INPUTEVENT_JOY2_CD32_RWD : INPUTEVENT_JOY1_CD32_RWD; + uid[i].eventid[ID_BUTTON_OFFSET + 5][0] = port ? INPUTEVENT_JOY2_CD32_FFW : INPUTEVENT_JOY1_CD32_FFW; if (isrealbutton (did, 6)) uid[i].eventid[ID_BUTTON_OFFSET + 6][0] = port ? INPUTEVENT_JOY2_CD32_PLAY : INPUTEVENT_JOY1_CD32_PLAY; } diff --git a/od-win32/win32.h b/od-win32/win32.h index cc3dc4d9..7aa80744 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -17,8 +17,8 @@ #define WINUAEPUBLICBETA 1 -#define WINUAEBETA L"13" -#define WINUAEDATE MAKEBD(2009, 9, 5) +#define WINUAEBETA L"14" +#define WINUAEDATE MAKEBD(2009, 9, 9) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index f39518cb..4f3b5649 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,25 @@ +Beta 14: + +- added very basic MMU statefile support +- and more MMU compatibility updates (LINK, RTD, CMPM) +- FTRAPcc fix from Aranym (I guess nobody uses this instruction..) +- MMU access error instruction restart update, Linux really works now + but is quite useless because there is no hardware cdrom or network + emulation.. +- CD32 pad default mapping RWD and FFW swapped +- non-CE mode blitter timing fix (blitter timing got better few betas + ago but it was less compatible because cpu is not slowed down..) +- bsdsocket MSG_WAITALL really works now +- added "value must change" debugger memwatch mode (C) +- another reading write-only register update, reading 0xDFF000 always + returns whatever was left on chip bus. Only on OCS chipset and only + 0xDFF000 (BLTDDAT) does this. Correct fix for Codetrash. This demo + has really "fun" bug, it does cmp.b #$30,$dff000;bne.s loop (should + be $dff006) and this comparison only succceeds because of 0xDFF000 + special case AND because module player is running and there is at + least one audio sample with value of $30! (unbelievable, isn't it?) + Beta 13: - MMU emulation bug fix (was bug in Aranym's code, official fix now diff --git a/savestate.c b/savestate.c index 908cadb9..ae308b26 100644 --- a/savestate.c +++ b/savestate.c @@ -480,6 +480,10 @@ void restore_state (const TCHAR *filename) #ifdef FPUEMU else if (!_tcscmp (name, L"FPU ")) end = restore_fpu (chunk); +#endif +#ifdef MMUEMU + else if (!_tcscmp (name, L"MMU ")) + end = restore_mmu (chunk); #endif else if (!_tcscmp (name, L"AGAC")) end = restore_custom_agacolors (chunk); @@ -710,6 +714,12 @@ int save_state (const TCHAR *filename, const TCHAR *description) xfree (dst); #endif +#ifdef MMUEMU + dst = save_mmu (&len, 0); + save_chunk (f, dst, len, L"MMU ", 0); + xfree (dst); +#endif + _tcscpy(name, L"DSKx"); for (i = 0; i < 4; i++) { dst = save_disk (i, &len, 0); @@ -1303,8 +1313,10 @@ FPU (only if used) MMU (when and if MMU is supported in future..) - MMU model 4 (68851,68030,68040,68060) + "MMU " + MMU model 4 (68040) + flags 4 (none defined yet) CUSTOM CHIPS diff --git a/table68k b/table68k index eb906ec8..c8bc2a99 100644 --- a/table68k +++ b/table68k @@ -4,6 +4,7 @@ % C: condition codes, except F % f: direction % i: immediate +% E: immediate, except 00 (for EmulOp instructions) % I: immediate, except 00 and ff % j: immediate 1..8 % J: immediate 0..15 @@ -25,19 +26,17 @@ % % Arp: --> -(Ar) % ArP: --> (Ar)+ -% Ara: --> (Ar) -% L: (xxx.L) +% L: --> (xxx.L) % -% Fields on a line: -% 16 chars bitpattern : -% CPU level / privilege level : +% Fields on a line: +% 16 chars bitpattern : +% CPU level / privildge level : % CPU level 0: 68000 % 1: 68010 % 2: 68020 -% 3: 68030 +% 3: 68020/68881 % 4: 68040 -% 5: 68060 (not used to produce a cputbl) -% [Everything from 68020 possibly allows for FPU emulation] +% 5: 68060 % privilege level 0: not privileged % 1: unprivileged only on 68000 (check regs.s) % 2: privileged (check regs.s) @@ -48,10 +47,19 @@ % 0 means flag reset % 1 means flag set % ? means programmer was too lazy to check or instruction may trap -% + means instruction is conditional branch -% everything else means flag set/used -% / means instruction is unconditional branch/call +% + means instruction is conditional branch (ignored, only for sync) +% / means instruction is unconditional branch/call (ignored, only for sync) % x means flag is unknown and well-behaved programs shouldn't check it +% everything else means flag set/used +% +% Control flow +% two letters, combination of +% - nothing +% T the instruction may trap or cause an exception +% B branch instruction +% J jump instruction +% R return instruction +% % srcaddr status destaddr status : % bitmasks of % 1 means fetched @@ -61,219 +69,223 @@ % instruction % -0000 0000 0011 1100:00:XNZVC:XNZVC:10: ORSR.B #1 -0000 0000 0111 1100:02:?????:?????:10: ORSR.W #1 -0000 0zz0 11ss sSSS:20:?????:?????:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd] -0000 0000 zzdd dDDD:00:-NZ00:-----:13: OR.z #z,d[!Areg] -0000 0010 0011 1100:00:XNZVC:XNZVC:10: ANDSR.B #1 -0000 0010 0111 1100:02:?????:?????:10: ANDSR.W #1 -0000 0010 zzdd dDDD:00:-NZ00:-----:13: AND.z #z,d[!Areg] -0000 0100 zzdd dDDD:00:XNZVC:-----:13: SUB.z #z,d[!Areg] -0000 0110 zzdd dDDD:00:XNZVC:-----:13: ADD.z #z,d[!Areg] -0000 0110 11ss sSSS:20:?????:?????:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd] -0000 0110 11ss sSSS:20:?????:?????:10: RTM s[Dreg,Areg] -0000 1000 00ss sSSS:00:--Z--:-----:11: BTST #1,s[!Areg] -0000 1000 01ss sSSS:00:--Z--:-----:13: BCHG #1,s[!Areg,Immd] -0000 1000 10ss sSSS:00:--Z--:-----:13: BCLR #1,s[!Areg,Immd] -0000 1000 11ss sSSS:00:--Z--:-----:13: BSET #1,s[!Areg,Immd] -0000 1010 0011 1100:00:XNZVC:XNZVC:10: EORSR.B #1 -0000 1010 0111 1100:02:?????:?????:10: EORSR.W #1 -0000 1010 zzdd dDDD:00:-NZ00:-----:13: EOR.z #z,d[!Areg] -0000 1100 zzss sSSS:00:-NZVC:-----:11: CMP.z #z,s[!Areg,Immd] +0000 0000 0011 1100:00:XNZVC:XNZVC:--:10: ORSR.B #1 +0000 0000 0111 1100:02:XNZVC:XNZVC:T-:10: ORSR.W #1 +0000 0zz0 11ss sSSS:20:-?Z?C:-----:T-:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd] +0000 0000 zzdd dDDD:00:-NZ00:-----:--:13: OR.z #z,d[!Areg] +0000 0010 0011 1100:00:XNZVC:XNZVC:--:10: ANDSR.B #1 +0000 0010 0111 1100:02:XNZVC:XNZVC:T-:10: ANDSR.W #1 +0000 0010 zzdd dDDD:00:-NZ00:-----:--:13: AND.z #z,d[!Areg] +0000 0100 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z #z,d[!Areg] +0000 0110 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z #z,d[!Areg] +0000 0110 11ss sSSS:20:-----:XNZVC:--:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd] +0000 0110 11ss sSSS:20:XNZVC:-----:-R:10: RTM s[Dreg,Areg] +0000 1000 00ss sSSS:00:--Z--:-----:--:11: BTST #1,s[!Areg] +0000 1000 01ss sSSS:00:--Z--:-----:--:13: BCHG #1,s[!Areg,Immd] +0000 1000 10ss sSSS:00:--Z--:-----:--:13: BCLR #1,s[!Areg,Immd] +0000 1000 11ss sSSS:00:--Z--:-----:--:13: BSET #1,s[!Areg,Immd] +0000 1010 0011 1100:00:XNZVC:XNZVC:--:10: EORSR.B #1 +0000 1010 0111 1100:02:XNZVC:XNZVC:T-:10: EORSR.W #1 +0000 1010 zzdd dDDD:00:-NZ00:-----:--:13: EOR.z #z,d[!Areg] +0000 1100 zzss sSSS:00:-NZVC:-----:--:11: CMP.z #z,s[!Areg,Immd] + +0000 1010 11ss sSSS:20:-NZVC:-----:--:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1100 11ss sSSS:20:-NZVC:-----:--:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1100 1111 1100:20:-NZVC:-----:--:10: CAS2.W #2 +0000 1110 zzss sSSS:22:-----:-----:T-:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1110 11ss sSSS:20:-NZVC:-----:--:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1110 1111 1100:20:-NZVC:-----:--:10: CAS2.L #2 -0000 1010 11ss sSSS:20:?????:?????:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16] -0000 1100 11ss sSSS:20:?????:?????:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16] -0000 1100 1111 1100:20:?????:?????:10: CAS2.W #2 -0000 1110 zzss sSSS:22:?????:?????:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16] -0000 1110 11ss sSSS:20:?????:?????:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16] -0000 1110 1111 1100:20:?????:?????:10: CAS2.L #2 +0000 rrr1 00dd dDDD:00:-----:-----:--:12: MVPMR.W d[Areg-Ad16],Dr +0000 rrr1 01dd dDDD:00:-----:-----:--:12: MVPMR.L d[Areg-Ad16],Dr +0000 rrr1 10dd dDDD:00:-----:-----:--:12: MVPRM.W Dr,d[Areg-Ad16] +0000 rrr1 11dd dDDD:00:-----:-----:--:12: MVPRM.L Dr,d[Areg-Ad16] +0000 rrr1 00ss sSSS:00:--Z--:-----:--:11: BTST Dr,s[!Areg] +0000 rrr1 01ss sSSS:00:--Z--:-----:--:13: BCHG Dr,s[!Areg,Immd] +0000 rrr1 10ss sSSS:00:--Z--:-----:--:13: BCLR Dr,s[!Areg,Immd] +0000 rrr1 11ss sSSS:00:--Z--:-----:--:13: BSET Dr,s[!Areg,Immd] -0000 rrr1 00dd dDDD:00:-----:-----:12: MVPMR.W d[Areg-Ad16],Dr -0000 rrr1 01dd dDDD:00:-----:-----:12: MVPMR.L d[Areg-Ad16],Dr -0000 rrr1 10dd dDDD:00:-----:-----:12: MVPRM.W Dr,d[Areg-Ad16] -0000 rrr1 11dd dDDD:00:-----:-----:12: MVPRM.L Dr,d[Areg-Ad16] -0000 rrr1 00ss sSSS:00:--Z--:-----:11: BTST Dr,s[!Areg] -0000 rrr1 01ss sSSS:00:--Z--:-----:13: BCHG Dr,s[!Areg,Immd] -0000 rrr1 10ss sSSS:00:--Z--:-----:13: BCLR Dr,s[!Areg,Immd] -0000 rrr1 11ss sSSS:00:--Z--:-----:13: BSET Dr,s[!Areg,Immd] +0001 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.B s,d[!Areg] +0010 DDDd ddss sSSS:00:-----:-----:--:12: MOVEA.L s,d[Areg] +0010 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.L s,d[!Areg] +0011 DDDd ddss sSSS:00:-----:-----:--:12: MOVEA.W s,d[Areg] +0011 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.W s,d[!Areg] -0001 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.B s,d[!Areg] -0010 DDDd ddss sSSS:00:-----:-----:12: MOVEA.L s,d[Areg] -0010 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.L s,d[!Areg] -0011 DDDd ddss sSSS:00:-----:-----:12: MOVEA.W s,d[Areg] -0011 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.W s,d[!Areg] +0100 0000 zzdd dDDD:00:XNZVC:X-Z--:--:30: NEGX.z d[!Areg] +0100 0000 11dd dDDD:01:-----:XNZVC:T-:10: MVSR2.W d[!Areg] +0100 0010 zzdd dDDD:00:-0100:-----:--:20: CLR.z d[!Areg] +0100 0010 11dd dDDD:10:-----:XNZVC:--:10: MVSR2.B d[!Areg] +0100 0100 zzdd dDDD:00:XNZVC:-----:--:30: NEG.z d[!Areg] +0100 0100 11ss sSSS:00:XNZVC:-----:--:10: MV2SR.B s[!Areg] +0100 0110 zzdd dDDD:00:-NZ00:-----:--:30: NOT.z d[!Areg] +0100 0110 11ss sSSS:02:XNZVC:XNZVC:T-:10: MV2SR.W s[!Areg] +0100 1000 0000 1rrr:20:-----:-----:--:31: LINK.L Ar,#2 +0100 1000 00dd dDDD:00:X?Z?C:X-Z--:--:30: NBCD.B d[!Areg] +0100 1000 0100 1kkk:20:-----:-----:T-:10: BKPT #k +0100 1000 01ss sSSS:00:-NZ00:-----:--:30: SWAP.W s[Dreg] +0100 1000 01ss sSSS:00:-----:-----:--:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 1000 10dd dDDD:00:-NZ00:-----:--:30: EXT.W d[Dreg] +0100 1000 10dd dDDD:00:-----:-----:--:02: MVMLE.W #1,d[!Dreg,Areg,Aipi] +0100 1000 11dd dDDD:00:-NZ00:-----:--:30: EXT.L d[Dreg] +0100 1000 11dd dDDD:00:-----:-----:--:02: MVMLE.L #1,d[!Dreg,Areg,Aipi] +0100 1001 11dd dDDD:00:-NZ00:-----:--:30: EXT.B d[Dreg] +0100 1010 zzss sSSS:00:-NZ00:-----:--:10: TST.z s +0100 1010 11dd dDDD:00:-NZ00:-----:--:30: TAS.B d[!Areg] +0100 1010 1111 1100:00:-----:-----:T-:00: ILLEGAL +0100 1100 00ss sSSS:20:-NZVC:-----:--:13: MULL.L #1,s[!Areg] +0100 1100 01ss sSSS:20:-NZV0:-----:T-:13: DIVL.L #1,s[!Areg] +0100 1100 10ss sSSS:00:-----:-----:--:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd] +0100 1100 11ss sSSS:00:-----:-----:--:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd] +0100 1110 0100 JJJJ:00:-----:XNZVC:--:10: TRAP #J +0100 1110 0101 0rrr:00:-----:-----:--:31: LINK.W Ar,#1 +0100 1110 0101 1rrr:00:-----:-----:--:30: UNLK.L Ar +0100 1110 0110 0rrr:02:-----:-----:T-:10: MVR2USP.L Ar +0100 1110 0110 1rrr:02:-----:-----:T-:20: MVUSP2R.L Ar +0100 1110 0111 0000:02:-----:-----:T-:00: RESET +0100 1110 0111 0001:00:-----:-----:--:00: NOP +0100 1110 0111 0010:02:XNZVC:-----:T-:10: STOP #1 +0100 1110 0111 0011:02:XNZVC:-----:TR:00: RTE +0100 1110 0111 0100:00:-----:-----:-R:10: RTD #1 +0100 1110 0111 0101:00:-----:-----:-R:00: RTS +0100 1110 0111 0110:00:-----:XNZVC:T-:00: TRAPV +0100 1110 0111 0111:00:XNZVC:-----:-R:00: RTR +0100 1110 0111 1010:12:-----:-----:T-:10: MOVEC2 #1 +0100 1110 0111 1011:12:-----:-----:T-:10: MOVE2C #1 +0100 1110 10ss sSSS:00://///://///:-J:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 rrr1 00ss sSSS:00:-N???:-----:T-:11: CHK.L s[!Areg],Dr +0100 rrr1 10ss sSSS:00:-N???:-----:T-:11: CHK.W s[!Areg],Dr +0100 1110 11ss sSSS:00://///://///:-J:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 rrr1 11ss sSSS:00:-----:-----:--:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar -0100 0000 zzdd dDDD:00:XxZxC:X-Z--:30: NEGX.z d[!Areg] -0100 0000 11dd dDDD:01:?????:?????:10: MVSR2.W d[!Areg] -0100 0010 zzdd dDDD:00:-0100:-----:20: CLR.z d[!Areg] -0100 0010 11dd dDDD:10:?????:?????:10: MVSR2.B d[!Areg] -0100 0100 zzdd dDDD:00:XNZVC:-----:30: NEG.z d[!Areg] -0100 0100 11ss sSSS:00:XNZVC:-----:10: MV2SR.B s[!Areg] -0100 0110 zzdd dDDD:00:-NZ00:-----:30: NOT.z d[!Areg] -0100 0110 11ss sSSS:02:?????:?????:10: MV2SR.W s[!Areg] -0100 1000 0000 1rrr:20:-----:-----:31: LINK.L Ar,#2 -0100 1000 00dd dDDD:00:X?Z?C:X-Z--:30: NBCD.B d[!Areg] -0100 1000 0100 1kkk:20:?????:?????:10: BKPT #k -0100 1000 01ss sSSS:00:-NZ00:-----:30: SWAP.W s[Dreg] -0100 1000 01ss sSSS:00:-----:-----:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd] -0100 1000 10dd dDDD:00:-NZ00:-----:30: EXT.W d[Dreg] -0100 1000 10dd dDDD:00:-----:-----:02: MVMLE.W #1,d[!Dreg,Areg,Aipi] -0100 1000 11dd dDDD:00:-NZ00:-----:30: EXT.L d[Dreg] -0100 1000 11dd dDDD:00:-----:-----:02: MVMLE.L #1,d[!Dreg,Areg,Aipi] -0100 1001 11dd dDDD:20:-NZ00:-----:30: EXT.B d[Dreg] -0100 1010 zzss sSSS:00:-NZ00:-----:10: TST.z s -0100 1010 11dd dDDD:00:?????:?????:30: TAS.B d[!Areg] -0100 1010 1111 1100:00:?????:?????:00: ILLEGAL -0100 1100 00ss sSSS:20:-NZVC:-----:13: MULL.L #1,s[!Areg] -0100 1100 01ss sSSS:20:?????:?????:13: DIVL.L #1,s[!Areg] -0100 1100 10ss sSSS:00:-----:-----:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd] -0100 1100 11ss sSSS:00:-----:-----:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd] -0100 1110 0100 JJJJ:00:-----:XNZVC:10: TRAP #J -0100 1110 0101 0rrr:00:-----:-----:31: LINK.W Ar,#1 -0100 1110 0101 1rrr:00:-----:-----:30: UNLK.L Ar -0100 1110 0110 0rrr:02:-----:-----:10: MVR2USP.L Ar -0100 1110 0110 1rrr:02:-----:-----:20: MVUSP2R.L Ar -0100 1110 0111 0000:02:-----:-----:00: RESET -0100 1110 0111 0001:00:-----:-----:00: NOP -0100 1110 0111 0010:02:XNZVC:-----:10: STOP #1 -0100 1110 0111 0011:02:XNZVC:-----:00: RTE -0100 1110 0111 0100:00:?????:?????:10: RTD #1 -0100 1110 0111 0101:00:-----:-----:00: RTS -0100 1110 0111 0110:00:-----:XNZVC:00: TRAPV -0100 1110 0111 0111:00:XNZVC:-----:00: RTR -0100 1110 0111 1010:12:?????:?????:10: MOVEC2 #1 -0100 1110 0111 1011:12:?????:?????:10: MOVE2C #1 -0100 1110 10ss sSSS:00://///://///:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd] -0100 rrr1 00ss sSSS:20:?????:?????:11: CHK.L s[!Areg],Dr -0100 rrr1 10ss sSSS:00:?????:?????:11: CHK.W s[!Areg],Dr -0100 1110 11ss sSSS:00://///://///:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd] -0100 rrr1 11ss sSSS:00:-----:-----:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar +% This variant of ADDQ is word and long sized only +0101 jjj0 01dd dDDD:00:-----:-----:--:13: ADDA.W #j,d[Areg] +0101 jjj0 10dd dDDD:00:-----:-----:--:13: ADDA.L #j,d[Areg] +0101 jjj0 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z #j,d[!Areg] -0101 jjj0 01dd dDDD:00:-----:-----:13: ADDA.W #j,d[Areg] -0101 jjj0 10dd dDDD:00:-----:-----:13: ADDA.L #j,d[Areg] -0101 jjj0 zzdd dDDD:00:XNZVC:-----:13: ADD.z #j,d[!Areg] -0101 jjj1 01dd dDDD:00:-----:-----:13: SUBA.W #j,d[Areg] -0101 jjj1 10dd dDDD:00:-----:-----:13: SUBA.L #j,d[Areg] -0101 jjj1 zzdd dDDD:00:XNZVC:-----:13: SUB.z #j,d[!Areg] -0101 cccc 1100 1rrr:00:-----:-++++:31: DBcc.W Dr,#1 -0101 cccc 11dd dDDD:00:-----:-++++:20: Scc.B d[!Areg] -0101 cccc 1111 1010:20:?????:?????:10: TRAPcc #1 -0101 cccc 1111 1011:20:?????:?????:10: TRAPcc #2 -0101 cccc 1111 1100:20:?????:?????:00: TRAPcc +% This variant of SUBQ is word and long sized only +0101 jjj1 01dd dDDD:00:-----:-----:--:13: SUBA.W #j,d[Areg] +0101 jjj1 10dd dDDD:00:-----:-----:--:13: SUBA.L #j,d[Areg] +0101 jjj1 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z #j,d[!Areg] + +0101 cccc 1100 1rrr:00:-----:-++++:-B:31: DBcc.W Dr,#1 +0101 cccc 11dd dDDD:00:-----:-++++:--:20: Scc.B d[!Areg] +0101 cccc 1111 1010:20:-----:-????:T-:10: TRAPcc #1 +0101 cccc 1111 1011:20:-----:-????:T-:10: TRAPcc #2 +0101 cccc 1111 1100:20:-----:-????:T-:00: TRAPcc % Bxx.L is 68020 only, but setting the CPU level to 2 would give illegal % instruction exceptions when compiling a 68000 only emulation, which isn't % what we want either. -0110 0001 0000 0000:00://///://///:40: BSR.W #1 -0110 0001 IIII IIII:00://///://///:40: BSR.B #i -0110 0001 1111 1111:00://///://///:40: BSR.L #2 -0110 CCCC 0000 0000:00:-----:-++++:40: Bcc.W #1 -0110 CCCC IIII IIII:00:-----:-++++:40: Bcc.B #i -0110 CCCC 1111 1111:00:-----:-++++:40: Bcc.L #2 +0110 0001 0000 0000:00://///://///:-B:40: BSR.W #1 +0110 0001 IIII IIII:00://///://///:-B:40: BSR.B #i +0110 0001 1111 1111:00://///://///:-B:40: BSR.L #2 +0110 CCCC 0000 0000:00:-----:-++++:-B:40: Bcc.W #1 +0110 CCCC IIII IIII:00:-----:-++++:-B:40: Bcc.B #i +0110 CCCC 1111 1111:00:-----:-++++:-B:40: Bcc.L #2 -0111 rrr0 iiii iiii:00:-NZ00:-----:12: MOVE.L #i,Dr +0111 rrr0 iiii iiii:00:-NZ00:-----:--:12: MOVE.L #i,Dr -1000 rrr0 zzss sSSS:00:-NZ00:-----:13: OR.z s[!Areg],Dr -1000 rrr0 11ss sSSS:00:?????:?????:13: DIVU.W s[!Areg],Dr -1000 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: SBCD.B d[Dreg],Dr -1000 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: SBCD.B d[Areg-Apdi],Arp -1000 rrr1 zzdd dDDD:00:-NZ00:-----:13: OR.z Dr,d[!Areg,Dreg] -1000 rrr1 01dd dDDD:20:?????:?????:12: PACK d[Dreg],Dr -1000 rrr1 01dd dDDD:20:?????:?????:12: PACK d[Areg-Apdi],Arp -1000 rrr1 10dd dDDD:20:?????:?????:12: UNPK d[Dreg],Dr -1000 rrr1 10dd dDDD:20:?????:?????:12: UNPK d[Areg-Apdi],Arp -1000 rrr1 11ss sSSS:00:?????:?????:13: DIVS.W s[!Areg],Dr +1000 rrr0 zzss sSSS:00:-NZ00:-----:--:13: OR.z s[!Areg],Dr +1000 rrr0 11ss sSSS:00:-NZV0:-----:T-:13: DIVU.W s[!Areg],Dr +1000 rrr1 00dd dDDD:00:X?Z?C:X-Z--:--:13: SBCD.B d[Dreg],Dr +1000 rrr1 00dd dDDD:00:X?Z?C:X-Z--:--:13: SBCD.B d[Areg-Apdi],Arp +1000 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: OR.z Dr,d[!Areg,Dreg] +1000 rrr1 01dd dDDD:20:-----:-----:--:12: PACK d[Dreg],Dr +1000 rrr1 01dd dDDD:20:-----:-----:--:12: PACK d[Areg-Apdi],Arp +1000 rrr1 10dd dDDD:20:-----:-----:--:12: UNPK d[Dreg],Dr +1000 rrr1 10dd dDDD:20:-----:-----:--:12: UNPK d[Areg-Apdi],Arp +1000 rrr1 11ss sSSS:00:-NZV0:-----:T-:13: DIVS.W s[!Areg],Dr -1001 rrr0 zzss sSSS:00:XNZVC:-----:13: SUB.z s,Dr -1001 rrr0 11ss sSSS:00:-----:-----:13: SUBA.W s,Ar -1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: SUBX.z d[Dreg],Dr -1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: SUBX.z d[Areg-Apdi],Arp -1001 rrr1 zzdd dDDD:00:XNZVC:-----:13: SUB.z Dr,d[!Areg,Dreg] -1001 rrr1 11ss sSSS:00:-----:-----:13: SUBA.L s,Ar +1001 rrr0 zzss sSSS:00:XNZVC:-----:--:13: SUB.z s,Dr +1001 rrr0 11ss sSSS:00:-----:-----:--:13: SUBA.W s,Ar +1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: SUBX.z d[Dreg],Dr +1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: SUBX.z d[Areg-Apdi],Arp +1001 rrr1 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z Dr,d[!Areg,Dreg] +1001 rrr1 11ss sSSS:00:-----:-----:--:13: SUBA.L s,Ar -1011 rrr0 zzss sSSS:00:-NZVC:-----:11: CMP.z s,Dr -1011 rrr0 11ss sSSS:00:-NZVC:-----:11: CMPA.W s,Ar -1011 rrr1 11ss sSSS:00:-NZVC:-----:11: CMPA.L s,Ar -1011 rrr1 zzdd dDDD:00:-NZVC:-----:11: CMPM.z d[Areg-Aipi],ArP -1011 rrr1 zzdd dDDD:00:-NZ00:-----:13: EOR.z Dr,d[!Areg] +1011 rrr0 zzss sSSS:00:-NZVC:-----:--:11: CMP.z s,Dr +1011 rrr0 11ss sSSS:00:-NZVC:-----:--:11: CMPA.W s,Ar +1011 rrr1 11ss sSSS:00:-NZVC:-----:--:11: CMPA.L s,Ar +1011 rrr1 zzdd dDDD:00:-NZVC:-----:--:11: CMPM.z d[Areg-Aipi],ArP +1011 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: EOR.z Dr,d[!Areg] -1100 rrr0 zzss sSSS:00:-NZ00:-----:13: AND.z s[!Areg],Dr -1100 rrr0 11ss sSSS:00:-NZ00:-----:13: MULU.W s[!Areg],Dr -1100 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: ABCD.B d[Dreg],Dr -1100 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: ABCD.B d[Areg-Apdi],Arp -1100 rrr1 zzdd dDDD:00:-NZ00:-----:13: AND.z Dr,d[!Areg,Dreg] -1100 rrr1 01dd dDDD:00:-----:-----:33: EXG.L Dr,d[Dreg] -1100 rrr1 01dd dDDD:00:-----:-----:33: EXG.L Ar,d[Areg] -1100 rrr1 10dd dDDD:00:-----:-----:33: EXG.L Dr,d[Areg] -1100 rrr1 11ss sSSS:00:-NZ00:-----:13: MULS.W s[!Areg],Dr +1100 rrr0 zzss sSSS:00:-NZ00:-----:--:13: AND.z s[!Areg],Dr +1100 rrr0 11ss sSSS:00:-NZ00:-----:--:13: MULU.W s[!Areg],Dr +1100 rrr1 00dd dDDD:00:X?Z?C:X-Z--:--:13: ABCD.B d[Dreg],Dr +1100 rrr1 00dd dDDD:00:X?Z?C:X-Z--:--:13: ABCD.B d[Areg-Apdi],Arp +1100 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: AND.z Dr,d[!Areg,Dreg] +1100 rrr1 01dd dDDD:00:-----:-----:--:33: EXG.L Dr,d[Dreg] +1100 rrr1 01dd dDDD:00:-----:-----:--:33: EXG.L Ar,d[Areg] +1100 rrr1 10dd dDDD:00:-----:-----:--:33: EXG.L Dr,d[Areg] +1100 rrr1 11ss sSSS:00:-NZ00:-----:--:13: MULS.W s[!Areg],Dr -1101 rrr0 zzss sSSS:00:XNZVC:-----:13: ADD.z s,Dr -1101 rrr0 11ss sSSS:00:-----:-----:13: ADDA.W s,Ar -1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: ADDX.z d[Dreg],Dr -1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: ADDX.z d[Areg-Apdi],Arp -1101 rrr1 zzdd dDDD:00:XNZVC:-----:13: ADD.z Dr,d[!Areg,Dreg] -1101 rrr1 11ss sSSS:00:-----:-----:13: ADDA.L s,Ar +1101 rrr0 zzss sSSS:00:XNZVC:-----:--:13: ADD.z s,Dr +1101 rrr0 11ss sSSS:00:-----:-----:--:13: ADDA.W s,Ar +1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: ADDX.z d[Dreg],Dr +1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: ADDX.z d[Areg-Apdi],Arp +1101 rrr1 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z Dr,d[!Areg,Dreg] +1101 rrr1 11ss sSSS:00:-----:-----:--:13: ADDA.L s,Ar -1110 jjjf zz00 0RRR:00:XNZVC:-----:13: ASf.z #j,DR -1110 jjjf zz00 1RRR:00:XNZ0C:-----:13: LSf.z #j,DR -1110 jjjf zz01 0RRR:00:XNZ0C:X----:13: ROXf.z #j,DR -1110 jjjf zz01 1RRR:00:-NZ0C:-----:13: ROf.z #j,DR -1110 rrrf zz10 0RRR:00:XNZVC:X----:13: ASf.z Dr,DR -1110 rrrf zz10 1RRR:00:XNZ0C:X----:13: LSf.z Dr,DR -1110 rrrf zz11 0RRR:00:XNZ0C:X----:13: ROXf.z Dr,DR -1110 rrrf zz11 1RRR:00:-NZ0C:-----:13: ROf.z Dr,DR -1110 000f 11dd dDDD:00:XNZVC:-----:13: ASfW.W d[!Dreg,Areg] -1110 001f 11dd dDDD:00:XNZ0C:-----:13: LSfW.W d[!Dreg,Areg] -1110 010f 11dd dDDD:00:XNZ0C:X----:13: ROXfW.W d[!Dreg,Areg] -1110 011f 11dd dDDD:00:-NZ0C:-----:13: ROfW.W d[!Dreg,Areg] +1110 jjjf zz00 0RRR:00:XNZVC:-----:--:13: ASf.z #j,DR +1110 jjjf zz00 1RRR:00:XNZ0C:-----:--:13: LSf.z #j,DR +1110 jjjf zz01 0RRR:00:XNZ0C:X----:--:13: ROXf.z #j,DR +1110 jjjf zz01 1RRR:00:-NZ0C:-----:--:13: ROf.z #j,DR +1110 rrrf zz10 0RRR:00:XNZVC:X----:--:13: ASf.z Dr,DR +1110 rrrf zz10 1RRR:00:XNZ0C:X----:--:13: LSf.z Dr,DR +1110 rrrf zz11 0RRR:00:XNZ0C:X----:--:13: ROXf.z Dr,DR +1110 rrrf zz11 1RRR:00:-NZ0C:-----:--:13: ROf.z Dr,DR +1110 000f 11dd dDDD:00:XNZVC:-----:--:13: ASfW.W d[!Dreg,Areg] +1110 001f 11dd dDDD:00:XNZ0C:-----:--:13: LSfW.W d[!Dreg,Areg] +1110 010f 11dd dDDD:00:XNZ0C:X----:--:13: ROXfW.W d[!Dreg,Areg] +1110 011f 11dd dDDD:00:-NZ0C:-----:--:13: ROfW.W d[!Dreg,Areg] -1110 1000 11ss sSSS:20:?????:?????:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd] -1110 1001 11ss sSSS:20:?????:?????:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd] -1110 1010 11ss sSSS:20:?????:?????:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] -1110 1011 11ss sSSS:20:?????:?????:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd] -1110 1100 11ss sSSS:20:?????:?????:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] -1110 1101 11ss sSSS:20:?????:?????:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd] -1110 1110 11ss sSSS:20:?????:?????:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] -1110 1111 11ss sSSS:20:?????:?????:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1000 11ss sSSS:20:-NZ00:-----:--:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd] +1110 1001 11ss sSSS:20:-NZ00:-----:--:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd] +1110 1010 11ss sSSS:20:-NZ00:-----:--:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1011 11ss sSSS:20:-NZ00:-----:--:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd] +1110 1100 11ss sSSS:20:-NZ00:-----:--:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1101 11ss sSSS:20:-NZ00:-----:--:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd] +1110 1110 11ss sSSS:20:-NZ00:-----:--:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1111 11ss sSSS:20:-NZ00:-----:--:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] % floating point co processor -1111 0010 00ss sSSS:20:?????:?????:11: FPP #1,s -1111 0010 01ss sSSS:20:?????:?????:11: FDBcc #1,s[Areg-Dreg] -1111 0010 01ss sSSS:20:?????:?????:11: FScc #1,s[!Areg,Immd,PC8r,PC16] -1111 0010 0111 1010:20:?????:?????:10: FTRAPcc #1 -1111 0010 0111 1011:20:?????:?????:10: FTRAPcc #2 -1111 0010 0111 1100:20:?????:?????:00: FTRAPcc -1111 0010 10KK KKKK:20:?????:?????:11: FBcc #K,#1 -1111 0010 11KK KKKK:20:?????:?????:11: FBcc #K,#2 -1111 0011 00ss sSSS:22:?????:?????:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16] -1111 0011 01ss sSSS:22:?????:?????:10: FRESTORE s[!Dreg,Areg,Apdi,Immd] +1111 0010 00ss sSSS:30:-----:-----:--:11: FPP #1,s +1111 0010 01ss sSSS:30:-----:-----:-B:11: FDBcc #1,s[Areg-Dreg] +1111 0010 01ss sSSS:30:-----:-----:--:11: FScc #1,s[!Areg,Immd,PC8r,PC16] +1111 0010 0111 1010:30:-----:-----:T-:10: FTRAPcc #1 +1111 0010 0111 1011:30:-----:-----:T-:10: FTRAPcc #2 +1111 0010 0111 1100:30:-----:-----:T-:00: FTRAPcc +1111 0010 10KK KKKK:30:-----:-----:-B:11: FBcc #K,#1 +1111 0010 11KK KKKK:30:-----:-----:-B:11: FBcc #K,#2 +1111 0011 00ss sSSS:32:-----:-----:--:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16] +1111 0011 01ss sSSS:32:-----:-----:--:10: FRESTORE s[!Dreg,Areg,Apdi,Immd] +% 68040 instructions +1111 0100 pp00 1rrr:42:-----:-----:T-:02: CINVL #p,Ar +1111 0100 pp01 0rrr:42:-----:-----:T-:02: CINVP #p,Ar +1111 0100 pp01 1rrr:42:-----:-----:T-:00: CINVA #p +1111 0100 pp10 1rrr:42:-----:-----:T-:02: CPUSHL #p,Ar +1111 0100 pp11 0rrr:42:-----:-----:T-:02: CPUSHP #p,Ar +1111 0100 pp11 1rrr:42:-----:-----:T-:00: CPUSHA #p +% destination register number is encoded in the following word +1111 0110 0010 0rrr:40:-----:-----:--:12: MOVE16 ArP,AxP +1111 0110 00ss sSSS:40:-----:-----:--:12: MOVE16 s[Dreg-Aipi],Al +1111 0110 00dd dDDD:40:-----:-----:--:12: MOVE16 Al,d[Areg-Aipi] +1111 0110 00ss sSSS:40:-----:-----:--:12: MOVE16 s[Aind],Al +1111 0110 00dd dDDD:40:-----:-----:--:12: MOVE16 Al,d[Aipi-Aind] % 68030 MMU (allowed addressing modes not checked!) 1111 0000 00ss sSSS:32:?????:?????:11: MMUOP030 s[!Immd],#1 -% 68040/68060 instructions -1111 0100 pp00 1rrr:42:-----:-----:02: CINVL #p,Ar -1111 0100 pp01 0rrr:42:-----:-----:02: CINVP #p,Ar -1111 0100 pp01 1rrr:42:-----:-----:00: CINVA #p -1111 0100 pp10 1rrr:42:-----:-----:02: CPUSHL #p,Ar -1111 0100 pp11 0rrr:42:-----:-----:02: CPUSHP #p,Ar -1111 0100 pp11 1rrr:42:-----:-----:00: CPUSHA #p -1111 0101 0000 0rrr:42:-----:-----:00: PFLUSHN Ara -1111 0101 0000 1rrr:42:-----:-----:00: PFLUSH Ara -1111 0101 0001 0rrr:42:-----:-----:00: PFLUSHAN Ara -1111 0101 0001 1rrr:42:-----:-----:00: PFLUSHA Ara -1111 0101 0100 1rrr:42:-----:-----:00: PTESTR Ara -1111 0101 0110 1rrr:42:-----:-----:00: PTESTW Ara - -% destination register number is encoded in the following word -1111 0110 0010 0rrr:40:-----:-----:12: MOVE16 ArP,AxP -1111 0110 00ss sSSS:40:-----:-----:12: MOVE16 s[Dreg-Aipi],L -1111 0110 00dd dDDD:40:-----:-----:12: MOVE16 L,d[Areg-Aipi] -1111 0110 00ss sSSS:40:-----:-----:12: MOVE16 s[Aind],L -1111 0110 00dd dDDD:40:-----:-----:12: MOVE16 L,d[Aipi-Aind] +% 68040 +1111 0101 0000 0rrr:42:-----:-----:--:00: PFLUSHN Ara +1111 0101 0000 1rrr:42:-----:-----:--:00: PFLUSH Ara +1111 0101 0001 0rrr:42:-----:-----:--:00: PFLUSHAN Ara +1111 0101 0001 1rrr:42:-----:-----:--:00: PFLUSHA Ara +1111 0101 0100 1rrr:42:-----:-----:--:00: PTESTR Ara +1111 0101 0110 1rrr:42:-----:-----:--:00: PTESTW Ara % 68060 -1111 1000 0000 0000:52:?????:?????:10: LPSTOP #1 -1111 0101 1000 1rrr:52:-----:-----:00: PLPAR Ara -1111 0101 1100 1rrr:52:-----:-----:00: PLPAW Ara +1111 1000 0000 0000:52:?????:?????:--:10: LPSTOP #1 +1111 0101 1000 1rrr:52:-----:-----:--:00: PLPAR Ara +1111 0101 1100 1rrr:52:-----:-----:--:00: PLPAW Ara diff --git a/zfile.c b/zfile.c index 2f8627bc..ef62b521 100644 --- a/zfile.c +++ b/zfile.c @@ -985,12 +985,21 @@ static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode, int ma static void manglefilename (TCHAR *out, const TCHAR *in) { + int i; + out[0] = 0; if (!strncasecmp (in, AF, _tcslen (AF))) _tcscpy (out, start_path_data); if ((in[0] == '/' || in[0] == '\\') || (_tcslen(in) > 3 && in[1] == ':' && in[2] == '\\')) out[0] = 0; _tcscat (out, in); + for (i = 0; i < _tcslen (out); i++) { + if ((out[i] == '/' || out[i] == '\\') && (out[i + 1] == '/' || out[i + 1] == '\\')) { + memmove (out + i, out + i + 1, (_tcslen (out + i) + 1) * sizeof (TCHAR)); + i--; + continue; + } + } } #else static void manglefilename(TCHAR *out, const TCHAR *in) @@ -1028,7 +1037,10 @@ static struct zfile *zfile_fopen_x (const TCHAR *name, const TCHAR *mode, int ma struct zfile *l, *l2; TCHAR path[MAX_DPATH]; + if (_tcslen (name) == 0) + return NULL; manglefilename (path, name); + //write_log (L"zfile_fopen('%s','%s',%08x)\n", path, mode, mask); l = zfile_fopen_2 (path, mode, mask); if (!l) return 0; @@ -1054,10 +1066,41 @@ static struct zfile *zfile_fopen_x (const TCHAR *name, const TCHAR *mode, int ma struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask) { struct zfile *f; - //write_log (L"zfile_fopen('%s','%s',%08x)\n", name, mode, mask); + TCHAR tmp[MAX_DPATH]; + TCHAR dirsep[2] = { FSDB_DIR_SEPARATOR, '\0' }; + f = zfile_fopen_x (name, mode, mask); - //write_log (L"=%p\n", f); - return f; + if (f) + return f; + if (_tcslen (name) <= 2) + return NULL; + if (name[1] != ':') { + _tcscpy (tmp, start_path_data); + _tcscat (tmp, name); + f = zfile_fopen_x (tmp, mode, mask); + if (f) + return f; + } +#if 0 + name += 2; + if (name[0] == '/' || name[0] == '\\') + name++; + for (;;) { + _tcscpy (tmp, start_path_data); + _tcscpy (tmp, name); + f = zfile_fopen_x (tmp, mode, mask); + if (f) + return f; + while (name[0]) { + name++; + if (name[-1] == '/' || name[-1] == '\\') + break; + } + if (name[0] == 0) + break; + } +#endif + return NULL; } -- 2.47.3