From: Toni Wilen Date: Wed, 6 Jul 2005 15:56:24 +0000 (+0300) Subject: imported winuaesrc1100b1.zip X-Git-Tag: 2100~309 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=8cfd140bb6865343640fc300c01f48ce40859ba0;p=francis%2Fwinuae.git imported winuaesrc1100b1.zip --- diff --git a/arcadia.c b/arcadia.c index eab2eb13..851d8dc2 100755 --- a/arcadia.c +++ b/arcadia.c @@ -35,7 +35,7 @@ * - ar_xeon * */ - + int arcadia_flag, arcadia_coin[2]; struct arcadiarom *arcadia_rom; @@ -75,7 +75,7 @@ static int load_rom8 (char *xpath, uae_u8 *mem, int isbin) int i; uae_u8 *tmp = xmalloc (131072); char *bin = isbin ? ".bin" : ""; - + memset (tmp, 0, 131072); sprintf (path, "%sh%s", xpath, bin); zf = zfile_fopen (path, "rb"); @@ -132,15 +132,15 @@ static int load_roms (char *xpath, struct arcadiarom *rom) { char path[MAX_DPATH], path2[MAX_DPATH], path3[MAX_DPATH], *p; int i; - + strcpy (path3, xpath); p = path3 + strlen (path3) - 1; while (p > path3) { if (p[0] == '\\' || p[0] == '/') { *p = 0; break; - } - p--; + } + p--; } if (p == path3) *p = 0; @@ -150,9 +150,9 @@ static int load_roms (char *xpath, struct arcadiarom *rom) sprintf (path, "%s/ar_bios.zip/%s", path3, rom->bios); if (!load_rom8 (path, arbmemory + bios_offset, 0)) { - write_log ("Arcadia: bios load failed ('%s')\n", path); + write_log ("Arcadia: bios load failed ('%s')\n", path); sprintf (path, "%s/%s", path2, rom->bios); - if (!load_rom8 (path, arbmemory + bios_offset, 0)) { + if (!load_rom8 (path, arbmemory + bios_offset, 0)) { write_log ("Arcadia: bios load failed ('%s')\n", path); return 0; } @@ -160,10 +160,10 @@ static int load_roms (char *xpath, struct arcadiarom *rom) write_log ("Arcadia: bios '%s' loaded\n", path); i = 0; for (;;) { - sprintf (path, "%s/%s%d", xpath, rom->rom, i + 1); + sprintf (path, "%s/%s%d", xpath, rom->rom, i + 1); if (!load_rom8 (path, arbmemory + 2 * 65536 * i, rom->bin)) { if (i == 0) - write_log ("Arcadia: game rom load failed ('%s')\n", path); + write_log ("Arcadia: game rom load failed ('%s')\n", path); break; } i++; @@ -177,7 +177,7 @@ static int load_roms (char *xpath, struct arcadiarom *rom) static uae_u8 bswap (uae_u8 v,int b7,int b6,int b5,int b4,int b3,int b2,int b1,int b0) { uae_u8 b = 0; - + b |= ((v >> b7) & 1) << 7; b |= ((v >> b6) & 1) << 6; b |= ((v >> b5) & 1) << 5; @@ -192,7 +192,7 @@ static uae_u8 bswap (uae_u8 v,int b7,int b6,int b5,int b4,int b3,int b2,int b1,i static void decrypt_roms (struct arcadiarom *rom) { int i, j; - + for (i = 1; i < 0x20000; i += 2) arbmemory[i] = bswap (arbmemory[i], rom->b7,rom->b6,rom->b5,rom->b4,rom->b3,rom->b2,rom->b1,rom->b0); @@ -347,8 +347,8 @@ static void nvram_write (void) { struct zfile *f = zfile_fopen (currprefs.flashfile, "rb+"); if (!f) { - f = zfile_fopen (currprefs.flashfile, "wb"); - if (!f) + f = zfile_fopen (currprefs.flashfile, "wb"); + if (!f) return; } zfile_fwrite (arbmemory + nvram_offset, NVRAM_SIZE, 1, f); diff --git a/audio.c b/audio.c index 1f51bb04..4e5c9477 100755 --- a/audio.c +++ b/audio.c @@ -212,7 +212,7 @@ static void do_samplerip(struct audio_channel_data *adp) rs = rs->next; cnt++; } - if (rs) + if (rs || cnt > 100) return; rs = xmalloc(sizeof(struct ripped_sample)); if (prev) diff --git a/autoconf.c b/autoconf.c index 0d94c4ff..e9d9c2e1 100755 --- a/autoconf.c +++ b/autoconf.c @@ -30,6 +30,11 @@ static uaecptr trapoldfunc[MAX_TRAPS]; static int max_trap; int lasttrap; +//#define sm_log write_log +#define sm_log + +#ifdef CAN_DO_STACK_MAGIC + /* Stack management */ /* The mechanism for doing m68k calls from native code is as follows: @@ -65,124 +70,123 @@ int lasttrap; #ifndef EXTRA_STACK_SIZE #define EXTRA_STACK_SIZE 32768 #endif +#ifdef _WIN32 +#define WIN32_EXTRA_STACKS 30 +static void *win32_freestack[WIN32_EXTRA_STACKS]; //EXTRA_STACK_SIZE +#endif + +struct extra_stack +{ + jmp_buf stackswap_env; + jmp_buf m68kcall_env; + uaecptr m68kcall_addr; + void *stack[EXTRA_STACK_SIZE - 2*sizeof(jmp_buf) - sizeof(uaecptr)]; +}; -static void *extra_stack_list = NULL; -static void *get_extra_stack (void) +static struct extra_stack *get_extra_stack (void) { - void *s = extra_stack_list; - //if (s) - //extra_stack_list = *(void **)s; - if (!s) { -#ifndef _MSC_VER - s = xmalloc (EXTRA_STACK_SIZE); -#else - { - static long opencount=0; - extern unsigned long *win32_stackbase; - int i; - extern unsigned long *win32_freestack[42]; - for (i=0;i<41;i++) {//0 to MAX_SELECT_THREADS - if(!win32_freestack[i]) - break; //get a free block - } - s=win32_stackbase+(i*EXTRA_STACK_SIZE); - win32_freestack[i]=s; + struct extra_stack *s; + +#ifdef _WIN32 + { + extern uae_u8 *win32_stackbase; + int i; + for (i = 0;i < WIN32_EXTRA_STACKS; i++) { //0 to MAX_SELECT_THREADS + if(!win32_freestack[i]) + break; //get a free block } -#endif + if (i == WIN32_EXTRA_STACKS) { + gui_message("run out of extra stacks. this shouldn't happen."); + i = 0; + } + s = (struct extra_stack*)(win32_stackbase + (i * EXTRA_STACK_SIZE)); + win32_freestack[i] = s; } +#else + s = xmalloc (sizeof (struct extra_stack)); +#endif return s; } -static void free_extra_stack (void *s) +static void free_extra_stack (struct extra_stack *s) { - //*(void **)s = extra_stack_list; - //extra_stack_list = s; - { - int i; - extern unsigned long *win32_freestack[42]; - for (i=0;i<41;i++) {//0 to MAX_SELECT_THREADS - if(win32_freestack[i]==s) - break; //get a free block - } - win32_freestack[i]=0; +#ifdef _WIN32 + int i; + for (i = 0; i < WIN32_EXTRA_STACKS; i++) {//0 to MAX_SELECT_THREADS + if(win32_freestack[i] == s) + break; //got a free block } + win32_freestack[i] = 0; +#else + free (s); +#endif } -static void stack_stub (void *s, TrapFunction f, uae_u32 *retval) +static void stack_stub (struct extra_stack *s, TrapFunction f, uae_u32 *retval) { -#ifdef CAN_DO_STACK_MAGIC - /*printf("in stack_stub: %p %p %p %x\n", s, f, retval, (int)*retval);*/ + sm_log("in stack_stub: %p %p %p %x\n", s, f, retval, (int)*retval); *retval = f (); - /*write_log ("returning from stack_stub\n");*/ - longjmp (((jmp_buf *)s)[0], 1); -#endif + sm_log("returning from stack_stub\n"); + longjmp (s->stackswap_env, 1); } -static void *current_extra_stack = NULL; -static uaecptr m68k_calladdr; +static struct extra_stack *current_extra_stack = NULL; -static void do_stack_magic (TrapFunction f, void *s, int has_retval) +static void do_stack_magic (TrapFunction f, struct extra_stack *s, int has_retval) { -#ifdef CAN_DO_STACK_MAGIC - uaecptr a7; - jmp_buf *j = (jmp_buf *)s; - switch (setjmp (j[0])) { + switch (setjmp (s->stackswap_env)) { case 0: /* Returning directly */ current_extra_stack = s; if (has_retval == -1) { - /*write_log ("finishing m68k mode return\n");*/ - longjmp (j[1], 1); + sm_log("finishing m68k mode return\n"); + longjmp (s->m68kcall_env, 1); } - /*write_log ("calling native function\n");*/ + sm_log("calling native function\n"); transfer_control (s, EXTRA_STACK_SIZE, stack_stub, f, has_retval); /* not reached */ abort (); case 1: - /*write_log ("native function complete\n");*/ + sm_log("native function complete\n"); /* Returning normally. */ if (stack_has_retval (s, EXTRA_STACK_SIZE)) m68k_dreg (regs, 0) = get_retval_from_stack (s, EXTRA_STACK_SIZE); free_extra_stack (s); break; - case 2: + case 2: { /* Returning to do a m68k call. We're now back on the main stack. */ - a7 = m68k_areg(regs, 7) -= (sizeof (void *) + 7) & ~3; + uaecptr a7 = m68k_areg (regs, 7) -= (sizeof (void *) + 7) & ~3; /* Save stack to restore */ *((void **)get_real_address (a7 + 4)) = s; /* Save special return address: this address contains a * calltrap that will longjmp to the right stack. */ put_long (m68k_areg (regs, 7), RTAREA_BASE + 0xFF00); - m68k_setpc (m68k_calladdr); + m68k_setpc (s->m68kcall_addr); fill_prefetch_slow (); - /*write_log ("native function calls m68k\n");*/ + sm_log("native function calls m68k\n"); break; + } } current_extra_stack = 0; -#endif } static uae_u32 execute_fn_on_extra_stack (TrapFunction f, int has_retval) { -#ifdef CAN_DO_STACK_MAGIC - void *s = get_extra_stack (); + struct extra_stack *s = get_extra_stack (); do_stack_magic (f, s, has_retval); -#endif return 0; } static uae_u32 m68k_mode_return (void) { -#ifdef CAN_DO_STACK_MAGIC - uaecptr a7 = m68k_areg(regs, 7); - void *s = *(void **)get_real_address(a7); - m68k_areg(regs, 7) += (sizeof (void *) + 3) & ~3; - /*write_log ("doing m68k mode return\n");*/ + uaecptr a7 = m68k_areg (regs, 7); + struct extra_stack *s = *(struct extra_stack **)get_real_address (a7); + m68k_areg (regs, 7) += (sizeof (void *) + 3) & ~3; + sm_log("doing m68k mode return\n"); do_stack_magic (NULL, s, -1); -#endif return 0; } @@ -190,21 +194,25 @@ static uae_u32 call_m68k (uaecptr addr, int saveregs) { volatile uae_u32 retval = 0; volatile int do_save = saveregs; - if (current_extra_stack == NULL) - abort(); -#ifdef CAN_DO_STACK_MAGIC + + sm_log("\nDoing call_m68k (addr=%08x, savereg=%d) extra_stack=%p\n", + addr,saveregs,current_extra_stack); + + if (current_extra_stack != NULL) { volatile struct regstruct saved_regs; - jmp_buf *j = (jmp_buf *)current_extra_stack; + struct extra_stack *s = current_extra_stack; if (do_save) saved_regs = regs; - m68k_calladdr = addr; - switch (setjmp(j[1])) { + + s->m68kcall_addr = addr; + + switch (setjmp (s->m68kcall_env)) { case 0: /*write_log ("doing call\n");*/ /* Returning directly: now switch to main stack and do the call */ - longjmp (j[0], 2); + longjmp (s->stackswap_env, 2); case 1: /*write_log ("returning from call\n");*/ retval = m68k_dreg (regs, 0); @@ -213,15 +221,16 @@ static uae_u32 call_m68k (uaecptr addr, int saveregs) /* Returning after the call. */ break; } - } -#endif + } else + abort (); + return retval; } uae_u32 CallLib (uaecptr base, uae_s16 offset) { int i; - uaecptr olda6 = m68k_areg(regs, 6); + uaecptr olda6 = m68k_areg (regs, 6); uae_u32 retval; #if 0 for (i = 0; i < n_libpatches; i++) { @@ -229,12 +238,31 @@ uae_u32 CallLib (uaecptr base, uae_s16 offset) return (*libpatches[i].functions[-offset/6])(); } #endif - m68k_areg(regs, 6) = base; - retval = call_m68k(base + offset, 1); - m68k_areg(regs, 6) = olda6; + m68k_areg (regs, 6) = base; + retval = call_m68k (base + offset, 1); + m68k_areg (regs, 6) = olda6; return retval; } +#else + +/* + * Stubs for when building without stack magic + */ +static uae_u32 m68k_mode_return (void) +{ + return 0; +} + +uae_u32 CallLib (uaecptr base, uae_s16 offset) +{ + /* Shouldn't be necessary */ + write_log ("WARNING: Calling 68k code from UAE is not supported in this version.\n"); + return 0; +} + +#endif + /* Commonly used autoconfig strings */ uaecptr EXPANSION_explibname, EXPANSION_doslibname, EXPANSION_uaeversion; @@ -268,43 +296,55 @@ uae_u8 REGPARAM2 *rtarea_xlate (uaecptr addr) uae_u32 REGPARAM2 rtarea_lget (uaecptr addr) { +#ifdef JIT special_mem |= S_READ; +#endif addr &= 0xFFFF; return (uae_u32)(rtarea_wget (addr) << 16) + rtarea_wget (addr+2); } uae_u32 REGPARAM2 rtarea_wget (uaecptr addr) { +#ifdef JIT special_mem |= S_READ; +#endif addr &= 0xFFFF; return (rtarea[addr]<<8) + rtarea[addr+1]; } uae_u32 REGPARAM2 rtarea_bget (uaecptr addr) { +#ifdef JIT special_mem |= S_READ; +#endif addr &= 0xFFFF; return rtarea[addr]; } void REGPARAM2 rtarea_lput (uaecptr addr, uae_u32 value) { +#ifdef JIT special_mem |= S_WRITE; +#endif } void REGPARAM2 rtarea_wput (uaecptr addr, uae_u32 value) { +#ifdef JIT special_mem |= S_WRITE; +#endif } void REGPARAM2 rtarea_bput (uaecptr addr, uae_u32 value) { +#ifdef JIT special_mem |= S_WRITE; +#endif } static const int trace_traps = 1; -void REGPARAM2 call_calltrap(int func) +void REGPARAM2 call_calltrap (int func) { uae_u32 retval = 0; int has_retval = (trapmode[func] & TRAPFLAG_NO_RETVAL) == 0; @@ -315,29 +355,32 @@ void REGPARAM2 call_calltrap(int func) /* For monitoring only? */ if (traps[func] == NULL) { - m68k_setpc(trapoldfunc[func]); + m68k_setpc (trapoldfunc[func]); fill_prefetch_slow (); return; } if (func < max_trap) { +#ifdef CAN_DO_STACK_MAGIC if (trapmode[func] & TRAPFLAG_EXTRA_STACK) { execute_fn_on_extra_stack(traps[func], has_retval); return; } +#endif retval = (*traps[func])(); } else write_log ("illegal emulator trap\n"); if (has_retval) - m68k_dreg(regs, 0) = retval; + m68k_dreg (regs, 0) = retval; if (implicit_rts) { m68k_do_rts (); fill_prefetch_slow (); } } -/* @$%&ยง compiler bugs */ +#ifdef CAN_DO_STACK_MAGIC +/* @$%& compiler bugs */ static volatile int four = 4; uaecptr libemu_InstallFunctionFlags (TrapFunction f, uaecptr libbase, int offset, @@ -347,13 +390,13 @@ uaecptr libemu_InstallFunctionFlags (TrapFunction f, uaecptr libbase, int offset uaecptr retval; uaecptr execbase = get_long (four); int trnum; - uaecptr addr = here(); + uaecptr addr = here (); calltrap (trnum = deftrap2 (f, flags, tracename)); dw (RTS); - m68k_areg(regs, 1) = libbase; - m68k_areg(regs, 0) = offset; - m68k_dreg(regs, 0) = addr; + m68k_areg (regs, 1) = libbase; + m68k_areg (regs, 0) = offset; + m68k_dreg (regs, 0) = addr; retval = CallLib (execbase, -420); trapoldfunc[trnum] = retval; @@ -373,6 +416,7 @@ uaecptr libemu_InstallFunctionFlags (TrapFunction f, uaecptr libbase, int offset #endif return retval; } +#endif /* some quick & dirty code to fill in the rt area and save me a lot of * scratch paper @@ -453,7 +497,7 @@ void align (int b) rt_addr = (rt_addr + b - 1) & ~(b - 1); } -static uae_u32 nullfunc(void) +static uae_u32 nullfunc (void) { write_log ("Null function called\n"); return 0; @@ -519,7 +563,9 @@ void rtarea_init (void) org (a); +#ifdef FILESYS filesys_install_code (); +#endif } volatile int uae_int_requested = 0; @@ -529,6 +575,6 @@ void set_uae_int_flag (void) rtarea[0xFFFB] = uae_int_requested; } -void rtarea_setup(void) +void rtarea_setup (void) { } diff --git a/blitter.c b/blitter.c index d9aa4357..1338894e 100755 --- a/blitter.c +++ b/blitter.c @@ -41,6 +41,7 @@ int blit_singlechannel; #ifdef BLITTER_DEBUG static int blitter_dontdo; +static int blitter_delayed_debug; #endif #ifdef BLITTER_SLOWDOWNDEBUG static int blitter_slowdowndebug; @@ -116,7 +117,7 @@ static uae_u8 blit_cycle_diagram_fill[][10] = static uae_u8 blit_cycle_diagram_line[] = { - 0, 4, 0,0,0,4 /* total guess.. */ + 0, 2, 0,4,0,4 /* total guess.. */ }; void build_blitfilltable(void) @@ -169,6 +170,23 @@ STATIC_INLINE uae_u8 *blit_xlateptr_desc(uaecptr bltpt, int bytecount) return chipmem_bank.xlateaddr(bltpt); } +STATIC_INLINE int channel_state (int cycles) +{ + if (cycles < 0) + return 0; + if (cycles < blit_diag[0]) + return blit_diag[blit_diag[1] + 2 + cycles]; + return blit_diag[((cycles - blit_diag[0]) % blit_diag[1]) + 2]; +} + +int is_bitplane_dma (int hpos); +STATIC_INLINE int canblit (int hpos) +{ + if ((cycle_line[hpos] == 0 || cycle_line[hpos] == CYCLE_NOCPU) && !is_bitplane_dma (hpos)) + return 1; + return 0; +} + static void blitter_done (void) { ddat1use = ddat2use = 0; @@ -371,29 +389,27 @@ static void blitter_dofast_desc(void) bltstate = BLT_done; } -STATIC_INLINE int blitter_read(void) +STATIC_INLINE void blitter_read(void) { if (bltcon0 & 0x200) { if (!dmaen(DMA_BLITTER)) - return 1; + return; blt_info.bltcdat = chipmem_bank.wget(bltcpt); } bltstate = BLT_work; - return (bltcon0 & 0x200) != 0; } -STATIC_INLINE int blitter_write(void) +STATIC_INLINE void blitter_write(void) { if (blt_info.bltddat) blt_info.blitzero = 0; /* D-channel state has no effect on linedraw, but C must be enabled or nothing is drawn! */ if (bltcon0 & 0x200) { - if (!dmaen(DMA_BLITTER)) return 1; + if (!dmaen(DMA_BLITTER)) + return; chipmem_bank.wput(bltdpt, blt_info.bltddat); - bltdpt = bltcpt; /* believe it or not but try Cardamon or Cardamom without this.. */ } bltstate = BLT_next; - return (bltcon0 & 0x200) != 0; } STATIC_INLINE void blitter_line_incx(void) @@ -429,7 +445,6 @@ static void blitter_line(void) uae_u16 blitahold = blinea >> blinea_shift; uae_u16 blitbhold = blineb & 1 ? 0xFFFF : 0; uae_u16 blitchold = blt_info.bltcdat; - blt_info.bltddat = 0; if (blitsing && blitonedot) blitahold = 0; @@ -471,13 +486,66 @@ static void blitter_line(void) STATIC_INLINE void blitter_nxline(void) { blineb = (blineb << 1) | (blineb >> 15); - if (--blt_info.vblitsize == 0) { - bltstate = BLT_done; + blt_info.vblitsize--; + bltstate = BLT_read; +} + +#ifdef CPUEMU_6 + +static int blit_last_hpos; + +static int blitter_dma_cycles_line, blitter_dma_cycles_line_count; +static int blitter_cyclecounter; +static int blitter_hcounter1, blitter_hcounter2; +static int blitter_vcounter1, blitter_vcounter2; + +static void decide_blitter_line (int hpos) +{ + hpos++; + if (dmaen (DMA_BLITTER)) { + while (blit_last_hpos < hpos) { + int c = blit_cyclecounter % 2; + for (;;) { + if (blit_cyclecounter < 0) { + blit_cyclecounter++; + break; + } +#if 1 + if ((c == 0 || c == 1) && !canblit(blit_last_hpos)) + break; +#endif +#if 1 + //if (c == 1) + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; +#endif + blit_cyclecounter++; + if (c == 1) { + /* believe it or not but try Cardamon or Cardamom without this.. */ + if (ddat1use) + bltdpt = bltcpt; + blitter_read(); + blitter_line(); + blitter_write(); + blitter_nxline(); + ddat1use = 1; + if (blt_info.vblitsize == 0) { + blitter_done(); + return; + } + } + break; + } + blit_last_hpos++; + } } else { - bltstate = BLT_read; + blit_last_hpos = hpos; } + if (blit_last_hpos > maxhpos) + blit_last_hpos = 0; } +#endif + static void actually_do_blit(void) { if (blitline) { @@ -485,7 +553,10 @@ static void actually_do_blit(void) blitter_read(); blitter_line(); blitter_write(); + bltdpt = bltcpt; blitter_nxline(); + if (blt_info.vblitsize == 0) + bltstate = BLT_done; } while (bltstate != BLT_done); } else { if (blitdesc) @@ -522,33 +593,8 @@ void blitter_handler(void) blitter_done (); } -STATIC_INLINE int channel_state (int cycles) -{ - if (cycles < 0) - return 0; - if (cycles < blit_diag[0]) - return blit_diag[blit_diag[1] + 2 + cycles]; - return blit_diag[((cycles - blit_diag[0]) % blit_diag[1]) + 2]; -} - -int is_bitplane_dma (int hpos); -STATIC_INLINE int canblit (int hpos) -{ - if ((cycle_line[hpos] == 0 || cycle_line[hpos] == CYCLE_NOCPU) && !is_bitplane_dma (hpos)) - return 1; - return 0; -} - #ifdef CPUEMU_6 -static int blit_last_hpos; - -static int blitter_dma_cycles_line, blitter_dma_cycles_line_count; -static int blitter_cyclecounter; -static int blitter_hcounter1, blitter_hcounter2; -static int blitter_vcounter1, blitter_vcounter2; - - static uae_u32 preva, prevb; STATIC_INLINE uae_u16 blitter_doblit (void) { @@ -668,45 +714,16 @@ STATIC_INLINE void blitter_dodma (int ch) } } -static void decide_blitter_line (int hpos) -{ - hpos++; - if (dmaen (DMA_BLITTER)) { - while (blit_last_hpos < hpos) { - int c = channel_state (blit_cyclecounter); - for (;;) { - if (c && !canblit (blit_last_hpos)) - break; - if (c) - cycle_line[blit_last_hpos] |= CYCLE_BLITTER; - blit_cyclecounter++; - blit_linecyclecounter++; - if (blit_linecyclecounter >= blit_diag[1]) { - blit_linecyclecounter = 0; - blitter_read(); - blitter_line(); - blitter_write(); - blitter_nxline(); - if (bltstate == BLT_done) { - blitter_done (); - return; - } - } - break; - } - blit_last_hpos++; - } - } else { - blit_last_hpos = hpos; - } - if (blit_last_hpos > maxhpos) - blit_last_hpos = 0; -} - void decide_blitter (int hpos) { if (bltstate == BLT_done) return; +#ifdef BLITTER_DEBUG + if (blitter_delayed_debug) { + blitter_delayed_debug = 0; + blitter_dump(); + } +#endif if (!currprefs.blitter_cycle_exact) return; if (blitline) { @@ -892,11 +909,11 @@ void do_blitter (int hpos) prevb = 0; blit_firstline_cycles = blit_first_cycle = get_cycles (); - blit_cyclecounter = -1; blit_misscyclecounter = 0; blit_last_cycle = 0; blit_maxcyclecounter = 0; blit_last_hpos = hpos; + blit_cyclecounter = 0; reset_blit (1|2); @@ -979,15 +996,19 @@ void maybe_blit (int hpos, int hack) if (currprefs.blitter_cycle_exact) { decide_blitter (hpos); - return; + goto end; } if (!eventtab[ev_blitter].active) write_log ("FOO!!?\n"); if (hack == 1 && get_cycles() < blit_firstline_cycles) - return; + goto end; blitter_handler (); +end:; +#ifdef BLITTER_DEBUG + blitter_delayed_debug = 1; +#endif } int blitnasty (void) diff --git a/blitter2.c b/blitter2.c new file mode 100755 index 00000000..d9aa4357 --- /dev/null +++ b/blitter2.c @@ -0,0 +1,1067 @@ + /* + * UAE - The Un*x Amiga Emulator + * + * Custom chip emulation + * + * (c) 1995 Bernd Schmidt, Alessandro Bissacco + * (c) 2002 - 2003 Toni Wilen + */ + +//#define BLITTER_DEBUG +//#define BLITTER_SLOWDOWNDEBUG 4 + +#define SPEEDUP + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "config.h" +#include "options.h" +#include "uae.h" +#include "memory.h" +#include "custom.h" +#include "events.h" +#include "newcpu.h" +#include "blitter.h" +#include "blit.h" +#include "savestate.h" + +uae_u16 oldvblts; +uae_u16 bltcon0,bltcon1; +uae_u32 bltapt,bltbpt,bltcpt,bltdpt; + +int blinea_shift; +static uae_u16 blinea, blineb; +static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc; +static int blitonedot,blitsign; +static int blit_add; +static int blit_modadda, blit_modaddb, blit_modaddc, blit_modaddd; +static int blit_ch; +int blit_singlechannel; + +#ifdef BLITTER_DEBUG +static int blitter_dontdo; +#endif +#ifdef BLITTER_SLOWDOWNDEBUG +static int blitter_slowdowndebug; +#endif + +struct bltinfo blt_info; + +static uae_u8 blit_filltable[256][4][2]; +uae_u32 blit_masktable[BLITTER_MAX_WORDS]; +static uae_u16 blit_trashtable[BLITTER_MAX_WORDS]; +enum blitter_states bltstate; + +static int blit_cyclecounter, blit_maxcyclecounter, blit_slowdown; +static int blit_linecyclecounter, blit_misscyclecounter; + +#ifdef CPUEMU_6 +extern uae_u8 cycle_line[]; +#endif + +static long blit_firstline_cycles; +static long blit_first_cycle; +static int blit_last_cycle, blit_dmacount, blit_dmacount2; +static int blit_linecycles, blit_extracycles; +static uae_u8 *blit_diag; + +static uae_u16 ddat1, ddat2; +static int ddat1use, ddat2use; + +static uae_u8 blit_cycle_diagram_finald[] = + { 0, 2, 0,4 }; + +static uae_u8 blit_cycle_diagram[][10] = +{ + { 0, 2, 0,0 }, /* 0 */ + { 0, 2, 4,0 }, /* 1 */ + { 0, 2, 3,0 }, /* 2 */ + { 2, 3, 0,3,4, 3,0 }, /* 3 */ + { 0, 3, 2,0,0 }, /* 4 */ + { 2, 3, 0,2,4, 2,0 }, /* 5 */ + { 0, 3, 2,3,0 }, /* 6 */ + { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ + { 0, 2, 1,0 }, /* 8 */ + { 2, 2, 1,4, 1,0 }, /* 9 */ + { 0, 2, 1,3 }, /* A */ + { 3, 3, 1,3,4, 1,3,0 }, /* B */ + { 2, 3, 0,1,2, 1,2 }, /* C */ + { 3, 3, 1,2,4, 1,2,0 }, /* D */ + { 0, 3, 1,2,3 }, /* E */ + { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ +}; + +/* fill mode always adds C-channel to cycle-diagram */ +/* Reflect - Sound Vision freezes without this */ +static uae_u8 blit_cycle_diagram_fill[][10] = +{ + { 0, 2, 0,0 }, /* 0 */ + { 0, 3, 0,3,4 }, /* 1 */ + { 0, 2, 3,0 }, /* 2 */ + { 2, 3, 0,3,4, 3,0 }, /* 3 */ + { 0, 3, 2,0,0 }, /* 4 */ + { 3, 4, 0,2,0,4, 2,0,0 }, /* 5 */ + { 0, 3, 2,3,0 }, /* 6 */ + { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ + { 0, 2, 1,0 }, /* 8 */ + { 3, 3, 1,0,4, 1,0,0}, /* 9 */ + { 0, 2, 1,3 }, /* A */ + { 3, 3, 1,3,4, 1,3,0 }, /* B */ + { 2, 3, 0,1,2, 1,2 }, /* C */ + { 4, 4, 1,2,0,4, 1,2,0,0 }, /* D */ + { 0, 3, 1,2,3 }, /* E */ + { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ +}; + +static uae_u8 blit_cycle_diagram_line[] = +{ + 0, 4, 0,0,0,4 /* total guess.. */ +}; + +void build_blitfilltable(void) +{ + unsigned int d, fillmask; + int i; + + for (i = 0; i < BLITTER_MAX_WORDS; i++) + blit_masktable[i] = 0xFFFF; + + for (d = 0; d < 256; d++) { + for (i = 0; i < 4; i++) { + int fc = i & 1; + uae_u8 data = d; + for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) { + uae_u16 tmp = data; + if (fc) { + if (i & 2) + data |= fillmask; + else + data ^= fillmask; + } + if (tmp & fillmask) fc = !fc; + } + blit_filltable[d][i][0] = data; + blit_filltable[d][i][1] = fc; + } + } +} + +static void blitter_dump (void) +{ + write_log ("APT=%08.8X BPT=%08.8X CPT=%08.8X DPT=%08.8X\n", bltapt, bltbpt, bltcpt, bltdpt); + write_log ("CON0=%04.4X CON1=%04.4X ADAT=%04.4X BDAT=%04.4X CDAT=%04.4X\n", + bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); + write_log ("AFWM=%04.4X ALWM=%04.4X AMOD=%04.4X BMOD=%04.4X CMOD=%04.4X DMOD=%04.4X\n", + blt_info.bltafwm, blt_info.bltalwm, + blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); +} + +STATIC_INLINE uae_u8 *blit_xlateptr(uaecptr bltpt, int bytecount) +{ + if (!chipmem_bank.check(bltpt,bytecount)) return NULL; + return chipmem_bank.xlateaddr(bltpt); +} + +STATIC_INLINE uae_u8 *blit_xlateptr_desc(uaecptr bltpt, int bytecount) +{ + if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL; + return chipmem_bank.xlateaddr(bltpt); +} + +static void blitter_done (void) +{ + ddat1use = ddat2use = 0; + bltstate = BLT_done; + blitter_done_notify (); + INTREQ(0x8040); + eventtab[ev_blitter].active = 0; + unset_special (SPCFLAG_BLTNASTY); +#ifdef BLITTER_DEBUG + write_log ("vpos=%d, cycles %d, missed %d, total %d\n", + vpos, blit_cyclecounter, blit_misscyclecounter, blit_cyclecounter + blit_misscyclecounter); +#endif +} + +static void blitter_dofast(void) +{ + int i,j; + uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; + uae_u8 mt = bltcon0 & 0xFF; + + blit_masktable[0] = blt_info.bltafwm; + blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; + + if (bltcon0 & 0x800) { + bltadatptr = bltapt; + bltapt += (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; + } + if (bltcon0 & 0x400) { + bltbdatptr = bltbpt; + bltbpt += (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; + } + if (bltcon0 & 0x200) { + bltcdatptr = bltcpt; + bltcpt += (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; + } + if (bltcon0 & 0x100) { + bltddatptr = bltdpt; + bltdpt += (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; + } + +#ifdef SPEEDUP + if (blitfunc_dofast[mt] && !blitfill) { + (*blitfunc_dofast[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); + } else +#endif + { + uae_u32 blitbhold = blt_info.bltbhold; + uae_u32 preva = 0, prevb = 0; + uaecptr dstp = 0; + int dodst = 0; + + /*if (!blitfill) write_log ("minterm %x not present\n",mt); */ + for (j = 0; j < blt_info.vblitsize; j++) { + blitfc = !!(bltcon1 & 0x4); + for (i = 0; i < blt_info.hblitsize; i++) { + uae_u32 bltadat, blitahold; + uae_u16 bltbdat; + if (bltadatptr) { + blt_info.bltadat = bltadat = chipmem_agnus_wget (bltadatptr); + bltadatptr += 2; + } else + bltadat = blt_info.bltadat; + bltadat &= blit_masktable[i]; + blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; + preva = bltadat; + + if (bltbdatptr) { + blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); + bltbdatptr += 2; + blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift; + prevb = bltbdat; + } + + if (bltcdatptr) { + blt_info.bltcdat = chipmem_agnus_wget (bltcdatptr); + bltcdatptr += 2; + } + if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; + if (blitfill) { + uae_u16 d = blt_info.bltddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + if (blt_info.bltddat) + blt_info.blitzero = 0; + if (bltddatptr) { + dodst = 1; + dstp = bltddatptr; + bltddatptr += 2; + } + } + if (bltadatptr) bltadatptr += blt_info.bltamod; + if (bltbdatptr) bltbdatptr += blt_info.bltbmod; + if (bltcdatptr) bltcdatptr += blt_info.bltcmod; + if (bltddatptr) bltddatptr += blt_info.bltdmod; + } + if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltbhold = blitbhold; + } + blit_masktable[0] = 0xFFFF; + blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; + + bltstate = BLT_done; +} + +static void blitter_dofast_desc(void) +{ + int i,j; + uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; + uae_u8 mt = bltcon0 & 0xFF; + + blit_masktable[0] = blt_info.bltafwm; + blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; + + if (bltcon0 & 0x800) { + bltadatptr = bltapt; + bltapt -= (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; + } + if (bltcon0 & 0x400) { + bltbdatptr = bltbpt; + bltbpt -= (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; + } + if (bltcon0 & 0x200) { + bltcdatptr = bltcpt; + bltcpt -= (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; + } + if (bltcon0 & 0x100) { + bltddatptr = bltdpt; + bltdpt -= (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; + } +#ifdef SPEEDUP + if (blitfunc_dofast_desc[mt] && !blitfill) { + (*blitfunc_dofast_desc[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); + } else +#endif + { + uae_u32 blitbhold = blt_info.bltbhold; + uae_u32 preva = 0, prevb = 0; + uaecptr dstp = 0; + int dodst = 0; + + for (j = 0; j < blt_info.vblitsize; j++) { + blitfc = !!(bltcon1 & 0x4); + for (i = 0; i < blt_info.hblitsize; i++) { + uae_u32 bltadat, blitahold; + uae_u16 bltbdat; + if (bltadatptr) { + bltadat = blt_info.bltadat = chipmem_agnus_wget (bltadatptr); + bltadatptr -= 2; + } else + bltadat = blt_info.bltadat; + bltadat &= blit_masktable[i]; + blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; + preva = bltadat; + + if (bltbdatptr) { + blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); + bltbdatptr -= 2; + blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift; + prevb = bltbdat; + } + + if (bltcdatptr) { + blt_info.bltcdat = blt_info.bltbdat = chipmem_agnus_wget (bltcdatptr); + bltcdatptr -= 2; + } + if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; + if (blitfill) { + uae_u16 d = blt_info.bltddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + if (blt_info.bltddat) + blt_info.blitzero = 0; + if (bltddatptr) { + dstp = bltddatptr; + dodst = 1; + bltddatptr -= 2; + } + } + if (bltadatptr) bltadatptr -= blt_info.bltamod; + if (bltbdatptr) bltbdatptr -= blt_info.bltbmod; + if (bltcdatptr) bltcdatptr -= blt_info.bltcmod; + if (bltddatptr) bltddatptr -= blt_info.bltdmod; + } + if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltbhold = blitbhold; + } + blit_masktable[0] = 0xFFFF; + blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; + + bltstate = BLT_done; +} + +STATIC_INLINE int blitter_read(void) +{ + if (bltcon0 & 0x200) { + if (!dmaen(DMA_BLITTER)) + return 1; + blt_info.bltcdat = chipmem_bank.wget(bltcpt); + } + bltstate = BLT_work; + return (bltcon0 & 0x200) != 0; +} + +STATIC_INLINE int blitter_write(void) +{ + if (blt_info.bltddat) + blt_info.blitzero = 0; + /* D-channel state has no effect on linedraw, but C must be enabled or nothing is drawn! */ + if (bltcon0 & 0x200) { + if (!dmaen(DMA_BLITTER)) return 1; + chipmem_bank.wput(bltdpt, blt_info.bltddat); + bltdpt = bltcpt; /* believe it or not but try Cardamon or Cardamom without this.. */ + } + bltstate = BLT_next; + return (bltcon0 & 0x200) != 0; +} + +STATIC_INLINE void blitter_line_incx(void) +{ + if (++blinea_shift == 16) { + blinea_shift = 0; + bltcpt += 2; + } +} + +STATIC_INLINE void blitter_line_decx(void) +{ + if (blinea_shift-- == 0) { + blinea_shift = 15; + bltcpt -= 2; + } +} + +STATIC_INLINE void blitter_line_decy(void) +{ + bltcpt -= blt_info.bltcmod; + blitonedot = 0; +} + +STATIC_INLINE void blitter_line_incy(void) +{ + bltcpt += blt_info.bltcmod; + blitonedot = 0; +} + +static void blitter_line(void) +{ + uae_u16 blitahold = blinea >> blinea_shift; + uae_u16 blitbhold = blineb & 1 ? 0xFFFF : 0; + uae_u16 blitchold = blt_info.bltcdat; + blt_info.bltddat = 0; + + if (blitsing && blitonedot) + blitahold = 0; + blitonedot = 1; + blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF); + if (!blitsign){ + if (bltcon0 & 0x800) + bltapt += (uae_s16)blt_info.bltamod; + if (bltcon1 & 0x10){ + if (bltcon1 & 0x8) + blitter_line_decy(); + else + blitter_line_incy(); + } else { + if (bltcon1 & 0x8) + blitter_line_decx(); + else + blitter_line_incx(); + } + } else { + if (bltcon0 & 0x800) + bltapt += (uae_s16)blt_info.bltbmod; + } + if (bltcon1 & 0x10){ + if (bltcon1 & 0x4) + blitter_line_decx(); + else + blitter_line_incx(); + } else { + if (bltcon1 & 0x4) + blitter_line_decy(); + else + blitter_line_incy(); + } + blitsign = 0 > (uae_s16)bltapt; + bltstate = BLT_write; +} + +STATIC_INLINE void blitter_nxline(void) +{ + blineb = (blineb << 1) | (blineb >> 15); + if (--blt_info.vblitsize == 0) { + bltstate = BLT_done; + } else { + bltstate = BLT_read; + } +} + +static void actually_do_blit(void) +{ + if (blitline) { + do { + blitter_read(); + blitter_line(); + blitter_write(); + blitter_nxline(); + } while (bltstate != BLT_done); + } else { + if (blitdesc) + blitter_dofast_desc(); + else + blitter_dofast(); + bltstate = BLT_done; + } +} + +void blitter_handler(void) +{ + if (!dmaen(DMA_BLITTER)) { + eventtab[ev_blitter].active = 1; + eventtab[ev_blitter].oldcycles = get_cycles (); + eventtab[ev_blitter].evtime = 10 * CYCLE_UNIT + get_cycles (); /* wait a little */ + return; /* gotta come back later. */ + } + if (blit_slowdown > 0) { + eventtab[ev_blitter].active = 1; + eventtab[ev_blitter].oldcycles = get_cycles (); + eventtab[ev_blitter].evtime = blit_slowdown * CYCLE_UNIT + get_cycles (); + blit_slowdown = -1; + return; + } +#ifdef BLITTER_DEBUG + if (!blitter_dontdo) + actually_do_blit(); + else + bltstate = BLT_done; +#else + actually_do_blit (); +#endif + blitter_done (); +} + +STATIC_INLINE int channel_state (int cycles) +{ + if (cycles < 0) + return 0; + if (cycles < blit_diag[0]) + return blit_diag[blit_diag[1] + 2 + cycles]; + return blit_diag[((cycles - blit_diag[0]) % blit_diag[1]) + 2]; +} + +int is_bitplane_dma (int hpos); +STATIC_INLINE int canblit (int hpos) +{ + if ((cycle_line[hpos] == 0 || cycle_line[hpos] == CYCLE_NOCPU) && !is_bitplane_dma (hpos)) + return 1; + return 0; +} + +#ifdef CPUEMU_6 + +static int blit_last_hpos; + +static int blitter_dma_cycles_line, blitter_dma_cycles_line_count; +static int blitter_cyclecounter; +static int blitter_hcounter1, blitter_hcounter2; +static int blitter_vcounter1, blitter_vcounter2; + + +static uae_u32 preva, prevb; +STATIC_INLINE uae_u16 blitter_doblit (void) +{ + uae_u32 blitahold; + uae_u16 bltadat, ddat; + uae_u8 mt = bltcon0 & 0xFF; + + bltadat = blt_info.bltadat; + if (blitter_hcounter1 == 0) + bltadat &= blt_info.bltafwm; + if (blitter_hcounter1 == blt_info.hblitsize - 1) + bltadat &= blt_info.bltalwm; + if (blitdesc) + blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; + else + blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; + preva = bltadat; + + ddat = blit_func (blitahold, blt_info.bltbhold, blt_info.bltcdat, mt) & 0xFFFF; + + if (bltcon1 & 0x18) { + uae_u16 d = ddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + ddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + + if (ddat) + blt_info.blitzero = 0; + + return ddat; +} + + +STATIC_INLINE int blitter_doddma (void) +{ + int wd; + uae_u16 d; + + wd = 0; + if (blit_dmacount2 == 0) { + d = blitter_doblit (); + wd = -1; + } else if (ddat2use) { + d = ddat2; + ddat2use = 0; + wd = 2; + } else if (ddat1use) { + d = ddat1; + ddat1use = 0; + wd = 1; + } + if (wd) { + chipmem_agnus_wput (bltdpt, d); + bltdpt += blit_add; + blitter_hcounter2++; + if (blitter_hcounter2 == blt_info.hblitsize) { + blitter_hcounter2 = 0; + bltdpt += blit_modaddd; + blitter_vcounter2++; + if (blitter_vcounter2 > blitter_vcounter1) + blitter_vcounter1 = blitter_vcounter2; + } + if (blit_ch == 1) + blitter_hcounter1 = blitter_hcounter2; + } + return wd; +} + +STATIC_INLINE void blitter_dodma (int ch) +{ + + switch (ch) + { + case 1: + blt_info.bltadat = chipmem_agnus_wget (bltapt); + bltapt += blit_add; + break; + case 2: + blt_info.bltbdat = chipmem_agnus_wget (bltbpt); + bltbpt += blit_add; + if (blitdesc) + blt_info.bltbhold = (((uae_u32)blt_info.bltbdat << 16) | prevb) >> blt_info.blitdownbshift; + else + blt_info.bltbhold = (((uae_u32)prevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift; + prevb = blt_info.bltbdat; + break; + case 3: + blt_info.bltcdat = chipmem_agnus_wget (bltcpt); + bltcpt += blit_add; + break; + } + + blitter_cyclecounter++; + if (blitter_cyclecounter >= blit_dmacount2) { + blitter_cyclecounter = 0; + ddat2 = ddat1; + ddat2use = ddat1use; + ddat1use = 0; + ddat1 = blitter_doblit (); + if (bltcon0 & 0x100) + ddat1use = 1; + blitter_hcounter1++; + if (blitter_hcounter1 == blt_info.hblitsize) { + blitter_hcounter1 = 0; + if (bltcon0 & 0x800) + bltapt += blit_modadda; + if (bltcon0 & 0x400) + bltbpt += blit_modaddb; + if (bltcon0 & 0x200) + bltcpt += blit_modaddc; + blitter_vcounter1++; + blitfc = !!(bltcon1 & 0x4); + } + } +} + +static void decide_blitter_line (int hpos) +{ + hpos++; + if (dmaen (DMA_BLITTER)) { + while (blit_last_hpos < hpos) { + int c = channel_state (blit_cyclecounter); + for (;;) { + if (c && !canblit (blit_last_hpos)) + break; + if (c) + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blit_cyclecounter++; + blit_linecyclecounter++; + if (blit_linecyclecounter >= blit_diag[1]) { + blit_linecyclecounter = 0; + blitter_read(); + blitter_line(); + blitter_write(); + blitter_nxline(); + if (bltstate == BLT_done) { + blitter_done (); + return; + } + } + break; + } + blit_last_hpos++; + } + } else { + blit_last_hpos = hpos; + } + if (blit_last_hpos > maxhpos) + blit_last_hpos = 0; +} + +void decide_blitter (int hpos) +{ + if (bltstate == BLT_done) + return; + if (!currprefs.blitter_cycle_exact) + return; + if (blitline) { + decide_blitter_line (hpos); + return; + } + hpos++; + if (dmaen (DMA_BLITTER)) { + while (blit_last_hpos < hpos) { + int c = channel_state (blit_cyclecounter); +#ifdef BLITTER_SLOWDOWNDEBUG + blitter_slowdowndebug--; + if (blitter_slowdowndebug < 0) { + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blitter_slowdowndebug = BLITTER_SLOWDOWNDEBUG; + } +#endif + for (;;) { + if (c && !canblit (blit_last_hpos)) { + blit_misscyclecounter++; + break; + } + if (c == 4) { + if (blitter_doddma ()) { + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blit_cyclecounter++; + } + } else if (c) { + if (blitter_vcounter1 < blt_info.vblitsize) { + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blitter_dodma (c); + } + blit_cyclecounter++; + } else { + blit_cyclecounter++; + /* check if blit with zero channels has ended */ + if (blit_cyclecounter >= blit_maxcyclecounter) { + blitter_done (); + return; + } + } + if (blitter_vcounter1 >= blt_info.vblitsize && blitter_vcounter2 >= blt_info.vblitsize) { + if (!ddat1use && !ddat2use) { + blitter_done (); + return; + } + if (blit_diag != blit_cycle_diagram_finald) { + blit_cyclecounter = 0; + blit_diag = blit_cycle_diagram_finald; + } + } + break; + } + blit_last_hpos++; + } + } else { + blit_last_hpos = hpos; + } + if (blit_last_hpos > maxhpos) + blit_last_hpos = 0; +} +#else +void decide_blitter (int hpos) { } +#endif + +static void blitter_force_finish (void) +{ + uae_u16 odmacon; + if (bltstate == BLT_done) + return; + if (bltstate != BLT_done) { + /* blitter is currently running + * force finish (no blitter state support yet) + */ + odmacon = dmacon; + dmacon |= DMA_MASTER | DMA_BLITTER; + write_log ("forcing blitter finish\n"); + if (currprefs.blitter_cycle_exact) { + int rounds = 10000; + while (bltstate != BLT_done && rounds > 0) { + memset (cycle_line, 0, maxhpos); + decide_blitter (maxhpos); + rounds--; + } + if (rounds == 0) + write_log ("blitter froze!?\n"); + } else { + actually_do_blit (); + } + blitter_done (); + dmacon = odmacon; + } +} + +static void blit_bltset (int con) +{ + int i; + + blitline = bltcon1 & 1; + blitfill = bltcon1 & 0x18; + blitdesc = bltcon1 & 2; + blit_ch = (bltcon0 & 0x0f00) >> 8; + + blit_singlechannel = 0; + if (blit_ch == 0 || blit_ch == 1 || blit_ch == 2 || blit_ch == 4 || blit_ch == 8) + blit_singlechannel = 1; + if (blitline) { + if (blt_info.hblitsize != 2) + write_log ("weird hblitsize in linemode: %d vsize=%d PC%=%x\n", blt_info.hblitsize, blt_info.vblitsize, m68k_getpc()); + blit_diag = blit_cycle_diagram_line; + blit_singlechannel = 1; + } else { + if (con & 2) { + blitfc = !!(bltcon1 & 0x4); + blitife = bltcon1 & 0x8; + if ((bltcon1 & 0x18) == 0x18) { + /* Digital "Trash" demo does this; others too. Apparently, no + * negative effects. */ + static int warn = 1; + if (warn) + write_log ("warning: weird fill mode (further messages suppressed) PC=%x\n", m68k_getpc()); + warn = 0; + blitife = 0; + } + } + if (blitfill && !blitdesc) { + static int warn = 1; + if (warn) + write_log ("warning: blitter fill without desc (further messages suppressed) PC=%x\n", m68k_getpc()); + warn = 0; + } + blit_diag = blitfill ? blit_cycle_diagram_fill[blit_ch] : blit_cycle_diagram[blit_ch]; + } + if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + write_log("warning: BLTCON1 DOFF-bit set\n"); + + ddat1use = ddat2use = 0; + blit_dmacount = blit_dmacount2 = 0; + for (i = 0; i < blit_diag[1]; i++) { + int v = blit_diag[2 + i]; + if (v) + blit_dmacount++; + if (v > 0 && v < 4) + blit_dmacount2++; + } + + blt_info.blitashift = bltcon0 >> 12; + blt_info.blitdownashift = 16 - blt_info.blitashift; + blt_info.blitbshift = bltcon1 >> 12; + blt_info.blitdownbshift = 16 - blt_info.blitbshift; +} + +void blit_modset (void) +{ + int mult; + + blit_add = blitdesc ? -2 : 2; + mult = blitdesc ? -1 : 1; + blit_modadda = mult * blt_info.bltamod; + blit_modaddb = mult * blt_info.bltbmod; + blit_modaddc = mult * blt_info.bltcmod; + blit_modaddd = mult * blt_info.bltdmod; +} + +void reset_blit (int bltcon) +{ + if (bltstate == BLT_done) + return; + if (bltcon) + blit_bltset (bltcon); + blit_modset (); +} + +void do_blitter (int hpos) +{ + int cycles; +#ifdef BLITTER_DEBUG + int oldstate = bltstate; +#endif + blt_info.blitzero = 1; + bltstate = BLT_init; + preva = 0; + prevb = 0; + + blit_firstline_cycles = blit_first_cycle = get_cycles (); + blit_cyclecounter = -1; + blit_misscyclecounter = 0; + blit_last_cycle = 0; + blit_maxcyclecounter = 0; + blit_last_hpos = hpos; + + reset_blit (1|2); + + if (blitline) { + blitsing = bltcon1 & 0x2; + blinea = blt_info.bltadat; + blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16 - blt_info.blitbshift)); + blitsign = bltcon1 & 0x40; + blitonedot = 0; + cycles = blt_info.vblitsize; + } else { + blit_firstline_cycles = blit_first_cycle + blit_diag[1] * blt_info.hblitsize * CYCLE_UNIT; + cycles = blt_info.vblitsize * blt_info.hblitsize; + } + +#ifdef BLITTER_DEBUG + blitter_dontdo = 0; + if (1) { + if (oldstate != BLT_done) + write_log ("blitter was already active!\n"); + write_log("blitstart: v=%03.3d h=%03.3d %dx%d %d (%d) d=%d f=%02.2X n=%d pc=%p l=%d dma=%d\n", + vpos, hpos, blt_info.hblitsize, blt_info.vblitsize, cycles, blit_ch, + blitdesc ? 1 : 0, blitfill, + dmaen(DMA_BLITPRI) ? 1 : 0, m68k_getpc(), blitline, dmaen(DMA_BLITTER)); + blitter_dump (); + } +#endif + blit_slowdown = 0; + + unset_special (SPCFLAG_BLTNASTY); + if (dmaen(DMA_BLITPRI)) + set_special (SPCFLAG_BLTNASTY); + + if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) { + blitter_done (); + return; + } + + if (dmaen(DMA_BLITTER)) + bltstate = BLT_work; + + blit_maxcyclecounter = 0x7fffffff; + if (currprefs.blitter_cycle_exact) { + blitter_dma_cycles_line_count = 0; + blitter_hcounter1 = blitter_hcounter2 = 0; + blitter_vcounter1 = blitter_vcounter2 = 0; + if (blit_dmacount2 == blit_dmacount) + blitter_vcounter2 = blt_info.vblitsize; + blit_linecyclecounter = 0; + blitter_dma_cycles_line = blt_info.hblitsize * blit_dmacount2; + if (blit_ch == 0) + blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize; + return; + } + + if (currprefs.immediate_blits) + cycles = 1; + + eventtab[ev_blitter].active = 1; + eventtab[ev_blitter].oldcycles = get_cycles (); + eventtab[ev_blitter].evtime = cycles * blit_diag[1] * CYCLE_UNIT + get_cycles (); + events_schedule(); +} + + +void maybe_blit (int hpos, int hack) +{ + static int warned; + + if (bltstate == BLT_done) + return; + + if (!warned && dmaen (DMA_BLITTER)) { +#ifndef BLITTER_DEBUG + warned = 1; +#endif + write_log ("warning: Program does not wait for blitter %p vpos=%d tc=%d\n", + m68k_getpc(), vpos, blit_cyclecounter); + } + + if (currprefs.blitter_cycle_exact) { + decide_blitter (hpos); + return; + } + + if (!eventtab[ev_blitter].active) + write_log ("FOO!!?\n"); + if (hack == 1 && get_cycles() < blit_firstline_cycles) + return; + + blitter_handler (); +} + +int blitnasty (void) +{ + int cycles, ccnt; + if (bltstate == BLT_done) + return 0; + if (!dmaen(DMA_BLITTER)) + return 0; + if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[1]) + return 0; + cycles = (get_cycles () - blit_first_cycle) / CYCLE_UNIT; + ccnt = 0; + while (blit_last_cycle < cycles) { + int c = channel_state (blit_last_cycle++); + if (!c) + ccnt++; + } + return ccnt; +} + +/* very approximate emulation of blitter slowdown caused by bitplane DMA */ +void blitter_slowdown (int ddfstrt, int ddfstop, int totalcycles, int freecycles) +{ + static int oddfstrt, oddfstop, ototal, ofree; + static int slow; + + if (!totalcycles || ddfstrt < 0 || ddfstop < 0) + return; + if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { + int linecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles; + int freelinecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles; + int dmacycles = (linecycles * blit_dmacount) / blit_diag[1]; + oddfstrt = ddfstrt; + oddfstop = ddfstop; + ototal = totalcycles; + ofree = freecycles; + slow = 0; + if (dmacycles > freelinecycles) + slow = dmacycles - freelinecycles; + } + if (blit_slowdown < 0 || blitline) + return; + blit_slowdown += slow; + blit_misscyclecounter += slow; +} + +uae_u8 *restore_blitter (uae_u8 *src) +{ + uae_u32 flags = restore_u32(); + + bltstate = (flags & 1) ? BLT_init : BLT_done; + if (bltstate == BLT_init) { + write_log ("blitter was started but DMA was inactive during save\n"); + do_blitter (0); + } + return src; +} + +uae_u8 *save_blitter (int *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak,*dst; + + if (bltstate != BLT_done && bltstate != BLT_init) { + write_log ("blitter was running, forcing immediate finish\n"); + /* blitter is active just now but we don't have blitter state support yet */ + blitter_force_finish (); + } + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = malloc (16); + save_u32((bltstate != BLT_done) ? 0 : 1); + *len = dst - dstbak; + return dstbak; + +} diff --git a/blitter3.c b/blitter3.c new file mode 100755 index 00000000..ae7c3b74 --- /dev/null +++ b/blitter3.c @@ -0,0 +1,1093 @@ + /* + * UAE - The Un*x Amiga Emulator + * + * Custom chip emulation + * + * (c) 1995 Bernd Schmidt, Alessandro Bissacco + * (c) 2002 - 2003 Toni Wilen + */ + +//#define BLITTER_DEBUG +//#define BLITTER_SLOWDOWNDEBUG 4 + +#define SPEEDUP + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "config.h" +#include "options.h" +#include "uae.h" +#include "memory.h" +#include "custom.h" +#include "events.h" +#include "newcpu.h" +#include "blitter.h" +#include "blit.h" +#include "savestate.h" + +uae_u16 oldvblts; +uae_u16 bltcon0,bltcon1; +uae_u32 bltapt,bltbpt,bltcpt,bltdpt; + +int blinea_shift; +static uae_u16 blinea, blineb; +static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc; +static int blitonedot,blitsign; +static int blit_add; +static int blit_modadda, blit_modaddb, blit_modaddc, blit_modaddd; +static int blit_ch; +int blit_singlechannel; + +#ifdef BLITTER_DEBUG +static int blitter_dontdo; +static int blitter_delayed_debug; +#endif +#ifdef BLITTER_SLOWDOWNDEBUG +static int blitter_slowdowndebug; +#endif + +struct bltinfo blt_info; + +static uae_u8 blit_filltable[256][4][2]; +uae_u32 blit_masktable[BLITTER_MAX_WORDS]; +static uae_u16 blit_trashtable[BLITTER_MAX_WORDS]; +enum blitter_states bltstate; + +static int blit_cyclecounter, blit_maxcyclecounter, blit_slowdown; +static int blit_linecyclecounter, blit_misscyclecounter; + +#ifdef CPUEMU_6 +extern uae_u8 cycle_line[]; +#endif + +static long blit_firstline_cycles; +static long blit_first_cycle; +static int blit_last_cycle, blit_dmacount, blit_dmacount2; +static int blit_linecycles, blit_extracycles; +static uae_u8 *blit_diag; + +static uae_u16 ddat1, ddat2; +static int ddat1use, ddat2use; + +static uae_u8 blit_cycle_diagram_finald[] = + { 0, 2, 0,4 }; + +static uae_u8 blit_cycle_diagram[][10] = +{ + { 0, 2, 0,0 }, /* 0 */ + { 0, 2, 4,0 }, /* 1 */ + { 0, 2, 3,0 }, /* 2 */ + { 2, 3, 0,3,4, 3,0 }, /* 3 */ + { 0, 3, 2,0,0 }, /* 4 */ + { 2, 3, 0,2,4, 2,0 }, /* 5 */ + { 0, 3, 2,3,0 }, /* 6 */ + { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ + { 0, 2, 1,0 }, /* 8 */ + { 2, 2, 1,4, 1,0 }, /* 9 */ + { 0, 2, 1,3 }, /* A */ + { 3, 3, 1,3,4, 1,3,0 }, /* B */ + { 2, 3, 0,1,2, 1,2 }, /* C */ + { 3, 3, 1,2,4, 1,2,0 }, /* D */ + { 0, 3, 1,2,3 }, /* E */ + { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ +}; + +/* fill mode always adds C-channel to cycle-diagram */ +/* Reflect - Sound Vision freezes without this */ +static uae_u8 blit_cycle_diagram_fill[][10] = +{ + { 0, 2, 0,0 }, /* 0 */ + { 0, 3, 0,3,4 }, /* 1 */ + { 0, 2, 3,0 }, /* 2 */ + { 2, 3, 0,3,4, 3,0 }, /* 3 */ + { 0, 3, 2,0,0 }, /* 4 */ + { 3, 4, 0,2,0,4, 2,0,0 }, /* 5 */ + { 0, 3, 2,3,0 }, /* 6 */ + { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ + { 0, 2, 1,0 }, /* 8 */ + { 3, 3, 1,0,4, 1,0,0}, /* 9 */ + { 0, 2, 1,3 }, /* A */ + { 3, 3, 1,3,4, 1,3,0 }, /* B */ + { 2, 3, 0,1,2, 1,2 }, /* C */ + { 4, 4, 1,2,0,4, 1,2,0,0 }, /* D */ + { 0, 3, 1,2,3 }, /* E */ + { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ +}; + +static uae_u8 blit_cycle_diagram_line[] = +{ + 0, 4, 0,0,0,4 /* total guess.. */ +}; + +void build_blitfilltable(void) +{ + unsigned int d, fillmask; + int i; + + for (i = 0; i < BLITTER_MAX_WORDS; i++) + blit_masktable[i] = 0xFFFF; + + for (d = 0; d < 256; d++) { + for (i = 0; i < 4; i++) { + int fc = i & 1; + uae_u8 data = d; + for (fillmask = 1; fillmask != 0x100; fillmask <<= 1) { + uae_u16 tmp = data; + if (fc) { + if (i & 2) + data |= fillmask; + else + data ^= fillmask; + } + if (tmp & fillmask) fc = !fc; + } + blit_filltable[d][i][0] = data; + blit_filltable[d][i][1] = fc; + } + } +} + +static void blitter_dump (void) +{ + write_log ("APT=%08.8X BPT=%08.8X CPT=%08.8X DPT=%08.8X\n", bltapt, bltbpt, bltcpt, bltdpt); + write_log ("CON0=%04.4X CON1=%04.4X ADAT=%04.4X BDAT=%04.4X CDAT=%04.4X\n", + bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); + write_log ("AFWM=%04.4X ALWM=%04.4X AMOD=%04.4X BMOD=%04.4X CMOD=%04.4X DMOD=%04.4X\n", + blt_info.bltafwm, blt_info.bltalwm, + blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); +} + +STATIC_INLINE uae_u8 *blit_xlateptr(uaecptr bltpt, int bytecount) +{ + if (!chipmem_bank.check(bltpt,bytecount)) return NULL; + return chipmem_bank.xlateaddr(bltpt); +} + +STATIC_INLINE uae_u8 *blit_xlateptr_desc(uaecptr bltpt, int bytecount) +{ + if (!chipmem_bank.check(bltpt-bytecount, bytecount)) return NULL; + return chipmem_bank.xlateaddr(bltpt); +} + +static void blitter_done (void) +{ + ddat1use = ddat2use = 0; + bltstate = BLT_done; + blitter_done_notify (); + INTREQ(0x8040); + eventtab[ev_blitter].active = 0; + unset_special (SPCFLAG_BLTNASTY); +#ifdef BLITTER_DEBUG + write_log ("vpos=%d, cycles %d, missed %d, total %d\n", + vpos, blit_cyclecounter, blit_misscyclecounter, blit_cyclecounter + blit_misscyclecounter); +#endif +} + +static void blitter_dofast(void) +{ + int i,j; + uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; + uae_u8 mt = bltcon0 & 0xFF; + + blit_masktable[0] = blt_info.bltafwm; + blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; + + if (bltcon0 & 0x800) { + bltadatptr = bltapt; + bltapt += (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; + } + if (bltcon0 & 0x400) { + bltbdatptr = bltbpt; + bltbpt += (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; + } + if (bltcon0 & 0x200) { + bltcdatptr = bltcpt; + bltcpt += (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; + } + if (bltcon0 & 0x100) { + bltddatptr = bltdpt; + bltdpt += (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; + } + +#ifdef SPEEDUP + if (blitfunc_dofast[mt] && !blitfill) { + (*blitfunc_dofast[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); + } else +#endif + { + uae_u32 blitbhold = blt_info.bltbhold; + uae_u32 preva = 0, prevb = 0; + uaecptr dstp = 0; + int dodst = 0; + + /*if (!blitfill) write_log ("minterm %x not present\n",mt); */ + for (j = 0; j < blt_info.vblitsize; j++) { + blitfc = !!(bltcon1 & 0x4); + for (i = 0; i < blt_info.hblitsize; i++) { + uae_u32 bltadat, blitahold; + uae_u16 bltbdat; + if (bltadatptr) { + blt_info.bltadat = bltadat = chipmem_agnus_wget (bltadatptr); + bltadatptr += 2; + } else + bltadat = blt_info.bltadat; + bltadat &= blit_masktable[i]; + blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; + preva = bltadat; + + if (bltbdatptr) { + blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); + bltbdatptr += 2; + blitbhold = (((uae_u32)prevb << 16) | bltbdat) >> blt_info.blitbshift; + prevb = bltbdat; + } + + if (bltcdatptr) { + blt_info.bltcdat = chipmem_agnus_wget (bltcdatptr); + bltcdatptr += 2; + } + if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; + if (blitfill) { + uae_u16 d = blt_info.bltddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + if (blt_info.bltddat) + blt_info.blitzero = 0; + if (bltddatptr) { + dodst = 1; + dstp = bltddatptr; + bltddatptr += 2; + } + } + if (bltadatptr) bltadatptr += blt_info.bltamod; + if (bltbdatptr) bltbdatptr += blt_info.bltbmod; + if (bltcdatptr) bltcdatptr += blt_info.bltcmod; + if (bltddatptr) bltddatptr += blt_info.bltdmod; + } + if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltbhold = blitbhold; + } + blit_masktable[0] = 0xFFFF; + blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; + + bltstate = BLT_done; +} + +static void blitter_dofast_desc(void) +{ + int i,j; + uaecptr bltadatptr = 0, bltbdatptr = 0, bltcdatptr = 0, bltddatptr = 0; + uae_u8 mt = bltcon0 & 0xFF; + + blit_masktable[0] = blt_info.bltafwm; + blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm; + + if (bltcon0 & 0x800) { + bltadatptr = bltapt; + bltapt -= (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize; + } + if (bltcon0 & 0x400) { + bltbdatptr = bltbpt; + bltbpt -= (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize; + } + if (bltcon0 & 0x200) { + bltcdatptr = bltcpt; + bltcpt -= (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize; + } + if (bltcon0 & 0x100) { + bltddatptr = bltdpt; + bltdpt -= (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize; + } +#ifdef SPEEDUP + if (blitfunc_dofast_desc[mt] && !blitfill) { + (*blitfunc_dofast_desc[mt])(bltadatptr, bltbdatptr, bltcdatptr, bltddatptr, &blt_info); + } else +#endif + { + uae_u32 blitbhold = blt_info.bltbhold; + uae_u32 preva = 0, prevb = 0; + uaecptr dstp = 0; + int dodst = 0; + + for (j = 0; j < blt_info.vblitsize; j++) { + blitfc = !!(bltcon1 & 0x4); + for (i = 0; i < blt_info.hblitsize; i++) { + uae_u32 bltadat, blitahold; + uae_u16 bltbdat; + if (bltadatptr) { + bltadat = blt_info.bltadat = chipmem_agnus_wget (bltadatptr); + bltadatptr -= 2; + } else + bltadat = blt_info.bltadat; + bltadat &= blit_masktable[i]; + blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; + preva = bltadat; + + if (bltbdatptr) { + blt_info.bltbdat = bltbdat = chipmem_agnus_wget (bltbdatptr); + bltbdatptr -= 2; + blitbhold = (((uae_u32)bltbdat << 16) | prevb) >> blt_info.blitdownbshift; + prevb = bltbdat; + } + + if (bltcdatptr) { + blt_info.bltcdat = blt_info.bltbdat = chipmem_agnus_wget (bltcdatptr); + bltcdatptr -= 2; + } + if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltddat = blit_func (blitahold, blitbhold, blt_info.bltcdat, mt) & 0xFFFF; + if (blitfill) { + uae_u16 d = blt_info.bltddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + blt_info.bltddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + if (blt_info.bltddat) + blt_info.blitzero = 0; + if (bltddatptr) { + dstp = bltddatptr; + dodst = 1; + bltddatptr -= 2; + } + } + if (bltadatptr) bltadatptr -= blt_info.bltamod; + if (bltbdatptr) bltbdatptr -= blt_info.bltbmod; + if (bltcdatptr) bltcdatptr -= blt_info.bltcmod; + if (bltddatptr) bltddatptr -= blt_info.bltdmod; + } + if (dodst) chipmem_agnus_wput (dstp, blt_info.bltddat); + blt_info.bltbhold = blitbhold; + } + blit_masktable[0] = 0xFFFF; + blit_masktable[blt_info.hblitsize - 1] = 0xFFFF; + + bltstate = BLT_done; +} + +STATIC_INLINE void blitter_read(void) +{ + if (bltcon0 & 0x200) { + if (!dmaen(DMA_BLITTER)) + return; + blt_info.bltcdat = chipmem_bank.wget(bltcpt); + } + bltstate = BLT_work; +} + +STATIC_INLINE void blitter_write(void) +{ + if (blt_info.bltddat) + blt_info.blitzero = 0; + /* D-channel state has no effect on linedraw, but C must be enabled or nothing is drawn! */ + if (bltcon0 & 0x200) { + if (!dmaen(DMA_BLITTER)) + return; + chipmem_bank.wput(bltdpt, blt_info.bltddat); + bltdpt = bltcpt; /* believe it or not but try Cardamon or Cardamom without this.. */ + } + bltstate = BLT_next; +} + +STATIC_INLINE void blitter_line_incx(void) +{ + if (++blinea_shift == 16) { + blinea_shift = 0; + bltcpt += 2; + } +} + +STATIC_INLINE void blitter_line_decx(void) +{ + if (blinea_shift-- == 0) { + blinea_shift = 15; + bltcpt -= 2; + } +} + +STATIC_INLINE void blitter_line_decy(void) +{ + bltcpt -= blt_info.bltcmod; + blitonedot = 0; +} + +STATIC_INLINE void blitter_line_incy(void) +{ + bltcpt += blt_info.bltcmod; + blitonedot = 0; +} + +static void blitter_line(void) +{ + uae_u16 blitahold = blinea >> blinea_shift; + uae_u16 blitbhold = blineb & 1 ? 0xFFFF : 0; + uae_u16 blitchold = blt_info.bltcdat; + + if (blitsing && blitonedot) + blitahold = 0; + blitonedot = 1; + blt_info.bltddat = blit_func(blitahold, blitbhold, blitchold, bltcon0 & 0xFF); + if (!blitsign){ + if (bltcon0 & 0x800) + bltapt += (uae_s16)blt_info.bltamod; + if (bltcon1 & 0x10){ + if (bltcon1 & 0x8) + blitter_line_decy(); + else + blitter_line_incy(); + } else { + if (bltcon1 & 0x8) + blitter_line_decx(); + else + blitter_line_incx(); + } + } else { + if (bltcon0 & 0x800) + bltapt += (uae_s16)blt_info.bltbmod; + } + if (bltcon1 & 0x10){ + if (bltcon1 & 0x4) + blitter_line_decx(); + else + blitter_line_incx(); + } else { + if (bltcon1 & 0x4) + blitter_line_decy(); + else + blitter_line_incy(); + } + blitsign = 0 > (uae_s16)bltapt; + bltstate = BLT_write; +} + +STATIC_INLINE void blitter_nxline(void) +{ + blineb = (blineb << 1) | (blineb >> 15); + if (blt_info.vblitsize > 0) + blt_info.vblitsize--; + bltstate = BLT_read; +} + +static void actually_do_blit(void) +{ + if (blitline) { + do { + blitter_read(); + blitter_line(); + blitter_write(); + blitter_nxline(); + if (blt_info.vblitsize == 0) + bltstate = BLT_done; + } while (bltstate != BLT_done); + } else { + if (blitdesc) + blitter_dofast_desc(); + else + blitter_dofast(); + bltstate = BLT_done; + } +} + +void blitter_handler(void) +{ + if (!dmaen(DMA_BLITTER)) { + eventtab[ev_blitter].active = 1; + eventtab[ev_blitter].oldcycles = get_cycles (); + eventtab[ev_blitter].evtime = 10 * CYCLE_UNIT + get_cycles (); /* wait a little */ + return; /* gotta come back later. */ + } + if (blit_slowdown > 0) { + eventtab[ev_blitter].active = 1; + eventtab[ev_blitter].oldcycles = get_cycles (); + eventtab[ev_blitter].evtime = blit_slowdown * CYCLE_UNIT + get_cycles (); + blit_slowdown = -1; + return; + } +#ifdef BLITTER_DEBUG + if (!blitter_dontdo) + actually_do_blit(); + else + bltstate = BLT_done; +#else + actually_do_blit (); +#endif + blitter_done (); +} + +STATIC_INLINE int channel_state (int cycles) +{ + if (cycles < 0) + return 0; + if (cycles < blit_diag[0]) + return blit_diag[blit_diag[1] + 2 + cycles]; + return blit_diag[((cycles - blit_diag[0]) % blit_diag[1]) + 2]; +} + +int is_bitplane_dma (int hpos); +STATIC_INLINE int canblit (int hpos) +{ + if ((cycle_line[hpos] == 0 || cycle_line[hpos] == CYCLE_NOCPU) && !is_bitplane_dma (hpos)) + return 1; + return 0; +} + +#ifdef CPUEMU_6 + +static int blit_last_hpos; + +static int blitter_dma_cycles_line, blitter_dma_cycles_line_count; +static int blitter_cyclecounter; +static int blitter_hcounter1, blitter_hcounter2; +static int blitter_vcounter1, blitter_vcounter2; + + +static uae_u32 preva, prevb; +STATIC_INLINE uae_u16 blitter_doblit (void) +{ + uae_u32 blitahold; + uae_u16 bltadat, ddat; + uae_u8 mt = bltcon0 & 0xFF; + + bltadat = blt_info.bltadat; + if (blitter_hcounter1 == 0) + bltadat &= blt_info.bltafwm; + if (blitter_hcounter1 == blt_info.hblitsize - 1) + bltadat &= blt_info.bltalwm; + if (blitdesc) + blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift; + else + blitahold = (((uae_u32)preva << 16) | bltadat) >> blt_info.blitashift; + preva = bltadat; + + ddat = blit_func (blitahold, blt_info.bltbhold, blt_info.bltcdat, mt) & 0xFFFF; + + if (bltcon1 & 0x18) { + uae_u16 d = ddat; + int ifemode = blitife ? 2 : 0; + int fc1 = blit_filltable[d & 255][ifemode + blitfc][1]; + ddat = (blit_filltable[d & 255][ifemode + blitfc][0] + + (blit_filltable[d >> 8][ifemode + fc1][0] << 8)); + blitfc = blit_filltable[d >> 8][ifemode + fc1][1]; + } + + if (ddat) + blt_info.blitzero = 0; + + return ddat; +} + + +STATIC_INLINE int blitter_doddma (void) +{ + int wd; + uae_u16 d; + + wd = 0; + if (blit_dmacount2 == 0) { + d = blitter_doblit (); + wd = -1; + } else if (ddat2use) { + d = ddat2; + ddat2use = 0; + wd = 2; + } else if (ddat1use) { + d = ddat1; + ddat1use = 0; + wd = 1; + } + if (wd) { + chipmem_agnus_wput (bltdpt, d); + bltdpt += blit_add; + blitter_hcounter2++; + if (blitter_hcounter2 == blt_info.hblitsize) { + blitter_hcounter2 = 0; + bltdpt += blit_modaddd; + blitter_vcounter2++; + if (blitter_vcounter2 > blitter_vcounter1) + blitter_vcounter1 = blitter_vcounter2; + } + if (blit_ch == 1) + blitter_hcounter1 = blitter_hcounter2; + } + return wd; +} + +STATIC_INLINE void blitter_dodma (int ch) +{ + + switch (ch) + { + case 1: + blt_info.bltadat = chipmem_agnus_wget (bltapt); + bltapt += blit_add; + break; + case 2: + blt_info.bltbdat = chipmem_agnus_wget (bltbpt); + bltbpt += blit_add; + if (blitdesc) + blt_info.bltbhold = (((uae_u32)blt_info.bltbdat << 16) | prevb) >> blt_info.blitdownbshift; + else + blt_info.bltbhold = (((uae_u32)prevb << 16) | blt_info.bltbdat) >> blt_info.blitbshift; + prevb = blt_info.bltbdat; + break; + case 3: + blt_info.bltcdat = chipmem_agnus_wget (bltcpt); + bltcpt += blit_add; + break; + } + + blitter_cyclecounter++; + if (blitter_cyclecounter >= blit_dmacount2) { + blitter_cyclecounter = 0; + ddat2 = ddat1; + ddat2use = ddat1use; + ddat1use = 0; + ddat1 = blitter_doblit (); + if (bltcon0 & 0x100) + ddat1use = 1; + blitter_hcounter1++; + if (blitter_hcounter1 == blt_info.hblitsize) { + blitter_hcounter1 = 0; + if (bltcon0 & 0x800) + bltapt += blit_modadda; + if (bltcon0 & 0x400) + bltbpt += blit_modaddb; + if (bltcon0 & 0x200) + bltcpt += blit_modaddc; + blitter_vcounter1++; + blitfc = !!(bltcon1 & 0x4); + } + } +} + +static void decide_blitter_line (int hpos) +{ + hpos++; + if (dmaen (DMA_BLITTER)) { + while (blit_last_hpos < hpos) { + int c = channel_state (blit_cyclecounter); + for (;;) { + if (blit_cyclecounter < 0) { + blit_cyclecounter++; + break; + } + if (c && !canblit (blit_last_hpos)) + break; + if (c) + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blit_cyclecounter++; + blit_linecyclecounter++; + if (blit_linecyclecounter >= blit_diag[1]) { + blit_linecyclecounter = 0; + ddat1use = ddat2use; + ddat1 = ddat2; + ddat2use = 0; + if (blt_info.vblitsize > 0) { + blitter_read(); + blitter_line(); + ddat2use = 1; + ddat2 = blt_info.bltddat; + } + if (ddat1use) { + blt_info.bltddat = ddat1; + ddat1use = 0; + blitter_write(); + } + blitter_nxline(); + if (!ddat1use && !ddat2use && blt_info.vblitsize == 0) { + bltstate = BLT_done; + blitter_done (); + return; + } + } + break; + } + blit_last_hpos++; + } + } else { + blit_last_hpos = hpos; + } + if (blit_last_hpos > maxhpos) + blit_last_hpos = 0; +} + +void decide_blitter (int hpos) +{ + if (bltstate == BLT_done) + return; +#ifdef BLITTER_DEBUG + if (blitter_delayed_debug) { + blitter_delayed_debug = 0; + blitter_dump(); + } +#endif + if (!currprefs.blitter_cycle_exact) + return; + if (blitline) { + decide_blitter_line (hpos); + return; + } + hpos++; + if (dmaen (DMA_BLITTER)) { + while (blit_last_hpos < hpos) { + int c = channel_state (blit_cyclecounter); +#ifdef BLITTER_SLOWDOWNDEBUG + blitter_slowdowndebug--; + if (blitter_slowdowndebug < 0) { + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blitter_slowdowndebug = BLITTER_SLOWDOWNDEBUG; + } +#endif + for (;;) { + if (c && !canblit (blit_last_hpos)) { + blit_misscyclecounter++; + break; + } + if (c == 4) { + if (blitter_doddma ()) { + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blit_cyclecounter++; + } + } else if (c) { + if (blitter_vcounter1 < blt_info.vblitsize) { + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blitter_dodma (c); + } + blit_cyclecounter++; + } else { + blit_cyclecounter++; + /* check if blit with zero channels has ended */ + if (blit_cyclecounter >= blit_maxcyclecounter) { + blitter_done (); + return; + } + } + if (blitter_vcounter1 >= blt_info.vblitsize && blitter_vcounter2 >= blt_info.vblitsize) { + if (!ddat1use && !ddat2use) { + blitter_done (); + return; + } + if (blit_diag != blit_cycle_diagram_finald) { + blit_cyclecounter = 0; + blit_diag = blit_cycle_diagram_finald; + } + } + break; + } + blit_last_hpos++; + } + } else { + blit_last_hpos = hpos; + } + if (blit_last_hpos > maxhpos) + blit_last_hpos = 0; +} +#else +void decide_blitter (int hpos) { } +#endif + +static void blitter_force_finish (void) +{ + uae_u16 odmacon; + if (bltstate == BLT_done) + return; + if (bltstate != BLT_done) { + /* blitter is currently running + * force finish (no blitter state support yet) + */ + odmacon = dmacon; + dmacon |= DMA_MASTER | DMA_BLITTER; + write_log ("forcing blitter finish\n"); + if (currprefs.blitter_cycle_exact) { + int rounds = 10000; + while (bltstate != BLT_done && rounds > 0) { + memset (cycle_line, 0, maxhpos); + decide_blitter (maxhpos); + rounds--; + } + if (rounds == 0) + write_log ("blitter froze!?\n"); + } else { + actually_do_blit (); + } + blitter_done (); + dmacon = odmacon; + } +} + +static void blit_bltset (int con) +{ + int i; + + blitline = bltcon1 & 1; + blitfill = bltcon1 & 0x18; + blitdesc = bltcon1 & 2; + blit_ch = (bltcon0 & 0x0f00) >> 8; + + blit_singlechannel = 0; + if (blit_ch == 0 || blit_ch == 1 || blit_ch == 2 || blit_ch == 4 || blit_ch == 8) + blit_singlechannel = 1; + if (blitline) { + if (blt_info.hblitsize != 2) + write_log ("weird hblitsize in linemode: %d vsize=%d PC%=%x\n", blt_info.hblitsize, blt_info.vblitsize, m68k_getpc()); + blit_diag = blit_cycle_diagram_line; + blit_singlechannel = 1; + } else { + if (con & 2) { + blitfc = !!(bltcon1 & 0x4); + blitife = bltcon1 & 0x8; + if ((bltcon1 & 0x18) == 0x18) { + /* Digital "Trash" demo does this; others too. Apparently, no + * negative effects. */ + static int warn = 1; + if (warn) + write_log ("warning: weird fill mode (further messages suppressed) PC=%x\n", m68k_getpc()); + warn = 0; + blitife = 0; + } + } + if (blitfill && !blitdesc) { + static int warn = 1; + if (warn) + write_log ("warning: blitter fill without desc (further messages suppressed) PC=%x\n", m68k_getpc()); + warn = 0; + } + blit_diag = blitfill ? blit_cycle_diagram_fill[blit_ch] : blit_cycle_diagram[blit_ch]; + } + if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + write_log("warning: BLTCON1 DOFF-bit set\n"); + + ddat1use = ddat2use = 0; + blit_dmacount = blit_dmacount2 = 0; + for (i = 0; i < blit_diag[1]; i++) { + int v = blit_diag[2 + i]; + if (v) + blit_dmacount++; + if (v > 0 && v < 4) + blit_dmacount2++; + } + + blt_info.blitashift = bltcon0 >> 12; + blt_info.blitdownashift = 16 - blt_info.blitashift; + blt_info.blitbshift = bltcon1 >> 12; + blt_info.blitdownbshift = 16 - blt_info.blitbshift; +} + +void blit_modset (void) +{ + int mult; + + blit_add = blitdesc ? -2 : 2; + mult = blitdesc ? -1 : 1; + blit_modadda = mult * blt_info.bltamod; + blit_modaddb = mult * blt_info.bltbmod; + blit_modaddc = mult * blt_info.bltcmod; + blit_modaddd = mult * blt_info.bltdmod; +} + +void reset_blit (int bltcon) +{ + if (bltstate == BLT_done) + return; + if (bltcon) + blit_bltset (bltcon); + blit_modset (); +} + +void do_blitter (int hpos) +{ + int cycles; +#ifdef BLITTER_DEBUG + int oldstate = bltstate; +#endif + blt_info.blitzero = 1; + bltstate = BLT_init; + preva = 0; + prevb = 0; + + blit_firstline_cycles = blit_first_cycle = get_cycles (); + blit_misscyclecounter = 0; + blit_last_cycle = 0; + blit_maxcyclecounter = 0; + blit_last_hpos = hpos; + + reset_blit (1|2); + + if (blitline) { + blit_cyclecounter = -1; + blitsing = bltcon1 & 0x2; + blinea = blt_info.bltadat; + blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16 - blt_info.blitbshift)); + blitsign = bltcon1 & 0x40; + blitonedot = 0; + cycles = blt_info.vblitsize; + } else { + blit_cyclecounter = -1; + blit_firstline_cycles = blit_first_cycle + blit_diag[1] * blt_info.hblitsize * CYCLE_UNIT; + cycles = blt_info.vblitsize * blt_info.hblitsize; + } + +#ifdef BLITTER_DEBUG + blitter_dontdo = 0; + if (1) { + if (oldstate != BLT_done) + write_log ("blitter was already active!\n"); + write_log("blitstart: v=%03.3d h=%03.3d %dx%d %d (%d) d=%d f=%02.2X n=%d pc=%p l=%d dma=%d\n", + vpos, hpos, blt_info.hblitsize, blt_info.vblitsize, cycles, blit_ch, + blitdesc ? 1 : 0, blitfill, + dmaen(DMA_BLITPRI) ? 1 : 0, m68k_getpc(), blitline, dmaen(DMA_BLITTER)); + blitter_dump (); + } +#endif + blit_slowdown = 0; + + unset_special (SPCFLAG_BLTNASTY); + if (dmaen(DMA_BLITPRI)) + set_special (SPCFLAG_BLTNASTY); + + if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) { + blitter_done (); + return; + } + + if (dmaen(DMA_BLITTER)) + bltstate = BLT_work; + + blit_maxcyclecounter = 0x7fffffff; + if (currprefs.blitter_cycle_exact) { + blitter_dma_cycles_line_count = 0; + blitter_hcounter1 = blitter_hcounter2 = 0; + blitter_vcounter1 = blitter_vcounter2 = 0; + if (blit_dmacount2 == blit_dmacount) + blitter_vcounter2 = blt_info.vblitsize; + blit_linecyclecounter = 0; + blitter_dma_cycles_line = blt_info.hblitsize * blit_dmacount2; + if (blit_ch == 0) + blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize; + return; + } + + if (currprefs.immediate_blits) + cycles = 1; + + eventtab[ev_blitter].active = 1; + eventtab[ev_blitter].oldcycles = get_cycles (); + eventtab[ev_blitter].evtime = cycles * blit_diag[1] * CYCLE_UNIT + get_cycles (); + events_schedule(); +} + + +void maybe_blit (int hpos, int hack) +{ + static int warned; + + if (bltstate == BLT_done) + return; + + if (!warned && dmaen (DMA_BLITTER)) { +#ifndef BLITTER_DEBUG + warned = 1; +#endif + write_log ("warning: Program does not wait for blitter %p vpos=%d tc=%d\n", + m68k_getpc(), vpos, blit_cyclecounter); + } + + if (currprefs.blitter_cycle_exact) { + decide_blitter (hpos); + goto end; + } + + if (!eventtab[ev_blitter].active) + write_log ("FOO!!?\n"); + if (hack == 1 && get_cycles() < blit_firstline_cycles) + goto end; + + blitter_handler (); +end:; +#ifdef BLITTER_DEBUG + blitter_delayed_debug = 1; +#endif +} + +int blitnasty (void) +{ + int cycles, ccnt; + if (bltstate == BLT_done) + return 0; + if (!dmaen(DMA_BLITTER)) + return 0; + if (blit_last_cycle >= blit_diag[0] && blit_dmacount == blit_diag[1]) + return 0; + cycles = (get_cycles () - blit_first_cycle) / CYCLE_UNIT; + ccnt = 0; + while (blit_last_cycle < cycles) { + int c = channel_state (blit_last_cycle++); + if (!c) + ccnt++; + } + return ccnt; +} + +/* very approximate emulation of blitter slowdown caused by bitplane DMA */ +void blitter_slowdown (int ddfstrt, int ddfstop, int totalcycles, int freecycles) +{ + static int oddfstrt, oddfstop, ototal, ofree; + static int slow; + + if (!totalcycles || ddfstrt < 0 || ddfstop < 0) + return; + if (ddfstrt != oddfstrt || ddfstop != oddfstop || totalcycles != ototal || ofree != freecycles) { + int linecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * totalcycles; + int freelinecycles = ((ddfstop - ddfstrt + totalcycles - 1) / totalcycles) * freecycles; + int dmacycles = (linecycles * blit_dmacount) / blit_diag[1]; + oddfstrt = ddfstrt; + oddfstop = ddfstop; + ototal = totalcycles; + ofree = freecycles; + slow = 0; + if (dmacycles > freelinecycles) + slow = dmacycles - freelinecycles; + } + if (blit_slowdown < 0 || blitline) + return; + blit_slowdown += slow; + blit_misscyclecounter += slow; +} + +uae_u8 *restore_blitter (uae_u8 *src) +{ + uae_u32 flags = restore_u32(); + + bltstate = (flags & 1) ? BLT_init : BLT_done; + if (bltstate == BLT_init) { + write_log ("blitter was started but DMA was inactive during save\n"); + do_blitter (0); + } + return src; +} + +uae_u8 *save_blitter (int *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak,*dst; + + if (bltstate != BLT_done && bltstate != BLT_init) { + write_log ("blitter was running, forcing immediate finish\n"); + /* blitter is active just now but we don't have blitter state support yet */ + blitter_force_finish (); + } + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = malloc (16); + save_u32((bltstate != BLT_done) ? 0 : 1); + *len = dst - dstbak; + return dstbak; + +} diff --git a/bsdsocket.c b/bsdsocket.c index 0fac4b1f..109e7e03 100755 --- a/bsdsocket.c +++ b/bsdsocket.c @@ -32,7 +32,7 @@ static uae_u32 SockLibBase; /* ObtainSocket()/ReleaseSocket() public socket pool */ long sockpoolids[SOCKPOOLSIZE]; -int sockpoolsocks[SOCKPOOLSIZE]; +SOCKET_TYPE sockpoolsocks[SOCKPOOLSIZE]; uae_u32 sockpoolflags[SOCKPOOLSIZE]; long curruniqid = 65536; @@ -187,16 +187,17 @@ BOOL checksd(SB, int sd) TRACE(("checksd FALSE s 0x%x sd %d\n",s,sd)); return FALSE; } -void setsd(SB, int sd, int s) - { + +void setsd(SB, int sd, SOCKET_TYPE s) +{ sb->dtable[sd - 1] = s; - } +} /* Socket descriptor/opaque socket handle management */ -int getsd (SB, int s) +int getsd (SB, SOCKET_TYPE s) { int i; - int *dt = sb->dtable; + SOCKET_TYPE *dt = sb->dtable; /* return socket descriptor if already exists */ for (i = sb->dtablesize; i--;) @@ -216,7 +217,7 @@ int getsd (SB, int s) return -1; } -int getsock (SB, int sd) +SOCKET_TYPE getsock (SB, int sd) { if ((unsigned int) (sd - 1) >= (unsigned int) sb->dtablesize) { TRACE (("Invalid Socket Descriptor (%d)\n", sd)); @@ -666,7 +667,7 @@ static uae_u32 bsdsocklib_ObtainSocket (void) SB = SOCKETBASE; int sd; long id; - int s; + SOCKET_TYPE s; int i; id = m68k_dreg (regs, 0); @@ -698,7 +699,7 @@ static uae_u32 bsdsocklib_ReleaseSocket (void) SB = SOCKETBASE; int sd; long id; - int s; + SOCKET_TYPE s; int i; uae_u32 flags; @@ -1251,12 +1252,12 @@ static uae_u32 bsdsocklib_init (void) /* Install error strings in Amiga memory */ tmp1 = 0; for (i = number_sys_error; i--;) - tmp1 += strlen (errortexts[i])+1; + tmp1 += strlen (errortexts[i])+1; - for (i = number_host_error; i--;) - tmp1 += strlen (herrortexts[i])+1; + for (i = number_host_error; i--;) + tmp1 += strlen (herrortexts[i])+1; - tmp1 += strlen(strErr)+1; + tmp1 += strlen(strErr)+1; m68k_dreg (regs, 0) = tmp1; m68k_dreg (regs, 1) = 0; @@ -1267,12 +1268,12 @@ static uae_u32 bsdsocklib_init (void) return 0; } for (i = 0; i < (int) (number_sys_error); i++) - errnotextptrs[i] = addstr (&tmp1, errortexts[i]); + errnotextptrs[i] = addstr (&tmp1, errortexts[i]); - for (i = 0; i < (int) (number_host_error); i++) - herrnotextptrs[i] = addstr (&tmp1, herrortexts[i]); + for (i = 0; i < (int) (number_host_error); i++) + herrnotextptrs[i] = addstr (&tmp1, herrortexts[i]); - strErrptr = addstr (&tmp1, strErr); + strErrptr = addstr (&tmp1, strErr); /* @@@ someone please implement a proper interrupt handler setup here :) */ tmp1 = here (); diff --git a/catweasel.c b/catweasel.c index 221f5599..1c03e94d 100755 --- a/catweasel.c +++ b/catweasel.c @@ -15,15 +15,161 @@ struct catweasel_contr cwc; -static int cwhsync; +static int cwhsync, cwmk3buttonsync; +static int cwmk3port, cwmk3port1, cwmk3port2; static int handshake; +static int mouse_x[2], mouse_y[2], mouse_px[2], mouse_py[2]; static HANDLE handle = INVALID_HANDLE_VALUE; +int catweasel_isjoystick(void) +{ + uae_u8 b = cwc.can_joy; + if (b) { + if (cwc.type == CATWEASEL_TYPE_MK3 && cwc.sid[0]) + b |= 0x80; + if (cwc.type >= CATWEASEL_TYPE_MK4) + b |= 0x80; + } + return b; +} +int catweasel_ismouse(void) +{ + return cwc.can_mouse; +} + +static void sid_write(uae_u8 reg, uae_u8 val, int sidnum) +{ + if (sidnum >= cwc.can_sid) + return; + catweasel_do_bput(0xd8, val); + catweasel_do_bput(0xdc, reg | (sidnum << 7)); + catweasel_do_bget(0xd8); // dummy read + catweasel_do_bget(0xd8); // dummy read +} + +static uae_u8 sid_read(uae_u8 reg, int sidnum) +{ + if (sidnum >= cwc.can_sid) + return 0; + catweasel_do_bput(0xdc, 0x20 | reg | (sidnum << 7)); + catweasel_do_bget(0xd8); // dummy read + catweasel_do_bget(0xd8); // dummy read + return catweasel_do_bget(0xd8); +} + +static uae_u8 get_buttons(void) +{ + uae_u8 b, b2; + + b = 0; + if (cwc.type < CATWEASEL_TYPE_MK3) + return b; + b2 = catweasel_do_bget(0xc8) & (0x80 | 0x40); + if (!(b2 & 0x80)) + b |= 0x80; + if (!(b2 & 0x40)) + b |= 0x08; + if (cwc.type >= CATWEASEL_TYPE_MK4) { + b &= ~0x80; + catweasel_do_bput(3, 0x81); + if (!(catweasel_do_bget(0x07) & 0x10)) + b |= 0x80; + b2 = catweasel_do_bget(0xd0) ^ 15; + catweasel_do_bput(3, 0x41); + if (cwc.sid[0]) { + b2 &= ~(1 | 2); + if (sid_read(0x19, 0) > 0x7f) + b2 |= 2; + if (sid_read(0x1a, 0) > 0x7f) + b2 |= 1; + } + if (cwc.sid[1]) { + b2 &= ~(4 | 8); + if (sid_read(0x19, 1) > 0x7f) + b2 |= 8; + if (sid_read(0x1a, 1) > 0x7f) + b2 |= 4; + } + } else { + b2 = cwmk3port1 | (cwmk3port2 << 2); + } + b |= (b2 & (8 | 4)) << 3; + b |= (b2 & (1 | 2)) << 1; + return b; +} + +int catweasel_read_mouse(int port, int *dx, int *dy, int *buttons) +{ + if (!cwc.can_mouse) + return 0; + *dx = mouse_x[port]; + mouse_x[port] = 0; + *dy = mouse_y[port]; + mouse_y[port] = 0; + *buttons = (get_buttons() >> (port * 4)) & 15; + return 1; +} + +static void sid_reset(void) +{ + int i; + for (i = 0; i < 0x19; i++) { + sid_write(i, 0, 0); + sid_write(i, 0, 1); + } +} + +static void catweasel_detect_sid(void) +{ + int i, j; + uae_u8 b1, b2; + + cwc.sid[0] = cwc.sid[1] = 0; + if (!cwc.can_sid) + return; + sid_reset(); + if (cwc.type >= CATWEASEL_TYPE_MK4) { + catweasel_do_bput(3, 0x81); + b1 = catweasel_do_bget(0xd0); + for (i = 0; i < 100; i++) { + sid_read(0x19, 0); // delay + b2 = catweasel_do_bget(0xd0); + if ((b1 & 3) != (b2 & 3)) + cwc.sid[0] = 6581; + if ((b1 & 12) != (b2 & 12)) + cwc.sid[1] = 6581; + } + } + catweasel_do_bput(3, 0x41); + for (i = 0; i < 2 ;i++) { + sid_reset(); + sid_write(0x0f, 0xff, i); + sid_write(0x12, 0x10, i); + for(j = 0; j != 1000; j++) { + sid_write(0, 0, i); + if((sid_read(0x1b, i) & 0x80) != 0) { + cwc.sid[i] = 6581; + break; + } + } + sid_reset(); + sid_write(0x0f, 0xff, i); + sid_write(0x12, 0x30, i); + for(j = 0; j != 1000; j++) { + sid_write(0, 0, i); + if((sid_read(0x1b, i) & 0x80) != 0) { + cwc.sid[i] = 8580; + break; + } + } + } + sid_reset(); +} + void catweasel_hsync (void) { int i; - uae_u8 x, y; if (cwc.type < CATWEASEL_TYPE_MK3) return; @@ -33,37 +179,70 @@ void catweasel_hsync (void) cwhsync = 10; if (handshake) { /* keyboard handshake */ - catweasel_do_bput (0xd0, 0); + catweasel_do_bput(0xd0, 0); handshake = 0; } - if (cwc.type < CATWEASEL_TYPE_MK4) + if (cwc.type == CATWEASEL_TYPE_MK3 && cwc.sid[0]) { + uae_u8 b; + cwmk3buttonsync--; + if (cwmk3buttonsync <= 0) { + cwmk3buttonsync = 30; + b = 0; + if (sid_read(0x19, 0) > 0x7f) + b |= 2; + if (sid_read(0x1a, 0) > 0x7f) + b |= 1; + if (cwmk3port == 0) { + cwmk3port1 = b; + catweasel_do_bput(0xd4, 0); // select port2 + cwmk3port = 1; + } else { + cwmk3port2 = b; + catweasel_do_bget(0xd4); // select port1 + cwmk3port = 0; + } + } + } + if (!cwc.can_mouse) return; /* read MK4 mouse counters */ - catweasel_do_bput (3, 0x81); + catweasel_do_bput(3, 0x81); for (i = 0; i < 2; i++) { - x = catweasel_do_bget (0xc4 + i * 8); - y = catweasel_do_bget (0xc0 + i * 8); + int x, y, dx, dy; + x = (uae_s8)catweasel_do_bget(0xc4 + i * 8); + y = (uae_s8)catweasel_do_bget(0xc0 + i * 8); + dx = mouse_px[i] - x; + if (dx > 127) + dx = 255 - dx; + if (dx < -128) + dx = 255 + dx; + dy = mouse_py[i] - y; + if (dy > 127) + dy = 255 - dy; + if (dy < -128) + dy = 255 + dy; + mouse_x[i] -= dx; + mouse_y[i] -= dy; + mouse_px[i] = x; + mouse_py[i] = y; } - catweasel_do_bput (3, 0x41); + catweasel_do_bput(3, 0x41); } int catweasel_read_joystick (uae_u8 *dir, uae_u8 *buttons) { - if (cwc.type < CATWEASEL_TYPE_MK3) + if (!cwc.can_joy) return 0; - *dir = catweasel_do_bget (0xc0); - *buttons = catweasel_do_bget (0xc8); - if (cwc.type == CATWEASEL_TYPE_MK4) { - *buttons &= ~0x80; - *buttons |= (catweasel_do_bget (0x07) << 3) & 0x80; - } + *dir = catweasel_do_bget(0xc0); + *buttons = get_buttons(); return 1; } int catweasel_read_keyboard (uae_u8 *keycode) { uae_u8 v; - if (cwc.type < CATWEASEL_TYPE_MK3) + + if (!cwc.can_kb) return 0; v = catweasel_do_bget (0xd4); if (!(v & 0x80)) @@ -108,9 +287,9 @@ void catweasel_do_bput (uaecptr addr, uae_u32 b) //write_log ("P %02.2X %02.2X %d\n", (uae_u8)addr, (uae_u8)b, did_read); } -int catweasel_init (void) +int catweasel_init(void) { - char name[32]; + char name[32], tmp[1000]; int i, len; uae_u8 buffer[10000]; uae_u32 model, base; @@ -118,9 +297,6 @@ int catweasel_init (void) if (cwc.type) return 1; - if (!currprefs.catweasel) - return 0; - if (currprefs.catweasel >= 100) { cwc.type = currprefs.catweasel >= 0x400 ? 3 : 1; cwc.iobase = currprefs.catweasel; @@ -138,35 +314,66 @@ int catweasel_init (void) break; } if (handle == INVALID_HANDLE_VALUE) { - write_log ("No Catweasel detected\n"); + write_log ("CW: No Catweasel detected\n"); goto fail; } if (!DeviceIoControl (handle, CW_GET_VERSION, 0, 0, buffer, sizeof (buffer), &len, 0)) { - write_log ("CW_GET_VERSION failed %d\n", GetLastError()); + write_log ("CW: CW_GET_VERSION failed %d\n", GetLastError()); goto fail; } write_log ("CW driver version string '%s'\n", buffer); if (!DeviceIoControl (handle, CW_GET_HWVERSION, 0, 0, buffer, sizeof (buffer), &len, 0)) { - write_log ("CW_GET_HWVERSION failed %d\n", GetLastError()); + write_log ("CW: CW_GET_HWVERSION failed %d\n", GetLastError()); goto fail; } write_log ("CW: v=%d 14=%d 28=%d 56=%d joy=%d dpm=%d sid=%d kb=%d sidfifo=%d\n", - buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], - buffer[6], buffer[7], ((uae_u32*)(buffer + 8))[0]); + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], + buffer[6], buffer[7], ((uae_u32*)(buffer + 8))[0]); + cwc.can_joy = (buffer[4] & 1) ? 2 : 0; + cwc.can_sid = buffer[6] ? 1 : 0; + cwc.can_kb = buffer[7] & 1; + cwc.can_mouse = (buffer[4] & 2) ? 2 : 0; if (!DeviceIoControl (handle, CW_LOCK_EXCLUSIVE, 0, 0, buffer, sizeof (buffer), &len, 0)) { - write_log ("CW_LOCK_EXCLUSIVE failed %d\n", GetLastError()); + write_log ("CW: CW_LOCK_EXCLUSIVE failed %d\n", GetLastError()); goto fail; } model = *((uae_u32*)(buffer + 4)); base = *((uae_u32*)(buffer + 0)); cwc.type = model == 0 ? 1 : model == 2 ? 4 : 3; cwc.iobase = base; + if (cwc.type == CATWEASEL_TYPE_MK4 && cwc.can_sid) + cwc.can_sid = 2; } - write_log ("Catweasel MK%d @%p (%s) detected and enabled\n", - cwc.type, cwc.iobase, name); - if (cwc.type == CATWEASEL_TYPE_MK4) - catweasel_do_bput (3, 0x41); /* enable MK3-mode */ - catweasel_init_controller (&cwc); + if (cwc.type == CATWEASEL_TYPE_MK4) { + if (cwc.can_mouse) { + int i; + catweasel_do_bput(3, 0x81); + catweasel_do_bput(0xd0, 0); // amiga mouse + // clear mouse counters + for (i = 0; i < 2; i++) { + catweasel_do_bput(0xc4 + i * 8, 0); + catweasel_do_bput(0xc0 + i * 8, 0); + } + } + catweasel_do_bput(3, 0x41); /* enable MK3-mode */ + } + if (cwc.can_joy) + catweasel_do_bput(0xcc, 0); // joystick buttons = input + + catweasel_init_controller(&cwc); + sprintf(tmp, "CW: Catweasel MK%d @%p (%s) enabled.", + cwc.type, (uae_u8*)cwc.iobase, name); + if (cwc.can_sid) { + char *p = tmp + strlen(tmp); + catweasel_detect_sid(); + sprintf(p, " SID0=%d", cwc.sid[0]); + if (cwc.can_sid > 1) { + p += strlen(p); + sprintf(p, " SID1=%d", cwc.sid[1]); + } + } + write_log("%s\n", tmp); + return 1; fail: catweasel_free (); @@ -180,7 +387,11 @@ void catweasel_free (void) CloseHandle (handle); handle = INVALID_HANDLE_VALUE; ioport_free(); - cwc.type = 0; + memset (&cwc, 0, sizeof cwc); + mouse_x[0] = mouse_x[1] = mouse_y[0] = mouse_y[1] = 0; + mouse_px[0] = mouse_px[1] = mouse_py[0] = mouse_py[1] = 0; + cwmk3port = cwmk3port1 = cwmk3port2 = 0; + cwhsync = cwmk3buttonsync = 0; } int catweasel_detect (void) @@ -191,8 +402,8 @@ int catweasel_detect (void) if (handle != INVALID_HANDLE_VALUE) return TRUE; for (i = 0; i < 4; i++) { - sprintf (name, "\\\\.\\CAT%d_F0", i); - handle = CreateFile (name, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, + sprintf (name, "\\\\.\\CAT%u_F0", i); + handle = CreateFile (name, GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (handle != INVALID_HANDLE_VALUE) break; diff --git a/catweasel_old.c b/catweasel_old.c deleted file mode 100755 index 9d345e50..00000000 --- a/catweasel_old.c +++ /dev/null @@ -1,804 +0,0 @@ - -#include "sysconfig.h" -#include "sysdeps.h" - -#ifdef CATWEASEL - -#include "config.h" -#include "options.h" -#include "memory.h" -#include "ioport.h" -#include "catweasel.h" -#include "uae.h" - -#include - -struct catweasel_contr cwc; - -static int cwhsync; -static int handshake; - -static HANDLE h = INVALID_HANDLE_VALUE; - -void catweasel_hsync (void) -{ - if (cwhsync <= 0) - return; - cwhsync--; - if (cwhsync == 0) { - if (handshake) - ioport_write (currprefs.catweasel_io + 0xd0, 0); - handshake = 0; - } -} - -int catweasel_read_joystick (uae_u8 *dir, uae_u8 *buttons) -{ - if (cwc.type != CATWEASEL_TYPE_MK3) - return 0; - *dir = ioport_read (currprefs.catweasel_io + 0xc0); - *buttons = ioport_read (currprefs.catweasel_io + 0xc8); - return 1; -} - -int catweasel_read_keyboard (uae_u8 *keycode) -{ - uae_u8 v; - if (cwc.type != CATWEASEL_TYPE_MK3) - return 0; - v = ioport_read (currprefs.catweasel_io + 0xd4); - if (!(v & 0x80)) - return 0; - if (handshake) - return 0; - *keycode = ioport_read (currprefs.catweasel_io + 0xd0); - ioport_write (currprefs.catweasel_io + 0xd0, 0); - handshake = 1; - cwhsync = 10; - return 1; -} - -uae_u32 catweasel_do_bget (uaecptr addr) -{ - if (cwc.type == CATWEASEL_TYPE_MK3) { - if ((currprefs.catweasel_io & 3) == 0 && addr >= 0xc0 && addr <= 0xfc) - return ioport_read (currprefs.catweasel_io + addr); - } else { - if (addr >= currprefs.catweasel_io && addr <= currprefs.catweasel_io + 8) { - return ioport_read (addr & 0x3ff); - } else if(addr >= 0x10000 + currprefs.catweasel_io && addr <= 0x10000 + currprefs.catweasel_io) { - return ioport_read (addr & 0x3ff); - } else if ((addr & 0x3ff) < 0x200 || (addr & 0x3ff) >= 0x400) { - write_log("catweasel_bget @%08.8X!\n",addr); - } - } - return 0; -} - -void catweasel_do_bput (uaecptr addr, uae_u32 b) -{ - if (cwc.type == CATWEASEL_TYPE_MK3) { - if ((currprefs.catweasel_io & 3) == 0 && addr >= 0xc0 && addr <= 0xfc) - ioport_write (currprefs.catweasel_io + addr, b); - } else { - if (addr >= currprefs.catweasel_io && addr <= currprefs.catweasel_io + 8) { - ioport_write (addr & 0x3ff, b); - } else if(addr >= 0x10000 + currprefs.catweasel_io && addr <= 0x10000 + currprefs.catweasel_io) { - ioport_write (addr & 0x3ff, b); - } else if ((addr & 0x3ff) < 0x200 || (addr & 0x3ff) >= 0x400) { - write_log("catweasel_bput @%08.8X=%02.2X!\n",addr,b); - } - } -} - -int catweasel_init (void) -{ - char name[32]; - int i, len; - uae_u8 buffer[1000]; - uae_u32 model, base; - - for (i = 0; i < 4; i++) { - sprintf (name, "\\\\.\\CAT%d", i); - handle = CreateFile (devname, GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (handle != INVALID_HANDLE_VALUE) - break; - } - if (handle == INVALID_HANDLE_VALUE) - goto fail; - if (!DeviceIoControl (handle, CW_LOCK_EXCLUSIVE, 0L, 0, buffer, sizeof (buffer), &len, 0) { - write_log ("CW_LOCK_EXCLUSIVE failed %d\n", GetLastError()); - goto fail; - model = *((uae_u32*)(buffer + 4)); - base = *((uae_u32*)(buffer + 0)); - write_log ("Catweasel MK%d @%p detected and enabled\n", model, base); - cwc.type = model == 0 ? 1 : model == 3 ? 4 : 2; - cwc.iobase = base; - catweasel_init_controller (&cwc); - return 1; -fail: - catweasel_free (); - return 0; - -} - -void catweasel_free (void) -{ - if (handle != INVALID_HANDLE_VALUE) - CloseHandle (handle); - handle = INVALID_HANDLE_VALUE; - cwc.type = 0; -} - -#define outb(v,port) ioport_write(port,v) -#define inb(port) ioport_read(port) - -#define LONGEST_TRACK 16000 - -static uae_u8 mfmbuf[LONGEST_TRACK * 4]; -static uae_u8 tmpmfmbuffer[LONGEST_TRACK * 2]; - -static int bitshiftcompare(uae_u8 *src,int bit,int len,uae_u8 *comp) -{ - uae_u8 b; - int ones,zeros,len2; - - ones=zeros=0; - len2=len; - while(len--) { - b = (comp[0] << bit) | (comp[1] >> (8 - bit)); - if(b != *src) return 1; - if(b==0x00) zeros++; - if(b==0xff) ones++; - src++; - comp++; - } - if(ones==len2||zeros==len2) return 1; - return 0; -} - -static uae_u8 *mergepieces(uae_u8 *start,int len,int bits,uae_u8 *sync) -{ - uae_u8 *dst=tmpmfmbuffer; - uae_u8 b; - int size; - int shift; - - size=len-(sync-start); - memcpy(dst,sync,size); - dst+=size; - b=start[len]; - b&=~(255>>bits); - b|=start[0]>>bits; - *dst++=b; - shift=8-bits; - while(start<=sync+2000) { - *dst++=(start[0]<>(8-shift)); - start++; - } - return tmpmfmbuffer; -} - -#define SCANOFFSET 1 /* scanning range in bytes, -SCANOFFSET to SCANOFFSET */ -#define SCANOFFSET2 20 -#define SCANLENGHT 200 /* scanning length in bytes */ - -static uae_u8* scantrack(uae_u8 *sync1,uae_u8 *sync2,int *trackbytes,int *trackbits) -{ - int i,bits,bytes,matched; - uae_u8 *sync2bak=sync2; - - sync1+=SCANOFFSET2; - sync2+=SCANOFFSET2; - while(sync1 < sync2bak - 2*SCANOFFSET - SCANOFFSET2 - SCANLENGHT) { - matched=0x7fff; - for(i=0;i<2*SCANOFFSET*8;i++) { - bits=i&7; - bytes=-SCANOFFSET+(i>>3); - if(!bitshiftcompare(sync1,bits,SCANLENGHT,sync2+bytes)) { - if(matched==0x7fff) { - matched=i; - } else { - break; - } - } - } - if(matched!=0x7fff && i>=2*SCANOFFSET*8) { - bits=matched&7; - bytes=-SCANOFFSET+(matched>>3); - *trackbytes=sync2+bytes-sync1; - *trackbits=bits; - return mergepieces(sync1,*trackbytes,*trackbits,sync2bak); - } - sync1++; - sync2++; - } - return 0; -} - -static unsigned char threshtab[128]; - -static void codec_makethresh(int trycnt, const unsigned char *origt, unsigned char *t, int numthresh) -{ - static unsigned char tab[10] = { 0, 0, 0, 0, -1, -2, 1, 2, -1, 1 }; - - if (trycnt >= sizeof (tab)) - trycnt = sizeof (tab) - 1; - while(numthresh--) - t[numthresh] = origt[numthresh] + tab[trycnt]; -} - -static void codec_init_threshtab(int trycnt, const unsigned char *origt) -{ - static unsigned char old_thresholds[2] = { 0, 0 }; - unsigned char t[2]; - int a, i; - - codec_makethresh(trycnt, origt, t, 2); - - if(*(unsigned short*)t == *(unsigned short*)old_thresholds) - return; - - for(i=0,a=2; i<128; i++) { - if(i == t[0] || i == t[1]) - a++; - threshtab[i] = a; - } - - *(unsigned short*)&old_thresholds = *(unsigned short*)t; -} - -static __inline__ void CWSetCReg(catweasel_contr *c, unsigned char clear, unsigned char set) -{ - c->control_register = (c->control_register & ~clear) | set; - outb(c->control_register, c->io_sr); -} - -static void CWTriggerStep(catweasel_contr *c) -{ - CWSetCReg(c, c->crm_step, 0); - CWSetCReg(c, 0, c->crm_step); -} - -void catweasel_init_controller(catweasel_contr *c) -{ - int i, j; - - if(!c->iobase) - return; - - switch(c->type) { - case CATWEASEL_TYPE_MK1: - c->crm_sel0 = 1 << 5; - c->crm_sel1 = 1 << 4; - c->crm_mot0 = 1 << 3; - c->crm_mot1 = 1 << 7; - c->crm_dir = 1 << 1; - c->crm_step = 1 << 0; - c->srm_trk0 = 1 << 4; - c->srm_dchg = 1 << 5; - c->srm_writ = 1 << 1; - c->io_sr = c->iobase + 2; - c->io_mem = c->iobase; - break; - case CATWEASEL_TYPE_MK3: - c->crm_sel0 = 1 << 2; - c->crm_sel1 = 1 << 3; - c->crm_mot0 = 1 << 1; - c->crm_mot1 = 1 << 5; - c->crm_dir = 1 << 4; - c->crm_step = 1 << 7; - c->srm_trk0 = 1 << 2; - c->srm_dchg = 1 << 5; - c->srm_writ = 1 << 6; - c->srm_dskready = 1 << 4; - c->io_sr = c->iobase + 0xe8; - c->io_mem = c->iobase + 0xe0; - break; - default: - return; - } - - c->control_register = 255; - - /* select all drives, step inside */ - CWSetCReg(c, c->crm_dir | c->crm_sel0 | c->crm_sel1, 0); - for(i=0;i<2;i++) { - c->drives[i].number = i; - c->drives[i].contr = c; - c->drives[i].diskindrive = 0; - - /* select only the respective drive, step to track 0 */ - if(i == 0) { - CWSetCReg(c, c->crm_sel0, c->crm_dir | c->crm_sel1); - } else { - CWSetCReg(c, c->crm_sel1, c->crm_dir | c->crm_sel0); - } - - for(j = 0; j < 86 && (inb(c->io_sr) & c->srm_trk0); j++) { - CWTriggerStep(c); - sleep_millis(6); - } - - if(j < 86) { - c->drives[i].type = 1; - c->drives[i].track = 0; - } else { - c->drives[i].type = 0; - } - } - c->drives[0].sel = c->crm_sel0; - c->drives[0].mot = c->crm_mot0; - c->drives[1].sel = c->crm_sel1; - c->drives[1].mot = c->crm_mot1; - CWSetCReg(c, 0, c->crm_sel0 | c->crm_sel1); /* deselect all drives */ -} - -void catweasel_free_controller(catweasel_contr *c) -{ - if(!c->iobase) - return; - - /* all motors off, deselect all drives */ - CWSetCReg(c, 0, c->crm_mot0 | c->crm_mot1 | c->crm_sel0 | c->crm_sel1); -} - -void catweasel_set_motor(catweasel_drive *d, int on) -{ - CWSetCReg(d->contr, d->sel, 0); - if (on) - CWSetCReg(d->contr, d->mot, 0); - else - CWSetCReg(d->contr, 0, d->mot); - CWSetCReg(d->contr, 0, d->sel); -} - -int catweasel_step(catweasel_drive *d, int dir) -{ - catweasel_contr *c = d->contr; - CWSetCReg(c, d->sel, 0); - if (dir > 0) - CWSetCReg(c, c->crm_dir, 0); - else - CWSetCReg(c, 0, c->crm_dir); - CWTriggerStep (c); - CWSetCReg(c, 0, d->sel); - d->track += dir > 0 ? 1 : -1; - return 1; -} - -int catweasel_disk_changed(catweasel_drive *d) -{ - int ret; - CWSetCReg(d->contr, d->sel, 0); - ret = (inb(d->contr->io_sr) & d->contr->srm_dchg) ? 0 : 1; - CWSetCReg(d->contr, 0, d->sel); - return ret; -} - -int catweasel_diskready(catweasel_drive *d) -{ - int ret; - CWSetCReg(d->contr, d->sel, 0); - ret = (inb(d->contr->io_sr) & d->contr->srm_dskready) ? 0 : 1; - CWSetCReg(d->contr, 0, d->sel); - return ret; -} - -int catweasel_track0(catweasel_drive *d) -{ - int ret; - CWSetCReg(d->contr, d->sel, 0); - ret = (inb(d->contr->io_sr) & d->contr->srm_trk0) ? 0 : 1; - CWSetCReg(d->contr, 0, d->sel); - if (ret) - d->track = 0; - return ret; -} - -int catweasel_write_protected(catweasel_drive *d) -{ - int ret; - CWSetCReg(d->contr, d->sel, 0); - ret = !(inb(d->contr->io_sr) & 8); - CWSetCReg(d->contr, 0, d->sel); - return ret; -} - -uae_u8 catweasel_read_byte(catweasel_drive *d) -{ - return inb(d->contr->io_mem); -} - -static const unsigned char amiga_thresholds[] = { 0x22, 0x30 }; // 27, 38 for 5.25" - -#define FLOPPY_WRITE_LEN 6250 - -#define MFMMASK 0x55555555 -static uae_u32 getmfmlong (uae_u16 * mbuf) -{ - return (uae_u32)(((*mbuf << 16) | *(mbuf + 1)) & MFMMASK); -} - -static int drive_write_adf_amigados (uae_u16 *mbuf, uae_u16 *mend, uae_u8 *writebuffer, int track) -{ - int i, secwritten = 0; - uae_u32 odd, even, chksum, id, dlong; - uae_u8 *secdata; - uae_u8 secbuf[544]; - char sectable[22]; - int num_sectors = 11; - int ec = 0; - - memset (sectable, 0, sizeof (sectable)); - mend -= (4 + 16 + 8 + 512); - while (secwritten < num_sectors) { - int trackoffs; - - do { - while (*mbuf++ != 0x4489) { - if (mbuf >= mend) { - ec = 1; - goto err; - } - } - } while (*mbuf++ != 0x4489); - - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2); - mbuf += 4; - id = (odd << 1) | even; - - trackoffs = (id & 0xff00) >> 8; - if (trackoffs > 10) { - ec = 2; - goto err; - } - chksum = odd ^ even; - for (i = 0; i < 4; i++) { - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 8); - mbuf += 2; - - dlong = (odd << 1) | even; - if (dlong) { - ec = 6; - goto err; - } - chksum ^= odd ^ even; - } /* could check here if the label is nonstandard */ - mbuf += 8; - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2); - mbuf += 4; - if (((odd << 1) | even) != chksum) { - ec = 3; - goto err; - } - odd = (id & 0x00ff0000) >> 16; - if (odd != track) { - ec = 7; - goto err; - } - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2); - mbuf += 4; - chksum = (odd << 1) | even; - secdata = secbuf + 32; - for (i = 0; i < 128; i++) { - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 256); - mbuf += 2; - dlong = (odd << 1) | even; - *secdata++ = dlong >> 24; - *secdata++ = dlong >> 16; - *secdata++ = dlong >> 8; - *secdata++ = dlong; - chksum ^= odd ^ even; - } - mbuf += 256; - if (chksum) { - ec = 4; - goto err; - } - sectable[trackoffs] = 1; - secwritten++; - memcpy (writebuffer + trackoffs * 512, secbuf + 32, 512); - } - if (secwritten == 0 || secwritten < 0) { - ec = 5; - goto err; - } - return 0; -err: - write_log ("mfm decode error %d. secwritten=%d\n", ec, secwritten); - for (i = 0; i < num_sectors; i++) - write_log ("%d:%d ", i, sectable[i]); - write_log ("\n"); - return ec; -} - -static void mfmcode (uae_u16 * mfm, int words) -{ - uae_u32 lastword = 0; - - while (words--) { - uae_u32 v = *mfm; - uae_u32 lv = (lastword << 16) | v; - uae_u32 nlv = 0x55555555 & ~lv; - uae_u32 mfmbits = (nlv << 1) & (nlv >> 1); - - *mfm++ = v | mfmbits; - lastword = v; - } -} - -#define FLOPPY_GAP_LEN 360 - -static int amigados_mfmcode (uae_u8 *src, uae_u16 *dst, int num_secs, int track) -{ - int sec; - memset (dst, 0xaa, FLOPPY_GAP_LEN * 2); - - for (sec = 0; sec < num_secs; sec++) { - uae_u8 secbuf[544]; - int i; - uae_u16 *mfmbuf = dst + 544 * sec + FLOPPY_GAP_LEN; - uae_u32 deven, dodd; - uae_u32 hck = 0, dck = 0; - - secbuf[0] = secbuf[1] = 0x00; - secbuf[2] = secbuf[3] = 0xa1; - secbuf[4] = 0xff; - secbuf[5] = track; - secbuf[6] = sec; - secbuf[7] = num_secs - sec; - - for (i = 8; i < 24; i++) - secbuf[i] = 0; - - mfmbuf[0] = mfmbuf[1] = 0xaaaa; - mfmbuf[2] = mfmbuf[3] = 0x4489; - - memcpy (secbuf + 32, src + sec * 512, 512); - deven = ((secbuf[4] << 24) | (secbuf[5] << 16) - | (secbuf[6] << 8) | (secbuf[7])); - dodd = deven >> 1; - deven &= 0x55555555; - dodd &= 0x55555555; - - mfmbuf[4] = dodd >> 16; - mfmbuf[5] = dodd; - mfmbuf[6] = deven >> 16; - mfmbuf[7] = deven; - - for (i = 8; i < 48; i++) - mfmbuf[i] = 0xaaaa; - for (i = 0; i < 512; i += 4) { - deven = ((secbuf[i + 32] << 24) | (secbuf[i + 33] << 16) - | (secbuf[i + 34] << 8) | (secbuf[i + 35])); - dodd = deven >> 1; - deven &= 0x55555555; - dodd &= 0x55555555; - mfmbuf[(i >> 1) + 32] = dodd >> 16; - mfmbuf[(i >> 1) + 33] = dodd; - mfmbuf[(i >> 1) + 256 + 32] = deven >> 16; - mfmbuf[(i >> 1) + 256 + 33] = deven; - } - - for (i = 4; i < 24; i += 2) - hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1]; - - deven = dodd = hck; - dodd >>= 1; - mfmbuf[24] = dodd >> 16; - mfmbuf[25] = dodd; - mfmbuf[26] = deven >> 16; - mfmbuf[27] = deven; - - for (i = 32; i < 544; i += 2) - dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1]; - - deven = dodd = dck; - dodd >>= 1; - mfmbuf[28] = dodd >> 16; - mfmbuf[29] = dodd; - mfmbuf[30] = deven >> 16; - mfmbuf[31] = deven; - mfmcode (mfmbuf + 4, 544 - 4); - - } - return (num_secs * 544 + FLOPPY_GAP_LEN) * 2 * 8; -} - -static uae_u16 amigamfmbuffer[LONGEST_TRACK]; -static uae_u8 amigabuffer[512*22]; - -/* search and align to 0x4489 WORDSYNC markers */ -static int isamigatrack(uae_u8 *mfmdata, uae_u8 *mfmdatae, uae_u16 *mfmdst, int track) -{ - uae_u16 *dst = amigamfmbuffer; - int len; - int shift, syncshift, sync,ret; - uae_u32 l; - uae_u16 w; - - sync = syncshift = shift = 0; - len = (mfmdatae - mfmdata) * 8; - if (len > LONGEST_TRACK * 8) - len = LONGEST_TRACK * 8; - while (len--) { - l = (mfmdata[0] << 16) | (mfmdata[1] << 8) | (mfmdata[2] << 0); - w = l >> (8 - shift); - if (w == 0x4489) { - sync = 1; - syncshift = 0; - } - if (sync) { - if (syncshift == 0) *dst++ = w; - syncshift ++; - if (syncshift == 16) syncshift = 0; - } - shift++; - if (shift == 8) { - mfmdata++; - shift = 0; - } - } - if (sync) { - ret=drive_write_adf_amigados (amigamfmbuffer, dst, amigabuffer, track); - if(!ret) - return amigados_mfmcode (amigabuffer, mfmdst, 11, track); - write_log ("decode error %d\n", ret); - } else { - write_log ("decode error: no sync found\n"); - } - return 0; -} - - - -int catweasel_fillmfm (catweasel_drive *d, uae_u16 *mfm, int side, int clock, int rawmode) -{ - int i, j, oldsync, syncs[10], synccnt, endcnt; - uae_u32 tt1 = 0, tt2 = 0; - uae_u8 *p1; - int bytes = 0, bits = 0; - static int lasttrack, trycnt; - - if (cwc.type == 0) - return 0; - if (d->contr->control_register & d->mot) - return 0; - if (!catweasel_read (d, side, 1, rawmode)) - return 0; - if(d->contr->type == CATWEASEL_TYPE_MK1) { - inb(d->contr->iobase + 1); - inb(d->contr->io_mem); /* ignore first byte */ - } else { - outb(0, d->contr->iobase + 0xe4); - } - catweasel_read_byte (d); - if (lasttrack == d->track) - trycnt++; - else - trycnt = 0; - lasttrack = d->track; - codec_init_threshtab(trycnt, amiga_thresholds); - i = 0; j = 0; - synccnt = 0; - oldsync = -1; - endcnt = 0; - while (j < LONGEST_TRACK * 4) { - uae_u8 b = catweasel_read_byte (d); - if (b >= 250) { - if (b == 255 - endcnt) { - endcnt++; - if (endcnt == 5) - break; - } else - endcnt = 0; - } - if (rawmode) { - if (b & 0x80) { - if (oldsync < j) { - syncs[synccnt++] = j; - oldsync = j + 300; - } - } - if (synccnt >= 3 && j > oldsync) - break; - } - b = threshtab[b & 0x7f]; - tt1 = (tt1 << b) + 1; - tt2 += b; - - if (tt2 >= 16) { - tt2 -= 16; - mfmbuf[j++] = tt1 >> (tt2 + 8); - mfmbuf[j++] = tt1 >> tt2; - } - i++; - } - write_log ("cyl=%d, side=%d, length %d, syncs %d\n", d->track, side, j, synccnt); - if (rawmode) { - if (synccnt >= 3) { - p1 = scantrack (mfmbuf + syncs[1], mfmbuf + syncs[2], &bytes, &bits); - if (p1) { - j = 0; - for (i = 0; i < bytes + 2; i+=2) { - mfm[j++] = (p1[i] << 8) | p1[i + 1]; - } - return bytes * 8 + bits; - } - } - } else { - return isamigatrack (mfmbuf, mfmbuf + j, mfm, d->track * 2 + side); - } - return 0; -} - -int catweasel_read(catweasel_drive *d, int side, int clock, int rawmode) -{ - int iobase = d->contr->iobase; - - CWSetCReg(d->contr, d->sel, 0); - if(d->contr->type == CATWEASEL_TYPE_MK1) { - CWSetCReg(d->contr, 1<<2, (!side)<<2); /* set disk side */ - - inb(iobase+1); /* ra reset */ - outb(clock*128, iobase+3); - - inb(iobase+1); - inb(iobase+0); -// inb(iobase+0); -// outb(0, iobase+3); /* don't store index pulse */ - - inb(iobase+1); - - inb(iobase+7); /* start reading */ - sleep_millis(rawmode ? 550 : 225); - outb(0, iobase+1); /* stop reading, don't reset RAM pointer */ - - outb(128, iobase+0); /* add data end mark */ - outb(128, iobase+0); - - inb(iobase+1); /* Reset RAM pointer */ - } else { - CWSetCReg(d->contr, 1<<6, (!side)<<6); /* set disk side */ - - outb(0, iobase + 0xe4); /* Reset memory pointer */ - switch(clock) { - case 0: /* 28MHz */ - outb(128, iobase + 0xec); - break; - case 1: /* 14MHz */ - outb(0, iobase + 0xec); - break; - } - inb(iobase + 0xe0); - inb(iobase + 0xe0); - outb(0, iobase + 0xec); /* no IRQs, no MFM predecode */ - inb(iobase + 0xe0); - outb(0, iobase + 0xec); /* don't store index pulse */ - - outb(0, iobase + 0xe4); /* Reset memory pointer */ - inb(iobase + 0xf0); /* start reading */ - sleep_millis(rawmode ? 550 : 225); - inb(iobase + 0xe4); /* stop reading, don't reset RAM pointer */ - - outb(255, iobase + 0xe0); /* add data end mark */ - outb(254, iobase + 0xe0); /* add data end mark */ - outb(253, iobase + 0xe0); /* add data end mark */ - outb(252, iobase + 0xe0); /* add data end mark */ - outb(251, iobase + 0xe0); /* add data end mark */ - outb(0, iobase + 0xe4); /* Reset memory pointer */ - } - CWSetCReg(d->contr, 0, d->sel); - return 1; -} - -#endif - - diff --git a/catweasel_old2.c b/catweasel_old2.c deleted file mode 100755 index ac67d333..00000000 --- a/catweasel_old2.c +++ /dev/null @@ -1,778 +0,0 @@ - -#include "sysconfig.h" -#include "sysdeps.h" - -#ifdef CATWEASEL - -#include "config.h" -#include "options.h" -#include "memory.h" -#include "ioport.h" -#include "catweasel.h" -#include "uae.h" - -struct catweasel_contr cwc; - -static int cwhsync; -static int handshake; - -void catweasel_hsync (void) -{ - if (cwhsync <= 0) - return; - cwhsync--; - if (cwhsync == 0) { - if (handshake) - ioport_write (currprefs.catweasel_io + 0xd0, 0); - handshake = 0; - } -} - -int catweasel_read_joystick (uae_u8 *dir, uae_u8 *buttons) -{ - if (cwc.type != CATWEASEL_TYPE_MK3) - return 0; - *dir = ioport_read (currprefs.catweasel_io + 0xc0); - *buttons = ioport_read (currprefs.catweasel_io + 0xc8); - return 1; -} - -int catweasel_read_keyboard (uae_u8 *keycode) -{ - uae_u8 v; - if (cwc.type != CATWEASEL_TYPE_MK3) - return 0; - v = ioport_read (currprefs.catweasel_io + 0xd4); - if (!(v & 0x80)) - return 0; - if (handshake) - return 0; - *keycode = ioport_read (currprefs.catweasel_io + 0xd0); - ioport_write (currprefs.catweasel_io + 0xd0, 0); - handshake = 1; - cwhsync = 10; - return 1; -} - -uae_u32 catweasel_do_bget (uaecptr addr) -{ - if (cwc.type == CATWEASEL_TYPE_MK3) { - if ((currprefs.catweasel_io & 3) == 0 && addr >= 0xc0 && addr <= 0xfc) - return ioport_read (currprefs.catweasel_io + addr); - } else { - if (addr >= currprefs.catweasel_io && addr <= currprefs.catweasel_io + 8) { - return ioport_read (addr & 0x3ff); - } else if(addr >= 0x10000 + currprefs.catweasel_io && addr <= 0x10000 + currprefs.catweasel_io) { - return ioport_read (addr & 0x3ff); - } else if ((addr & 0x3ff) < 0x200 || (addr & 0x3ff) >= 0x400) { - write_log("catweasel_bget @%08.8X!\n",addr); - } - } - return 0; -} - -void catweasel_do_bput (uaecptr addr, uae_u32 b) -{ - if (cwc.type == CATWEASEL_TYPE_MK3) { - if ((currprefs.catweasel_io & 3) == 0 && addr >= 0xc0 && addr <= 0xfc) - ioport_write (currprefs.catweasel_io + addr, b); - } else { - if (addr >= currprefs.catweasel_io && addr <= currprefs.catweasel_io + 8) { - ioport_write (addr & 0x3ff, b); - } else if(addr >= 0x10000 + currprefs.catweasel_io && addr <= 0x10000 + currprefs.catweasel_io) { - ioport_write (addr & 0x3ff, b); - } else if ((addr & 0x3ff) < 0x200 || (addr & 0x3ff) >= 0x400) { - write_log("catweasel_bput @%08.8X=%02.2X!\n",addr,b); - } - } -} - -int catweasel_init (void) -{ - if (!currprefs.catweasel_io) - return 0; - if (!ioport_init ()) - return 0; - cwc.type = currprefs.catweasel_io >= 0x400 ? CATWEASEL_TYPE_MK3 : CATWEASEL_TYPE_MK1; - cwc.iobase = currprefs.catweasel_io; - catweasel_init_controller (&cwc); - return 1; -} - -void catweasel_free (void) -{ - if (!currprefs.catweasel_io) - return; - ioport_free (); - cwc.type = 0; -} - -#define outb(v,port) ioport_write(port,v) -#define inb(port) ioport_read(port) - -#define LONGEST_TRACK 16000 - -static uae_u8 mfmbuf[LONGEST_TRACK * 4]; -static uae_u8 tmpmfmbuffer[LONGEST_TRACK * 2]; - -static int bitshiftcompare(uae_u8 *src,int bit,int len,uae_u8 *comp) -{ - uae_u8 b; - int ones,zeros,len2; - - ones=zeros=0; - len2=len; - while(len--) { - b = (comp[0] << bit) | (comp[1] >> (8 - bit)); - if(b != *src) return 1; - if(b==0x00) zeros++; - if(b==0xff) ones++; - src++; - comp++; - } - if(ones==len2||zeros==len2) return 1; - return 0; -} - -static uae_u8 *mergepieces(uae_u8 *start,int len,int bits,uae_u8 *sync) -{ - uae_u8 *dst=tmpmfmbuffer; - uae_u8 b; - int size; - int shift; - - size=len-(sync-start); - memcpy(dst,sync,size); - dst+=size; - b=start[len]; - b&=~(255>>bits); - b|=start[0]>>bits; - *dst++=b; - shift=8-bits; - while(start<=sync+2000) { - *dst++=(start[0]<>(8-shift)); - start++; - } - return tmpmfmbuffer; -} - -#define SCANOFFSET 1 /* scanning range in bytes, -SCANOFFSET to SCANOFFSET */ -#define SCANOFFSET2 20 -#define SCANLENGHT 200 /* scanning length in bytes */ - -static uae_u8* scantrack(uae_u8 *sync1,uae_u8 *sync2,int *trackbytes,int *trackbits) -{ - int i,bits,bytes,matched; - uae_u8 *sync2bak=sync2; - - sync1+=SCANOFFSET2; - sync2+=SCANOFFSET2; - while(sync1 < sync2bak - 2*SCANOFFSET - SCANOFFSET2 - SCANLENGHT) { - matched=0x7fff; - for(i=0;i<2*SCANOFFSET*8;i++) { - bits=i&7; - bytes=-SCANOFFSET+(i>>3); - if(!bitshiftcompare(sync1,bits,SCANLENGHT,sync2+bytes)) { - if(matched==0x7fff) { - matched=i; - } else { - break; - } - } - } - if(matched!=0x7fff && i>=2*SCANOFFSET*8) { - bits=matched&7; - bytes=-SCANOFFSET+(matched>>3); - *trackbytes=sync2+bytes-sync1; - *trackbits=bits; - return mergepieces(sync1,*trackbytes,*trackbits,sync2bak); - } - sync1++; - sync2++; - } - return 0; -} - -static unsigned char threshtab[128]; - -static void codec_makethresh(int trycnt, const unsigned char *origt, unsigned char *t, int numthresh) -{ - static unsigned char tab[10] = { 0, 0, 0, 0, -1, -2, 1, 2, -1, 1 }; - - if (trycnt >= sizeof (tab)) - trycnt = sizeof (tab) - 1; - while(numthresh--) - t[numthresh] = origt[numthresh] + tab[trycnt]; -} - -static void codec_init_threshtab(int trycnt, const unsigned char *origt) -{ - static unsigned char old_thresholds[2] = { 0, 0 }; - unsigned char t[2]; - int a, i; - - codec_makethresh(trycnt, origt, t, 2); - - if(*(unsigned short*)t == *(unsigned short*)old_thresholds) - return; - - for(i=0,a=2; i<128; i++) { - if(i == t[0] || i == t[1]) - a++; - threshtab[i] = a; - } - - *(unsigned short*)&old_thresholds = *(unsigned short*)t; -} - -static __inline__ void CWSetCReg(catweasel_contr *c, unsigned char clear, unsigned char set) -{ - c->control_register = (c->control_register & ~clear) | set; - outb(c->control_register, c->io_sr); -} - -static void CWTriggerStep(catweasel_contr *c) -{ - CWSetCReg(c, c->crm_step, 0); - CWSetCReg(c, 0, c->crm_step); -} - -void catweasel_init_controller(catweasel_contr *c) -{ - int i, j; - - if(!c->iobase) - return; - - switch(c->type) { - case CATWEASEL_TYPE_MK1: - c->crm_sel0 = 1 << 5; - c->crm_sel1 = 1 << 4; - c->crm_mot0 = 1 << 3; - c->crm_mot1 = 1 << 7; - c->crm_dir = 1 << 1; - c->crm_step = 1 << 0; - c->srm_trk0 = 1 << 4; - c->srm_dchg = 1 << 5; - c->srm_writ = 1 << 1; - c->io_sr = c->iobase + 2; - c->io_mem = c->iobase; - break; - case CATWEASEL_TYPE_MK3: - c->crm_sel0 = 1 << 2; - c->crm_sel1 = 1 << 3; - c->crm_mot0 = 1 << 1; - c->crm_mot1 = 1 << 5; - c->crm_dir = 1 << 4; - c->crm_step = 1 << 7; - c->srm_trk0 = 1 << 2; - c->srm_dchg = 1 << 5; - c->srm_writ = 1 << 6; - c->srm_dskready = 1 << 4; - c->io_sr = c->iobase + 0xe8; - c->io_mem = c->iobase + 0xe0; - break; - default: - return; - } - - c->control_register = 255; - - /* select all drives, step inside */ - CWSetCReg(c, c->crm_dir | c->crm_sel0 | c->crm_sel1, 0); - for(i=0;i<2;i++) { - c->drives[i].number = i; - c->drives[i].contr = c; - c->drives[i].diskindrive = 0; - - /* select only the respective drive, step to track 0 */ - if(i == 0) { - CWSetCReg(c, c->crm_sel0, c->crm_dir | c->crm_sel1); - } else { - CWSetCReg(c, c->crm_sel1, c->crm_dir | c->crm_sel0); - } - - for(j = 0; j < 86 && (inb(c->io_sr) & c->srm_trk0); j++) { - CWTriggerStep(c); - sleep_millis(6); - } - - if(j < 86) { - c->drives[i].type = 1; - c->drives[i].track = 0; - } else { - c->drives[i].type = 0; - } - } - c->drives[0].sel = c->crm_sel0; - c->drives[0].mot = c->crm_mot0; - c->drives[1].sel = c->crm_sel1; - c->drives[1].mot = c->crm_mot1; - CWSetCReg(c, 0, c->crm_sel0 | c->crm_sel1); /* deselect all drives */ -} - -void catweasel_free_controller(catweasel_contr *c) -{ - if(!c->iobase) - return; - - /* all motors off, deselect all drives */ - CWSetCReg(c, 0, c->crm_mot0 | c->crm_mot1 | c->crm_sel0 | c->crm_sel1); -} - -void catweasel_set_motor(catweasel_drive *d, int on) -{ - CWSetCReg(d->contr, d->sel, 0); - if (on) - CWSetCReg(d->contr, d->mot, 0); - else - CWSetCReg(d->contr, 0, d->mot); - CWSetCReg(d->contr, 0, d->sel); -} - -int catweasel_step(catweasel_drive *d, int dir) -{ - catweasel_contr *c = d->contr; - CWSetCReg(c, d->sel, 0); - if (dir > 0) - CWSetCReg(c, c->crm_dir, 0); - else - CWSetCReg(c, 0, c->crm_dir); - CWTriggerStep (c); - CWSetCReg(c, 0, d->sel); - d->track += dir > 0 ? 1 : -1; - return 1; -} - -int catweasel_disk_changed(catweasel_drive *d) -{ - int ret; - CWSetCReg(d->contr, d->sel, 0); - ret = (inb(d->contr->io_sr) & d->contr->srm_dchg) ? 0 : 1; - CWSetCReg(d->contr, 0, d->sel); - return ret; -} - -int catweasel_diskready(catweasel_drive *d) -{ - int ret; - CWSetCReg(d->contr, d->sel, 0); - ret = (inb(d->contr->io_sr) & d->contr->srm_dskready) ? 0 : 1; - CWSetCReg(d->contr, 0, d->sel); - return ret; -} - -int catweasel_track0(catweasel_drive *d) -{ - int ret; - CWSetCReg(d->contr, d->sel, 0); - ret = (inb(d->contr->io_sr) & d->contr->srm_trk0) ? 0 : 1; - CWSetCReg(d->contr, 0, d->sel); - if (ret) - d->track = 0; - return ret; -} - -int catweasel_write_protected(catweasel_drive *d) -{ - int ret; - CWSetCReg(d->contr, d->sel, 0); - ret = !(inb(d->contr->io_sr) & 8); - CWSetCReg(d->contr, 0, d->sel); - return ret; -} - -uae_u8 catweasel_read_byte(catweasel_drive *d) -{ - return inb(d->contr->io_mem); -} - -static const unsigned char amiga_thresholds[] = { 0x22, 0x30 }; // 27, 38 for 5.25" - -#define FLOPPY_WRITE_LEN 6250 - -#define MFMMASK 0x55555555 -static uae_u32 getmfmlong (uae_u16 * mbuf) -{ - return (uae_u32)(((*mbuf << 16) | *(mbuf + 1)) & MFMMASK); -} - -static int drive_write_adf_amigados (uae_u16 *mbuf, uae_u16 *mend, uae_u8 *writebuffer, int track) -{ - int i, secwritten = 0; - uae_u32 odd, even, chksum, id, dlong; - uae_u8 *secdata; - uae_u8 secbuf[544]; - char sectable[22]; - int num_sectors = 11; - int ec = 0; - - memset (sectable, 0, sizeof (sectable)); - mend -= (4 + 16 + 8 + 512); - while (secwritten < num_sectors) { - int trackoffs; - - do { - while (*mbuf++ != 0x4489) { - if (mbuf >= mend) { - ec = 1; - goto err; - } - } - } while (*mbuf++ != 0x4489); - - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2); - mbuf += 4; - id = (odd << 1) | even; - - trackoffs = (id & 0xff00) >> 8; - if (trackoffs > 10) { - ec = 2; - goto err; - } - chksum = odd ^ even; - for (i = 0; i < 4; i++) { - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 8); - mbuf += 2; - - dlong = (odd << 1) | even; - if (dlong) { - ec = 6; - goto err; - } - chksum ^= odd ^ even; - } /* could check here if the label is nonstandard */ - mbuf += 8; - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2); - mbuf += 4; - if (((odd << 1) | even) != chksum) { - ec = 3; - goto err; - } - odd = (id & 0x00ff0000) >> 16; - if (odd != track) { - ec = 7; - goto err; - } - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 2); - mbuf += 4; - chksum = (odd << 1) | even; - secdata = secbuf + 32; - for (i = 0; i < 128; i++) { - odd = getmfmlong (mbuf); - even = getmfmlong (mbuf + 256); - mbuf += 2; - dlong = (odd << 1) | even; - *secdata++ = dlong >> 24; - *secdata++ = dlong >> 16; - *secdata++ = dlong >> 8; - *secdata++ = dlong; - chksum ^= odd ^ even; - } - mbuf += 256; - if (chksum) { - ec = 4; - goto err; - } - sectable[trackoffs] = 1; - secwritten++; - memcpy (writebuffer + trackoffs * 512, secbuf + 32, 512); - } - if (secwritten == 0 || secwritten < 0) { - ec = 5; - goto err; - } - return 0; -err: - write_log ("mfm decode error %d. secwritten=%d\n", ec, secwritten); - for (i = 0; i < num_sectors; i++) - write_log ("%d:%d ", i, sectable[i]); - write_log ("\n"); - return ec; -} - -static void mfmcode (uae_u16 * mfm, int words) -{ - uae_u32 lastword = 0; - - while (words--) { - uae_u32 v = *mfm; - uae_u32 lv = (lastword << 16) | v; - uae_u32 nlv = 0x55555555 & ~lv; - uae_u32 mfmbits = (nlv << 1) & (nlv >> 1); - - *mfm++ = v | mfmbits; - lastword = v; - } -} - -#define FLOPPY_GAP_LEN 360 - -static int amigados_mfmcode (uae_u8 *src, uae_u16 *dst, int num_secs, int track) -{ - int sec; - memset (dst, 0xaa, FLOPPY_GAP_LEN * 2); - - for (sec = 0; sec < num_secs; sec++) { - uae_u8 secbuf[544]; - int i; - uae_u16 *mfmbuf = dst + 544 * sec + FLOPPY_GAP_LEN; - uae_u32 deven, dodd; - uae_u32 hck = 0, dck = 0; - - secbuf[0] = secbuf[1] = 0x00; - secbuf[2] = secbuf[3] = 0xa1; - secbuf[4] = 0xff; - secbuf[5] = track; - secbuf[6] = sec; - secbuf[7] = num_secs - sec; - - for (i = 8; i < 24; i++) - secbuf[i] = 0; - - mfmbuf[0] = mfmbuf[1] = 0xaaaa; - mfmbuf[2] = mfmbuf[3] = 0x4489; - - memcpy (secbuf + 32, src + sec * 512, 512); - deven = ((secbuf[4] << 24) | (secbuf[5] << 16) - | (secbuf[6] << 8) | (secbuf[7])); - dodd = deven >> 1; - deven &= 0x55555555; - dodd &= 0x55555555; - - mfmbuf[4] = dodd >> 16; - mfmbuf[5] = dodd; - mfmbuf[6] = deven >> 16; - mfmbuf[7] = deven; - - for (i = 8; i < 48; i++) - mfmbuf[i] = 0xaaaa; - for (i = 0; i < 512; i += 4) { - deven = ((secbuf[i + 32] << 24) | (secbuf[i + 33] << 16) - | (secbuf[i + 34] << 8) | (secbuf[i + 35])); - dodd = deven >> 1; - deven &= 0x55555555; - dodd &= 0x55555555; - mfmbuf[(i >> 1) + 32] = dodd >> 16; - mfmbuf[(i >> 1) + 33] = dodd; - mfmbuf[(i >> 1) + 256 + 32] = deven >> 16; - mfmbuf[(i >> 1) + 256 + 33] = deven; - } - - for (i = 4; i < 24; i += 2) - hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1]; - - deven = dodd = hck; - dodd >>= 1; - mfmbuf[24] = dodd >> 16; - mfmbuf[25] = dodd; - mfmbuf[26] = deven >> 16; - mfmbuf[27] = deven; - - for (i = 32; i < 544; i += 2) - dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1]; - - deven = dodd = dck; - dodd >>= 1; - mfmbuf[28] = dodd >> 16; - mfmbuf[29] = dodd; - mfmbuf[30] = deven >> 16; - mfmbuf[31] = deven; - mfmcode (mfmbuf + 4, 544 - 4); - - } - return (num_secs * 544 + FLOPPY_GAP_LEN) * 2 * 8; -} - -static uae_u16 amigamfmbuffer[LONGEST_TRACK]; -static uae_u8 amigabuffer[512*22]; - -/* search and align to 0x4489 WORDSYNC markers */ -static int isamigatrack(uae_u8 *mfmdata, uae_u8 *mfmdatae, uae_u16 *mfmdst, int track) -{ - uae_u16 *dst = amigamfmbuffer; - int len; - int shift, syncshift, sync,ret; - uae_u32 l; - uae_u16 w; - - sync = syncshift = shift = 0; - len = (mfmdatae - mfmdata) * 8; - if (len > LONGEST_TRACK * 8) - len = LONGEST_TRACK * 8; - while (len--) { - l = (mfmdata[0] << 16) | (mfmdata[1] << 8) | (mfmdata[2] << 0); - w = l >> (8 - shift); - if (w == 0x4489) { - sync = 1; - syncshift = 0; - } - if (sync) { - if (syncshift == 0) *dst++ = w; - syncshift ++; - if (syncshift == 16) syncshift = 0; - } - shift++; - if (shift == 8) { - mfmdata++; - shift = 0; - } - } - if (sync) { - ret=drive_write_adf_amigados (amigamfmbuffer, dst, amigabuffer, track); - if(!ret) - return amigados_mfmcode (amigabuffer, mfmdst, 11, track); - write_log ("decode error %d\n", ret); - } else { - write_log ("decode error: no sync found\n"); - } - return 0; -} - - - -int catweasel_fillmfm (catweasel_drive *d, uae_u16 *mfm, int side, int clock, int rawmode) -{ - int i, j, oldsync, syncs[10], synccnt, endcnt; - uae_u32 tt1 = 0, tt2 = 0; - uae_u8 *p1; - int bytes = 0, bits = 0; - static int lasttrack, trycnt; - - if (cwc.type == 0) - return 0; - if (d->contr->control_register & d->mot) - return 0; - if (!catweasel_read (d, side, 1, rawmode)) - return 0; - if(d->contr->type == CATWEASEL_TYPE_MK1) { - inb(d->contr->iobase + 1); - inb(d->contr->io_mem); /* ignore first byte */ - } else { - outb(0, d->contr->iobase + 0xe4); - } - catweasel_read_byte (d); - if (lasttrack == d->track) - trycnt++; - else - trycnt = 0; - lasttrack = d->track; - codec_init_threshtab(trycnt, amiga_thresholds); - i = 0; j = 0; - synccnt = 0; - oldsync = -1; - endcnt = 0; - while (j < LONGEST_TRACK * 4) { - uae_u8 b = catweasel_read_byte (d); - if (b >= 250) { - if (b == 255 - endcnt) { - endcnt++; - if (endcnt == 5) - break; - } else - endcnt = 0; - } - if (rawmode) { - if (b & 0x80) { - if (oldsync < j) { - syncs[synccnt++] = j; - oldsync = j + 300; - } - } - if (synccnt >= 3 && j > oldsync) - break; - } - b = threshtab[b & 0x7f]; - tt1 = (tt1 << b) + 1; - tt2 += b; - - if (tt2 >= 16) { - tt2 -= 16; - mfmbuf[j++] = tt1 >> (tt2 + 8); - mfmbuf[j++] = tt1 >> tt2; - } - i++; - } - write_log ("cyl=%d, side=%d, length %d, syncs %d\n", d->track, side, j, synccnt); - if (rawmode) { - if (synccnt >= 3) { - p1 = scantrack (mfmbuf + syncs[1], mfmbuf + syncs[2], &bytes, &bits); - if (p1) { - j = 0; - for (i = 0; i < bytes + 2; i+=2) { - mfm[j++] = (p1[i] << 8) | p1[i + 1]; - } - return bytes * 8 + bits; - } - } - } else { - return isamigatrack (mfmbuf, mfmbuf + j, mfm, d->track * 2 + side); - } - return 0; -} - -int catweasel_read(catweasel_drive *d, int side, int clock, int rawmode) -{ - int iobase = d->contr->iobase; - - CWSetCReg(d->contr, d->sel, 0); - if(d->contr->type == CATWEASEL_TYPE_MK1) { - CWSetCReg(d->contr, 1<<2, (!side)<<2); /* set disk side */ - - inb(iobase+1); /* ra reset */ - outb(clock*128, iobase+3); - - inb(iobase+1); - inb(iobase+0); -// inb(iobase+0); -// outb(0, iobase+3); /* don't store index pulse */ - - inb(iobase+1); - - inb(iobase+7); /* start reading */ - sleep_millis(rawmode ? 550 : 225); - outb(0, iobase+1); /* stop reading, don't reset RAM pointer */ - - outb(128, iobase+0); /* add data end mark */ - outb(128, iobase+0); - - inb(iobase+1); /* Reset RAM pointer */ - } else { - CWSetCReg(d->contr, 1<<6, (!side)<<6); /* set disk side */ - - outb(0, iobase + 0xe4); /* Reset memory pointer */ - switch(clock) { - case 0: /* 28MHz */ - outb(128, iobase + 0xec); - break; - case 1: /* 14MHz */ - outb(0, iobase + 0xec); - break; - } - inb(iobase + 0xe0); - inb(iobase + 0xe0); - outb(0, iobase + 0xec); /* no IRQs, no MFM predecode */ - inb(iobase + 0xe0); - outb(0, iobase + 0xec); /* don't store index pulse */ - - outb(0, iobase + 0xe4); /* Reset memory pointer */ - inb(iobase + 0xf0); /* start reading */ - sleep_millis(rawmode ? 550 : 225); - inb(iobase + 0xe4); /* stop reading, don't reset RAM pointer */ - - outb(255, iobase + 0xe0); /* add data end mark */ - outb(254, iobase + 0xe0); /* add data end mark */ - outb(253, iobase + 0xe0); /* add data end mark */ - outb(252, iobase + 0xe0); /* add data end mark */ - outb(251, iobase + 0xe0); /* add data end mark */ - outb(0, iobase + 0xe4); /* Reset memory pointer */ - } - CWSetCReg(d->contr, 0, d->sel); - return 1; -} - -#endif \ No newline at end of file diff --git a/cfgfile.c b/cfgfile.c index 86d48fc7..aba821e6 100755 --- a/cfgfile.c +++ b/cfgfile.c @@ -581,9 +581,9 @@ static int cfgfile_parse_host (struct uae_prefs *p, char *option, char *value) *tmpp = '\0'; if (strcmp (section, TARGET_NAME) == 0) { /* We special case the various path options here. */ - if (cfgfile_string (option, value, "rom_path", p->path_rom, 256) - || cfgfile_string (option, value, "floppy_path", p->path_floppy, 256) - || cfgfile_string (option, value, "hardfile_path", p->path_hardfile, 256)) + if (cfgfile_string (option, value, "rom_path", p->path_rom, sizeof p->path_rom) + || cfgfile_string (option, value, "floppy_path", p->path_floppy, sizeof p->path_floppy) + || cfgfile_string (option, value, "hardfile_path", p->path_hardfile, sizeof p->path_hardfile)) return 1; return target_parse_option (p, option, value); } @@ -591,7 +591,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, char *option, char *value) } for (i = 0; i < MAX_SPARE_DRIVES; i++) { sprintf (tmpbuf, "diskimage%d", i); - if (cfgfile_string (option, value, tmpbuf, p->dfxlist[i], 256)) { + if (cfgfile_string (option, value, tmpbuf, p->dfxlist[i], sizeof p->dfxlist[i])) { #if 0 if (i < 4 && !p->df[i][0]) strcpy (p->df[i], p->dfxlist[i]); @@ -635,12 +635,12 @@ static int cfgfile_parse_host (struct uae_prefs *p, char *option, char *value) || cfgfile_intval (option, value, "override_dga_address", &p->override_dga_address, 1)) return 1; - if (cfgfile_string (option, value, "floppy0soundext", p->dfxclickexternal[0], 256) - || cfgfile_string (option, value, "floppy1soundext", p->dfxclickexternal[1], 256) - || cfgfile_string (option, value, "floppy2soundext", p->dfxclickexternal[2], 256) - || cfgfile_string (option, value, "floppy3soundext", p->dfxclickexternal[3], 256) - || cfgfile_string (option, value, "config_info", p->info, 256) - || cfgfile_string (option, value, "config_description", p->description, 256)) + if (cfgfile_string (option, value, "floppy0soundext", p->dfxclickexternal[0], sizeof p->dfxclickexternal[0]) + || cfgfile_string (option, value, "floppy1soundext", p->dfxclickexternal[1], sizeof p->dfxclickexternal[1]) + || cfgfile_string (option, value, "floppy2soundext", p->dfxclickexternal[2], sizeof p->dfxclickexternal[2]) + || cfgfile_string (option, value, "floppy3soundext", p->dfxclickexternal[3], sizeof p->dfxclickexternal[3]) + || cfgfile_string (option, value, "config_info", p->info, sizeof p->info) + || cfgfile_string (option, value, "config_description", p->description, sizeof p->description)) return 1; if (cfgfile_yesno (option, value, "use_debugger", &p->start_debugger) @@ -896,17 +896,17 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu || cfgfile_strval (option, value, "collision_level", &p->collision_level, collmode, 0) || cfgfile_strval (option, value, "comp_flushmode", &p->comp_hardflush, flushmode, 0)) return 1; - if (cfgfile_string (option, value, "kickstart_rom_file", p->romfile, 256) - || cfgfile_string (option, value, "kickstart_ext_rom_file", p->romextfile, 256) - || cfgfile_string (option, value, "flash_file", p->flashfile, 256) - || cfgfile_string (option, value, "cart_file", p->cartfile, 256) - || cfgfile_string (option, value, "pci_devices", p->pci_devices, 256) - || cfgfile_string (option, value, "ghostscript_parameters", p->ghostscript_parameters, 256)) + if (cfgfile_string (option, value, "kickstart_rom_file", p->romfile, sizeof p->romfile) + || cfgfile_string (option, value, "kickstart_ext_rom_file", p->romextfile, sizeof p->romextfile) + || cfgfile_string (option, value, "flash_file", p->flashfile, sizeof p->flashfile) + || cfgfile_string (option, value, "cart_file", p->cartfile, sizeof p->cartfile) + || cfgfile_string (option, value, "pci_devices", p->pci_devices, sizeof p->pci_devices) + || cfgfile_string (option, value, "ghostscript_parameters", p->ghostscript_parameters, sizeof p->ghostscript_parameters)) return 1; for (i = 0; i < 4; i++) { sprintf (tmpbuf, "floppy%d", i); - if (cfgfile_string (option, value, tmpbuf, p->df[i], 256)) { + if (cfgfile_string (option, value, tmpbuf, p->df[i], sizeof p->df[i])) { #if 0 strcpy (p->dfxlist[i], p->df[i]); #endif @@ -1104,9 +1104,9 @@ int cfgfile_parse_option (struct uae_prefs *p, char *option, char *value, int ty return 1; if (!strcmp (option, "config_host")) return 1; - if (cfgfile_string (option, value, "config_hardware_path", p->config_hardware_path, 256)) + if (cfgfile_string (option, value, "config_hardware_path", p->config_hardware_path, sizeof p->config_hardware_path)) return 1; - if (cfgfile_string (option, value, "config_host_path", p->config_host_path, 256)) + if (cfgfile_string (option, value, "config_host_path", p->config_host_path, sizeof p->config_host_path)) return 1; if (type == 0 || (type & CONFIG_TYPE_HARDWARE)) { if (cfgfile_parse_hardware (p, option, value)) diff --git a/compemu_fpp.c b/compemu_fpp.c index 24244edc..795805e1 100755 --- a/compemu_fpp.c +++ b/compemu_fpp.c @@ -21,6 +21,8 @@ #include "md-fpp.h" #include "compemu.h" +#if defined(JIT) + #define MAKE_FPSR(r) do { fmov_rr(FP_RESULT,r); } while (0) #define delay //nop() ;nop() @@ -1610,3 +1612,5 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra) m68k_setpc (m68k_getpc () - 4); op_illg (opcode); } + +#endif diff --git a/compemu_optimizer.c b/compemu_optimizer.c index e48d57d7..b9bcc612 100755 --- a/compemu_optimizer.c +++ b/compemu_optimizer.c @@ -56,19 +56,19 @@ #define OPT_FR OFR , #define OPT_FRW OFRW , -#define DIR_IMM -#define DIR_MEMR -#define DIR_MEMW -#define DIR_MEMRW -#define DIR_R1 -#define DIR_R2 -#define DIR_R4 -#define DIR_W1 -#define DIR_W2 -#define DIR_W4 -#define DIR_RW1 -#define DIR_RW2 -#define DIR_RW4 +#define DIR_IMM +#define DIR_MEMR +#define DIR_MEMW +#define DIR_MEMRW +#define DIR_R1 +#define DIR_R2 +#define DIR_R4 +#define DIR_W1 +#define DIR_W2 +#define DIR_W4 +#define DIR_RW1 +#define DIR_RW2 +#define DIR_RW4 #define DIR_FR #define DIR_FW @@ -108,7 +108,7 @@ static __inline__ void store_any(uae_u8 type, uae_u32 val) static __inline__ void store_arg(uae_u8 type, uae_u32 val) { - if (typeORW4) + if (typeORW4) return; store_any(type,val); } @@ -123,7 +123,7 @@ static __inline__ void opt_store_op1(uae_u8 t1, uae_u32 a1) store_arg(t1,a1); opt_store_op0(); } - + static __inline__ void opt_store_op2(uae_u8 t1, uae_u32 a1, uae_u8 t2, uae_u32 a2) { @@ -162,7 +162,7 @@ static void opt_assert_empty(int line) { } -void empty_optimizer(void) +void empty_optimizer(void) { } diff --git a/compemu_optimizer_x86.c b/compemu_optimizer_x86.c index 52a1b91e..cc40eed2 100755 --- a/compemu_optimizer_x86.c +++ b/compemu_optimizer_x86.c @@ -68,22 +68,22 @@ #define LOPT_MEMW LMEMW, #define LOPT_MEMRW LMEMRW, -#define LDIR_IMM -#define LDIR_R1 -#define LDIR_R2 -#define LDIR_R4 -#define LDIR_W1 -#define LDIR_W2 -#define LDIR_W4 -#define LDIR_RW1 -#define LDIR_RW2 -#define LDIR_RW4 +#define LDIR_IMM +#define LDIR_R1 +#define LDIR_R2 +#define LDIR_R4 +#define LDIR_W1 +#define LDIR_W2 +#define LDIR_W4 +#define LDIR_RW1 +#define LDIR_RW2 +#define LDIR_RW4 #define LDIR_FW #define LDIR_FR #define LDIR_FRW -#define LDIR_MEMR -#define LDIR_MEMW -#define LDIR_MEMRW +#define LDIR_MEMR +#define LDIR_MEMW +#define LDIR_MEMRW #undef LOWFUNC @@ -100,7 +100,7 @@ } else { \ do_##func ldirect##nargs##args; \ } \ - } + } typedef struct lopt_inst_rec { void* func; @@ -124,13 +124,13 @@ static __inline__ int argsize(int type) static __inline__ int reads_mem(int i) { return linst[i].mem & READ; } - - + + static __inline__ int access_reg(int i, int r, int mode) { int k; for (k=0;k=i-4 && j>=0 && !depends_on(i,j)) { j--; } @@ -272,7 +272,7 @@ static void lopt_emit_all(void) int i; lopt_inst* x; static int inemit=0; - + if (inemit) { printf("WARNING: lopt_emit is not reentrant!\n"); } @@ -305,7 +305,7 @@ static __inline__ void low_advance(void) lopt_emit_all(); } -static __inline__ void lopt_store_op0(void* lfuncptr, uae_u32 lmem, +static __inline__ void lopt_store_op0(void* lfuncptr, uae_u32 lmem, uae_u32 lflags) { linst[lopt_index].func=lfuncptr; @@ -316,7 +316,7 @@ static __inline__ void lopt_store_op0(void* lfuncptr, uae_u32 lmem, } static __inline__ void lopt_store_op1(uae_u8 t1, uae_u32 a1, - void* lfuncptr, uae_u32 lmem, + void* lfuncptr, uae_u32 lmem, uae_u32 lflags) { linst[lopt_index].func=lfuncptr; @@ -330,7 +330,7 @@ static __inline__ void lopt_store_op1(uae_u8 t1, uae_u32 a1, static __inline__ void lopt_store_op2(uae_u8 t1, uae_u32 a1, uae_u8 t2, uae_u32 a2, - void* lfuncptr, uae_u32 lmem, + void* lfuncptr, uae_u32 lmem, uae_u32 lflags) { linst[lopt_index].func=lfuncptr; @@ -347,7 +347,7 @@ static __inline__ void lopt_store_op2(uae_u8 t1, uae_u32 a1, static __inline__ void lopt_store_op3(uae_u8 t1, uae_u32 a1, uae_u8 t2, uae_u32 a2, uae_u8 t3, uae_u32 a3, - void* lfuncptr, uae_u32 lmem, + void* lfuncptr, uae_u32 lmem, uae_u32 lflags) { linst[lopt_index].func=lfuncptr; @@ -367,7 +367,7 @@ static __inline__ void lopt_store_op4(uae_u8 t1, uae_u32 a1, uae_u8 t2, uae_u32 a2, uae_u8 t3, uae_u32 a3, uae_u8 t4, uae_u32 a4, - void* lfuncptr, uae_u32 lmem, + void* lfuncptr, uae_u32 lmem, uae_u32 lflags) { linst[lopt_index].func=lfuncptr; @@ -390,7 +390,7 @@ static __inline__ void lopt_store_op5(uae_u8 t1, uae_u32 a1, uae_u8 t3, uae_u32 a3, uae_u8 t4, uae_u32 a4, uae_u8 t5, uae_u32 a5, - void* lfuncptr, uae_u32 lmem, + void* lfuncptr, uae_u32 lmem, uae_u32 lflags) { linst[lopt_index].func=lfuncptr; @@ -410,7 +410,7 @@ static __inline__ void lopt_store_op5(uae_u8 t1, uae_u32 a1, low_advance(); } -static __inline__ void empty_low_optimizer(void) +static __inline__ void empty_low_optimizer(void) { lopt_emit_all(); } diff --git a/compemu_raw_x86.c b/compemu_raw_x86.c index b470eade..429ebd5a 100755 --- a/compemu_raw_x86.c +++ b/compemu_raw_x86.c @@ -1982,14 +1982,14 @@ int EvalException ( LPEXCEPTION_POINTERS blah, int n_except ) blockinfo* bi; if (currprefs.comp_oldsegv) { - addr-=NATMEM_OFFSET; + addr-=(uae_u32)NATMEM_OFFSET; +#ifdef JIT_DEBUG if ((addr>=0x10000000 && addr<0x40000000) || (addr>=0x50000000)) { -#ifdef JIT_DEBUG write_log("Suspicious address 0x%x in SEGV handler.\n",addr); -#endif } +#endif if (dir==SIG_READ) { switch(size) { case 1: *((uae_u8*)pr)=get_byte(addr); break; @@ -2018,14 +2018,14 @@ int EvalException ( LPEXCEPTION_POINTERS blah, int n_except ) int i; uae_u8 vecbuf[5]; - addr-=NATMEM_OFFSET; + addr-=(uae_u32)NATMEM_OFFSET; +#ifdef JIT_DEBUG if ((addr>=0x10000000 && addr<0x40000000) || (addr>=0x50000000)) { -#ifdef JIT_DEBUG write_log("Suspicious address 0x%x in SEGV handler.\n",addr); -#endif } +#endif target=(uae_u8*)pContext->Eip; for (i=0;i<5;i++) @@ -2111,14 +2111,14 @@ int EvalException ( LPEXCEPTION_POINTERS blah, int n_except ) return EXCEPTION_CONTINUE_EXECUTION; } } - write_log("JIT: Can't handle access!\n"); - if( i ) + write_log("JIT: Can't handle access %08.8X!\n", i); +#if 0 + if (i) { for (j=0;j<10;j++) { write_log("JIT: instruction byte %2d is 0x%02x\n",j,i[j]); } } -#if 0 write_log("Please send the above info (starting at \"fault address\") to\n" "bmeyer@csse.monash.edu.au\n" "This shouldn't happen ;-)\n"); @@ -3191,21 +3191,21 @@ LOWFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s)) ds=stackpos(s); emit_byte(0xd9); - emit_byte(0xe8); /* fld 1.0 */ - emit_byte(0xd9); - emit_byte(0xc1+ds); /* fld x */ + emit_byte(0xc0+ds); /* fld x */ emit_byte(0xd8); emit_byte(0xc8); /* fmul x*x */ - emit_byte(0xd8); - emit_byte(0xe9); /* fsubr 1 - (x^2) */ + emit_byte(0xd9); + emit_byte(0xe8); /* fld 1.0 */ + emit_byte(0xde); + emit_byte(0xe1); /* fsubrp 1 - (x^2) */ emit_byte(0xd9); emit_byte(0xfa); /* fsqrt sqrt(1-(x^2)) */ - emit_byte(0xd8); - emit_byte(0xfa+ds); /* fdivr x / sqrt(1-(x^2)) */ emit_byte(0xd9); - emit_byte(0xc9); /* fxch swap with 1.0 */ + emit_byte(0xc1+ds); /* fld x again */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap x with sqrt(1-(x^2)) */ emit_byte(0xd9); - emit_byte(0xf3); /* fpatan atan(x)/1 & pop */ + emit_byte(0xf3); /* fpatan atan(x/sqrt(1-(x^2))) & pop */ tos_make(d); /* store y=asin(x) */ } LENDFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s)) @@ -3225,12 +3225,14 @@ LOWFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s)) emit_byte(0xe9); /* fsubr 1 - (x^2) */ emit_byte(0xd9); emit_byte(0xfa); /* fsqrt sqrt(1-(x^2)) */ - emit_byte(0xd8); - emit_byte(0xf2+ds); /* fdiv sqrt(1-(x^2)) / x */ emit_byte(0xd9); emit_byte(0xc9); /* fxch swap with 1.0 */ + emit_byte(0xd8); + emit_byte(0xc2+ds); /* fadd 1 + x */ emit_byte(0xd9); - emit_byte(0xf3); /* fpatan atan(x)/1 & pop */ + emit_byte(0xf3); /* fpatan atan(sqrt(1-(x^2))/(1+x)) & pop */ + emit_byte(0xd8); + emit_byte(0xc0); /* fadd 2*atan(sqrt(1-(x^2))/(1+x)) */ tos_make(d); /* store y=acos(x) */ } LENDFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s)) @@ -3245,7 +3247,7 @@ LOWFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s)) emit_byte(0xd9); emit_byte(0xe8); /* fld 1.0 */ emit_byte(0xd9); - emit_byte(0xf3); /* fpatan atan(x)/1 */ + emit_byte(0xf3); /* fpatan atan(x)/1 & pop*/ tos_make(d); /* store y=atan(x) */ } LENDFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s)) diff --git a/compemu_support.c b/compemu_support.c index f59bcb86..a79fdef9 100755 --- a/compemu_support.c +++ b/compemu_support.c @@ -1,3 +1,4 @@ + #define writemem_special writemem #define readmem_special readmem @@ -14,6 +15,10 @@ #include "comptbl.h" #include "compemu.h" +#if defined(JIT) + +#define NATMEM_OFFSETX (uae_u32)NATMEM_OFFSET + // %%% BRIAN KING WAS HERE %%% extern int canbang; #include @@ -5056,9 +5061,9 @@ static void writemem_real(int address, int source, int offset, int size, int tmp if (clobber) f=source; switch(size) { - case 1: mov_b_bRr(address,source,NATMEM_OFFSET); break; - case 2: mov_w_rr(f,source); bswap_16(f); mov_w_bRr(address,f,NATMEM_OFFSET); break; - case 4: mov_l_rr(f,source); bswap_32(f); mov_l_bRr(address,f,NATMEM_OFFSET); break; + case 1: mov_b_bRr(address,source,NATMEM_OFFSETX); break; + case 2: mov_w_rr(f,source); bswap_16(f); mov_w_bRr(address,f,NATMEM_OFFSETX); break; + case 4: mov_l_rr(f,source); bswap_32(f); mov_l_bRr(address,f,NATMEM_OFFSETX); break; } forget_about(tmp); forget_about(f); @@ -5193,9 +5198,9 @@ static void readmem_real(int address, int dest, int offset, int size, int tmp) #ifdef NATMEM_OFFSET if (canbang) { /* Woohoo! go directly at the memory! */ switch(size) { - case 1: mov_b_brR(dest,address,NATMEM_OFFSET); break; - case 2: mov_w_brR(dest,address,NATMEM_OFFSET); bswap_16(dest); break; - case 4: mov_l_brR(dest,address,NATMEM_OFFSET); bswap_32(dest); break; + case 1: mov_b_brR(dest,address,NATMEM_OFFSETX); break; + case 2: mov_w_brR(dest,address,NATMEM_OFFSETX); bswap_16(dest); break; + case 4: mov_l_brR(dest,address,NATMEM_OFFSETX); bswap_32(dest); break; } forget_about(tmp); return; @@ -5298,7 +5303,7 @@ static __inline__ void get_n_addr_real(int address, int dest, int tmp) #ifdef NATMEM_OFFSET if (canbang) { - lea_l_brr(dest,address,NATMEM_OFFSET); + lea_l_brr(dest,address,NATMEM_OFFSETX); forget_about(tmp); return; } @@ -6350,4 +6355,4 @@ void compile_block(cpu_history* pc_hist, int blocklen, int totcycles) } } - +#endif diff --git a/crc32.c b/crc32.c index 18729a1c..30025556 100755 --- a/crc32.c +++ b/crc32.c @@ -7,7 +7,7 @@ static void make_crc_table() { unsigned long c; int n, k; - for (n = 0; n < 256; n++) + for (n = 0; n < 256; n++) { c = (unsigned long)n; for (k = 0; k < 8; k++) c = (c >> 1) ^ (c & 1 ? 0xedb88320 : 0); @@ -21,7 +21,7 @@ uae_u32 get_crc32 (uae_u8 *buf, int len) make_crc_table(); crc = 0xffffffff; while (len-- > 0) { - crc = crc_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8); + crc = crc_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8); } return crc ^ 0xffffffff; } diff --git a/custom.c b/custom.c index 51e79470..55614bd5 100755 --- a/custom.c +++ b/custom.c @@ -54,7 +54,9 @@ #include "avioutput.h" #include "debug.h" #include "akiko.h" +#if defined(ENFORCER) #include "enforcer.h" +#endif void uae_abort (const char *format,...) { @@ -2649,8 +2651,9 @@ void INTREQ (uae_u16 v) serial_check_irq (); rethink_cias (); #if 0 - if (1 || (v & (0x10))) - write_log("%d INTREQ %04.4X (%04.4X) %x %x %x\n", vpos, intreq, v, m68k_getpc(), cop1lc, cop2lc); + if (0 || (v & (0x8010)) == 0x8010) + write_log("%d INTREQ %04.4X (%04.4X) %x %x %x\n", + vpos, intreq, v, m68k_getpc(), cop1lc, cop2lc); #endif } @@ -4775,11 +4778,9 @@ void customreset (void) /* Doing this here ensures we can use the 'reset' command from within AR */ action_replay_reset (); #endif - #ifdef WIN32 - #ifndef UAE_MINI + #if defined(ENFORCER) enforcer_disable(); #endif - #endif } void dumpcustom (void) diff --git a/custom2.c b/custom2.c new file mode 100755 index 00000000..55614bd5 --- /dev/null +++ b/custom2.c @@ -0,0 +1,5755 @@ + /* + * UAE - The Un*x Amiga Emulator + * + * Custom chip emulation + * + * Copyright 1995-2002 Bernd Schmidt + * Copyright 1995 Alessandro Bissacco + * Copyright 2000-2004 Toni Wilen + */ + +//#define CUSTOM_DEBUG +#define DEBUG_COPPER 0 +#define SPRITE_DEBUG 0 +#define SPRITE_DEBUG_MINY 0 +#define SPRITE_DEBUG_MAXY 100 +//#define SPRITE_MASK 0 +#define SPRITE_MASK (1|2|4|8|16|32|64|128) +#define SPR0_HPOS 0x15 +#define MAX_SPRITES 8 +#define SPRITE_COLLISIONS +#define SPEEDUP + +#include "sysconfig.h" +#include "sysdeps.h" + +#include +#include + +#include "config.h" +#include "options.h" +#include "threaddep/thread.h" +#include "uae.h" +#include "gensound.h" +#include "sounddep/sound.h" +#include "events.h" +#include "memory.h" +#include "custom.h" +#include "newcpu.h" +#include "cia.h" +#include "disk.h" +#include "blitter.h" +#include "xwin.h" +#include "inputdevice.h" +#include "audio.h" +#include "keybuf.h" +#include "serial.h" +#include "osemu.h" +#include "autoconf.h" +#include "gui.h" +#include "picasso96.h" +#include "drawing.h" +#include "savestate.h" +#include "ar.h" +#include "avioutput.h" +#include "debug.h" +#include "akiko.h" +#if defined(ENFORCER) +#include "enforcer.h" +#endif + +void uae_abort (const char *format,...) +{ + static int nomore; + va_list parms; + char buffer[1000]; + + va_start (parms, format); + _vsnprintf( buffer, sizeof (buffer) -1, format, parms ); + va_end (parms); + if (nomore) { + write_log(buffer); + return; + } + gui_message (buffer); + nomore = 1; +} + +#if 0 +void customhack_put (struct customhack *ch, uae_u16 v, int hpos) +{ + ch->v = v; + ch->vpos = vpos; + ch->hpos = hpos; +} + +uae_u16 customhack_get (struct customhack *ch, int hpos) +{ + if (ch->vpos == vpos && ch->hpos == hpos) { + ch->vpos = -1; + return 0xffff; + } + return ch->v; +} +#endif + +static uae_u16 last_custom_value; + +static unsigned int n_consecutive_skipped = 0; +static unsigned int total_skipped = 0; + +STATIC_INLINE void sync_copper (int hpos); + +/* Events */ + +unsigned long int event_cycles, nextevent, is_lastline, currcycle; +long cycles_to_next_event; +long max_cycles_to_next_event; +long cycles_to_hsync_event; + +static int rpt_did_reset; +struct ev eventtab[ev_max]; + +volatile frame_time_t vsynctime, vsyncmintime; + +#ifdef JIT +extern uae_u8* compiled_code; +#endif + +int vpos; +int hack_vpos; +static uae_u16 lof; +static int next_lineno; +static enum nln_how nextline_how; +static int lof_changed = 0; + +static uae_u32 sprtaba[256],sprtabb[256]; +static uae_u32 sprite_ab_merge[256]; +/* Tables for collision detection. */ +static uae_u32 sprclx[16], clxmask[16]; + +/* + * Hardware registers of all sorts. + */ + +static int custom_wput_1 (int, uaecptr, uae_u32, int) REGPARAM; + +static uae_u16 cregs[256]; + +uae_u16 intena,intreq; +uae_u16 dmacon; +uae_u16 adkcon; /* used by audio code */ + +static uae_u32 cop1lc,cop2lc,copcon; + +int maxhpos = MAXHPOS_PAL; +int maxvpos = MAXVPOS_PAL; +int minfirstline = VBLANK_ENDLINE_PAL; +int vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_skip; +unsigned long syncbase; +static int fmode; +unsigned int beamcon0, new_beamcon0; +uae_u16 vtotal = MAXVPOS_PAL, htotal = MAXHPOS_PAL; +static uae_u16 hsstop, hbstrt, hbstop, vsstop, vbstrt, vbstop, hsstrt, vsstrt, hcenter; + +#define HSYNCTIME (maxhpos * CYCLE_UNIT); + +/* This is but an educated guess. It seems to be correct, but this stuff + * isn't documented well. */ +struct sprite { + uaecptr pt; + int xpos; + int vstart; + int vstop; + int armed; + int dmastate; + int dmacycle; +}; + +static struct sprite spr[MAX_SPRITES]; + +static int sprite_vblank_endline = VBLANK_SPRITE_PAL; + +static unsigned int sprctl[MAX_SPRITES], sprpos[MAX_SPRITES]; +#ifdef AGA +static uae_u16 sprdata[MAX_SPRITES][4], sprdatb[MAX_SPRITES][4]; +#else +static uae_u16 sprdata[MAX_SPRITES][1], sprdatb[MAX_SPRITES][1]; +#endif +static int sprite_last_drawn_at[MAX_SPRITES]; +static int last_sprite_point, nr_armed; +static int sprite_width, sprres, sprite_buffer_res; + +#ifdef CPUEMU_6 +uae_u8 cycle_line[256]; +#endif + +static uae_u32 bpl1dat; +#if 0 /* useless */ +static uae_u32 bpl2dat, bpl3dat, bpl4dat, bpl5dat, bpl6dat, bpl7dat, bpl8dat; +#endif +static uae_s16 bpl1mod, bpl2mod; + +static uaecptr bplpt[8]; +uae_u8 *real_bplpt[8]; +/* Used as a debugging aid, to offset any bitplane temporarily. */ +int bpl_off[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +/*static int blitcount[256]; blitter debug */ + +static struct color_entry current_colors; +static unsigned int bplcon0, bplcon1, bplcon2, bplcon3, bplcon4; +static unsigned int diwstrt, diwstop, diwhigh; +static int diwhigh_written; +static unsigned int ddfstrt, ddfstop, ddfstrt_old_hpos, ddfstrt_old_vpos; +static int ddf_change; +static unsigned int bplcon0_at_start; + +/* The display and data fetch windows */ + +enum diw_states +{ + DIW_waiting_start, DIW_waiting_stop +}; + +int plffirstline, plflastline; +int plfstrt, plfstop; +static int last_diw_pix_hpos, last_ddf_pix_hpos; +static int last_decide_line_hpos, last_sprite_decide_line_hpos; +static int last_fetch_hpos, last_sprite_hpos; +int diwfirstword, diwlastword; +static enum diw_states diwstate, hdiwstate, ddfstate; + +/* Sprite collisions */ +static unsigned int clxdat, clxcon, clxcon2, clxcon_bpl_enable, clxcon_bpl_match; + +enum copper_states { + COP_stop, + COP_read1_in2, + COP_read1_wr_in4, + COP_read1_wr_in2, + COP_read1, + COP_read2_wr_in2, + COP_read2, + COP_bltwait, + COP_wait_in4, + COP_wait_in2, + COP_skip_in4, + COP_skip_in2, + COP_wait1, + COP_wait, + COP_skip1, + COP_strobe_delay +}; + +struct copper { + /* The current instruction words. */ + unsigned int i1, i2; + unsigned int saved_i1, saved_i2; + enum copper_states state; + /* Instruction pointer. */ + uaecptr ip, saved_ip; + int hpos, vpos; + unsigned int ignore_next; + int vcmp, hcmp; + + /* When we schedule a copper event, knowing a few things about the future + of the copper list can reduce the number of sync_with_cpu calls + dramatically. */ + unsigned int first_sync; + unsigned int regtypes_modified; + int strobe; /* COPJMP1 / COPJMP2 accessed */ + int last_write, last_write_hpos; +}; + +#define REGTYPE_NONE 0 +#define REGTYPE_COLOR 1 +#define REGTYPE_SPRITE 2 +#define REGTYPE_PLANE 4 +#define REGTYPE_BLITTER 8 +#define REGTYPE_JOYPORT 16 +#define REGTYPE_DISK 32 +#define REGTYPE_POS 64 +#define REGTYPE_AUDIO 128 + +#define REGTYPE_ALL 255 +/* Always set in regtypes_modified, to enable a forced update when things like + DMACON, BPLCON0, COPJMPx get written. */ +#define REGTYPE_FORCE 256 + + +static unsigned int regtypes[512]; + +static struct copper cop_state; +static int copper_enabled_thisline; +static int cop_min_waittime; + +/* + * Statistics + */ + +/* Used also by bebox.cpp */ +unsigned long int frametime = 0, lastframetime = 0, timeframes = 0, hsync_counter = 0; +unsigned long int idletime; +int bogusframe; + +#if DEBUG_COPPER +/* 10000 isn't enough! */ +#define NR_COPPER_RECORDS 40000 +#else +#define NR_COPPER_RECORDS 1 +#endif + +/* Record copper activity for the debugger. */ +struct cop_record +{ + int hpos, vpos; + uaecptr addr; +}; +static struct cop_record cop_record[2][NR_COPPER_RECORDS]; +static int nr_cop_records[2]; +static int curr_cop_set; + +/* Recording of custom chip register changes. */ +static int current_change_set; + +#ifdef OS_WITHOUT_MEMORY_MANAGEMENT +/* sam: Those arrays uses around 7Mb of BSS... That seems */ +/* too much for AmigaDOS (uae crashes as soon as one loads */ +/* it. So I use a different strategy here (realloc the */ +/* arrays when needed. That strategy might be usefull for */ +/* computer with low memory. */ +struct sprite_entry *sprite_entries[2]; +struct color_change *color_changes[2]; +static int max_sprite_entry = 400; +static int delta_sprite_entry = 0; +static int max_color_change = 400; +static int delta_color_change = 0; +#else +struct sprite_entry sprite_entries[2][MAX_SPR_PIXELS / 16]; +struct color_change color_changes[2][MAX_REG_CHANGE]; +#endif + +struct decision line_decisions[2 * (MAXVPOS + 1) + 1]; +struct draw_info line_drawinfo[2][2 * (MAXVPOS + 1) + 1]; +struct color_entry color_tables[2][(MAXVPOS + 1) * 2]; + +static int next_sprite_entry = 0; +static int prev_next_sprite_entry; +static int next_sprite_forced = 1; + +struct sprite_entry *curr_sprite_entries, *prev_sprite_entries; +struct color_change *curr_color_changes, *prev_color_changes; +struct draw_info *curr_drawinfo, *prev_drawinfo; +struct color_entry *curr_color_tables, *prev_color_tables; + +static int next_color_change; +static int next_color_entry, remembered_color_entry; +static int color_src_match, color_dest_match, color_compare_result; + +static uae_u32 thisline_changed; + +#ifdef SMART_UPDATE +#define MARK_LINE_CHANGED do { thisline_changed = 1; } while (0) +#else +#define MARK_LINE_CHANGED do { ; } while (0) +#endif + +static struct decision thisline_decision; +static int passed_plfstop, fetch_cycle; + +enum fetchstate { + fetch_not_started, + fetch_started, + fetch_was_plane0 +} fetch_state; + +/* + * helper functions + */ + +STATIC_INLINE int nodraw (void) +{ + return !currprefs.cpu_cycle_exact && framecnt != 0; +} + +uae_u32 get_copper_address (int copno) +{ + switch (copno) { + case 1: return cop1lc; + case 2: return cop2lc; + default: return 0; + } +} + +STATIC_INLINE void record_copper (uaecptr addr, int hpos, int vpos) +{ +#if DEBUG_COPPER + int t = nr_cop_records[curr_cop_set]; + if (t < NR_COPPER_RECORDS) { + cop_record[curr_cop_set][t].addr = addr; + cop_record[curr_cop_set][t].hpos = hpos; + cop_record[curr_cop_set][t].vpos = vpos; + nr_cop_records[curr_cop_set] = t + 1; + } +#endif +} + +int find_copper_record (uaecptr addr, int *phpos, int *pvpos) +{ + int s = curr_cop_set ^ 1; + int t = nr_cop_records[s]; + int i; + for (i = 0; i < t; i++) { + if (cop_record[s][i].addr == addr) { + *phpos = cop_record[s][i].hpos; + *pvpos = cop_record[s][i].vpos; + return 1; + } + } + return 0; +} + +int rpt_available = 0; + +void reset_frame_rate_hack (void) +{ + if (currprefs.m68k_speed != -1) + return; + + if (! rpt_available) { + currprefs.m68k_speed = 0; + return; + } + + rpt_did_reset = 1; + is_lastline = 0; + vsyncmintime = read_processor_time() + vsynctime; + write_log ("Resetting frame rate hack\n"); +} + +STATIC_INLINE void setclr (uae_u16 *p, uae_u16 val) +{ + if (val & 0x8000) + *p |= val & 0x7FFF; + else + *p &= ~val; +} + +STATIC_INLINE int current_hpos (void) +{ + return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT; +} + +STATIC_INLINE uae_u8 *pfield_xlateptr (uaecptr plpt, int bytecount) +{ + if (!chipmem_bank.check (plpt, bytecount)) { + static int count = 0; + if (!count) + count++, write_log ("Warning: Bad playfield pointer\n"); + return NULL; + } + return chipmem_bank.xlateaddr (plpt); +} + +STATIC_INLINE void docols (struct color_entry *colentry) +{ + int i; + +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + for (i = 0; i < 256; i++) { + int v = color_reg_get (colentry, i); + if (v < 0 || v > 16777215) + continue; + colentry->acolors[i] = CONVERT_RGB (v); + } + } else { +#endif + for (i = 0; i < 32; i++) { + int v = color_reg_get (colentry, i); + if (v < 0 || v > 4095) + continue; + colentry->acolors[i] = xcolors[v]; + } +#ifdef AGA + } +#endif +} + +void notice_new_xcolors (void) +{ + int i; + + docols(¤t_colors); +/* docols(&colors_for_drawing);*/ + for (i = 0; i < (MAXVPOS + 1)*2; i++) { + docols(color_tables[0]+i); + docols(color_tables[1]+i); + } +} + +static void do_sprites (int currhp); + +static void remember_ctable (void) +{ + if (remembered_color_entry == -1) { + /* The colors changed since we last recorded a color map. Record a + * new one. */ + color_reg_cpy (curr_color_tables + next_color_entry, ¤t_colors); + remembered_color_entry = next_color_entry++; + } + thisline_decision.ctable = remembered_color_entry; + if (color_src_match == -1 || color_dest_match != remembered_color_entry + || line_decisions[next_lineno].ctable != color_src_match) + { + /* The remembered comparison didn't help us - need to compare again. */ + int oldctable = line_decisions[next_lineno].ctable; + int changed = 0; + + if (oldctable == -1) { + changed = 1; + color_src_match = color_dest_match = -1; + } else { + color_compare_result = color_reg_cmp (&prev_color_tables[oldctable], ¤t_colors) != 0; + if (color_compare_result) + changed = 1; + color_src_match = oldctable; + color_dest_match = remembered_color_entry; + } + thisline_changed |= changed; + } else { + /* We know the result of the comparison */ + if (color_compare_result) + thisline_changed = 1; + } +} + +static void remember_ctable_for_border (void) +{ + remember_ctable (); +} + +/* Called to determine the state of the horizontal display window state + * machine at the current position. It might have changed since we last + * checked. */ +static void decide_diw (int hpos) +{ + int pix_hpos = coord_diw_to_window_x (hpos == 227 ? 455 : hpos * 2); /* (227.5*2 = 455) */ + if (hdiwstate == DIW_waiting_start && thisline_decision.diwfirstword == -1 + && pix_hpos >= diwfirstword && last_diw_pix_hpos < diwfirstword) + { + thisline_decision.diwfirstword = diwfirstword < 0 ? 0 : diwfirstword; + hdiwstate = DIW_waiting_stop; + } + if (hdiwstate == DIW_waiting_stop && thisline_decision.diwlastword == -1 + && pix_hpos >= diwlastword && last_diw_pix_hpos < diwlastword) + { + thisline_decision.diwlastword = diwlastword < 0 ? 0 : diwlastword; + hdiwstate = DIW_waiting_start; + } + last_diw_pix_hpos = pix_hpos; +} + +static int fetchmode; +static int maxplanes_ocs[]={ 6,4,0,0 }; +static int maxplanes_ecs[]={ 6,4,2,0 }; +static int maxplanes_aga[]={ 8,4,2,0, 8,8,4,0, 8,8,8,0 }; + +static int get_maxplanes (int res) +{ + int *planes; + if (currprefs.chipset_mask & CSMASK_AGA) + planes = maxplanes_aga; + else if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE)) + planes = maxplanes_ocs; + else + planes = maxplanes_ecs; + return planes[fetchmode * 4 + res]; +} + +/* Disable bitplane DMA if planes > maxplanes. This is needed e.g. by the + Sanity WOC demo (at the "Party Effect"). */ +STATIC_INLINE int GET_PLANES_LIMIT (uae_u16 v) +{ + if (GET_PLANES(v) > get_maxplanes (GET_RES(v))) + v &= ~0x7010; + return GET_PLANES (v); +} + +/* The HRM says 0xD8, but that can't work... */ +#define HARD_DDF_STOP 0xd4 +#define HARD_DDF_START 0x18 + +static void add_modulos (void) +{ + int m1, m2; + + if (fmode & 0x4000) { + if (((diwstrt >> 8) ^ vpos) & 1) + m1 = m2 = bpl2mod; + else + m1 = m2 = bpl1mod; + } else { + m1 = bpl1mod; + m2 = bpl2mod; + } + + switch (GET_PLANES_LIMIT (bplcon0)) { +#ifdef AGA + case 8: bplpt[7] += m2; + case 7: bplpt[6] += m1; +#endif + case 6: bplpt[5] += m2; + case 5: bplpt[4] += m1; + case 4: bplpt[3] += m2; + case 3: bplpt[2] += m1; + case 2: bplpt[1] += m2; + case 1: bplpt[0] += m1; + } +} + +static void finish_playfield_line (void) +{ + /* The latter condition might be able to happen in interlaced frames. */ + if (vpos >= minfirstline && (thisframe_first_drawn_line == -1 || vpos < thisframe_first_drawn_line)) + thisframe_first_drawn_line = vpos; + thisframe_last_drawn_line = vpos; + + /* These are for comparison. */ + thisline_decision.bplcon0 = bplcon0; + thisline_decision.bplcon2 = bplcon2; +#ifdef AGA + thisline_decision.bplcon3 = bplcon3; + thisline_decision.bplcon4 = bplcon4; +#endif + +#ifdef SMART_UPDATE + if (line_decisions[next_lineno].plflinelen != thisline_decision.plflinelen + || line_decisions[next_lineno].plfleft != thisline_decision.plfleft + || line_decisions[next_lineno].bplcon0 != thisline_decision.bplcon0 + || line_decisions[next_lineno].bplcon2 != thisline_decision.bplcon2 +#ifdef AGA + || line_decisions[next_lineno].bplcon3 != thisline_decision.bplcon3 + || line_decisions[next_lineno].bplcon4 != thisline_decision.bplcon4 +#endif + ) +#endif /* SMART_UPDATE */ + thisline_changed = 1; +} + +/* The fetch unit mainly controls ddf stop. It's the number of cycles that + are contained in an indivisible block during which ddf is active. E.g. + if DDF starts at 0x30, and fetchunit is 8, then possible DDF stops are + 0x30 + n * 8. */ +static int fetchunit, fetchunit_mask; +/* The delay before fetching the same bitplane again. Can be larger than + the number of bitplanes; in that case there are additional empty cycles + with no data fetch (this happens for high fetchmodes and low + resolutions). */ +static int fetchstart, fetchstart_shift, fetchstart_mask; +/* fm_maxplane holds the maximum number of planes possible with the current + fetch mode. This selects the cycle diagram: + 8 planes: 73516240 + 4 planes: 3120 + 2 planes: 10. */ +static int fm_maxplane, fm_maxplane_shift; + +/* The corresponding values, by fetchmode and display resolution. */ +static int fetchunits[] = { 8,8,8,0, 16,8,8,0, 32,16,8,0 }; +static int fetchstarts[] = { 3,2,1,0, 4,3,2,0, 5,4,3,0 }; +static int fm_maxplanes[] = { 3,2,1,0, 3,3,2,0, 3,3,3,0 }; + +static uae_u8 cycle_diagram_table[3][3][9][32]; +static uae_u8 cycle_diagram_free_cycles[3][3][9]; +static uae_u8 cycle_diagram_total_cycles[3][3][9]; +static uae_u8 *curr_diagram; +static uae_u8 cycle_sequences[3*8] = { 2,1,2,1,2,1,2,1, 4,2,3,1,4,2,3,1, 8,4,6,2,7,3,5,1 }; + +static void debug_cycle_diagram(void) +{ + int fm, res, planes, cycle, v; + char aa; + + for (fm = 0; fm < 3; fm++) { + write_log ("FMODE %d\n=======\n", fm); + for (res = 0; res <= 2; res++) { + for (planes = 0; planes <= 8; planes++) { + write_log("%d: ",planes); + for (cycle = 0; cycle < 32; cycle++) { + v=cycle_diagram_table[fm][res][planes][cycle]; + if (v==0) aa='-'; else if(v>0) aa='1'; else aa='X'; + write_log("%c",aa); + } + write_log(" %d:%d\n", + cycle_diagram_free_cycles[fm][res][planes], cycle_diagram_total_cycles[fm][res][planes]); + } + write_log("\n"); + } + } + fm=0; +} + +static void create_cycle_diagram_table(void) +{ + int fm, res, cycle, planes, v; + int fetch_start, max_planes, freecycles; + uae_u8 *cycle_sequence; + + for (fm = 0; fm <= 2; fm++) { + for (res = 0; res <= 2; res++) { + max_planes = fm_maxplanes[fm * 4 + res]; + fetch_start = 1 << fetchstarts[fm * 4 + res]; + cycle_sequence = &cycle_sequences[(max_planes - 1) * 8]; + max_planes = 1 << max_planes; + for (planes = 0; planes <= 8; planes++) { + freecycles = 0; + for (cycle = 0; cycle < 32; cycle++) + cycle_diagram_table[fm][res][planes][cycle] = -1; + if (planes <= max_planes) { + for (cycle = 0; cycle < fetch_start; cycle++) { + if (cycle < max_planes && planes >= cycle_sequence[cycle & 7]) { + v = cycle_sequence[cycle & 7]; + } else { + v = 0; + freecycles++; + } + cycle_diagram_table[fm][res][planes][cycle] = v; + } + } + cycle_diagram_free_cycles[fm][res][planes] = freecycles; + cycle_diagram_total_cycles[fm][res][planes] = fetch_start; + } + } + } +#if 0 + debug_cycle_diagram (); +#endif +} + + +/* Used by the copper. */ +static int estimated_last_fetch_cycle; +static int cycle_diagram_shift; + +static void estimate_last_fetch_cycle (int hpos) +{ + int fetchunit = fetchunits[fetchmode * 4 + GET_RES (bplcon0)]; + + if (! passed_plfstop) { + int stop = plfstop < hpos || plfstop > HARD_DDF_STOP ? HARD_DDF_STOP : plfstop; + /* We know that fetching is up-to-date up until hpos, so we can use fetch_cycle. */ + int fetch_cycle_at_stop = fetch_cycle + (stop - hpos); + int starting_last_block_at = (fetch_cycle_at_stop + fetchunit - 1) & ~(fetchunit - 1); + + estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit; + } else { + int starting_last_block_at = (fetch_cycle + fetchunit - 1) & ~(fetchunit - 1); + if (passed_plfstop == 2) + starting_last_block_at -= fetchunit; + + estimated_last_fetch_cycle = hpos + (starting_last_block_at - fetch_cycle) + fetchunit; + } +} + +static uae_u32 outword[MAX_PLANES]; +static int out_nbits, out_offs; +static uae_u32 todisplay[MAX_PLANES][4]; +static uae_u32 fetched[MAX_PLANES]; +#ifdef AGA +static uae_u32 fetched_aga0[MAX_PLANES]; +static uae_u32 fetched_aga1[MAX_PLANES]; +#endif + +/* Expansions from bplcon0/bplcon1. */ +static int toscr_res, toscr_res_first, toscr_nr_planes, fetchwidth; +static int toscr_delay1x, toscr_delay2x, toscr_delay1, toscr_delay2; + +/* The number of bits left from the last fetched words. + This is an optimization - conceptually, we have to make sure the result is + the same as if toscr is called in each clock cycle. However, to speed this + up, we accumulate display data; this variable keeps track of how much. + Thus, once we do call toscr_nbits (which happens at least every 16 bits), + we can do more work at once. */ +static int toscr_nbits; + +static int delayoffset; + +STATIC_INLINE void compute_delay_offset (void) +{ + delayoffset = (((plfstrt - HARD_DDF_START) & fetchstart_mask) << 1) & ~7; + if (delayoffset == 8) + delayoffset = 8; + else if (delayoffset == 16) /* Overkill AGA */ + delayoffset = 48; + else if (delayoffset == 24) /* AB 2 */ + delayoffset = 8; + else if (delayoffset == 32) + delayoffset = 32; + else if (delayoffset == 48) /* Pinball Illusions AGA, ingame */ + delayoffset = 16; + else /* what about 40 and 56? */ + delayoffset = 0; +} + +static void expand_fmodes (void) +{ + int res = GET_RES(bplcon0); + int fm = fetchmode; + fetchunit = fetchunits[fm * 4 + res]; + fetchunit_mask = fetchunit - 1; + fetchstart_shift = fetchstarts[fm * 4 + res]; + fetchstart = 1 << fetchstart_shift; + fetchstart_mask = fetchstart - 1; + fm_maxplane_shift = fm_maxplanes[fm * 4 + res]; + fm_maxplane = 1 << fm_maxplane_shift; + curr_diagram = cycle_diagram_table[fm][res][GET_PLANES_LIMIT (bplcon0)]; +} + +/* Expand bplcon0/bplcon1 into the toscr_xxx variables. */ +static void compute_toscr_delay_1 (void) +{ + int delay1 = (bplcon1 & 0x0f) | ((bplcon1 & 0x0c00) >> 6); + int delay2 = ((bplcon1 >> 4) & 0x0f) | (((bplcon1 >> 4) & 0x0c00) >> 6); + int delaymask; + int fetchwidth = 16 << fetchmode; + + delay1 += delayoffset; + delay2 += delayoffset; + delaymask = (fetchwidth - 1) >> toscr_res; + toscr_delay1x = (delay1 & delaymask) << toscr_res; + toscr_delay2x = (delay2 & delaymask) << toscr_res; +} + +static void compute_toscr_delay (int hpos) +{ + toscr_res = GET_RES (bplcon0); + toscr_nr_planes = GET_PLANES_LIMIT (bplcon0); + compute_toscr_delay_1 (); +} + +STATIC_INLINE void maybe_first_bpl1dat (int hpos) +{ + if (thisline_decision.plfleft == -1) { + thisline_decision.plfleft = hpos; + compute_delay_offset (); + compute_toscr_delay_1 (); + } +} + +STATIC_INLINE void fetch (int nr, int fm) +{ + uaecptr p; + if (nr >= toscr_nr_planes) + return; + p = bplpt[nr] + bpl_off[nr]; + switch (fm) { + case 0: + fetched[nr] = last_custom_value = chipmem_agnus_wget (p); + bplpt[nr] += 2; + break; +#ifdef AGA + case 1: + fetched_aga0[nr] = chipmem_lget (p); + last_custom_value = (uae_u16)fetched_aga0[nr]; + bplpt[nr] += 4; + break; + case 2: + fetched_aga1[nr] = chipmem_lget (p); + fetched_aga0[nr] = chipmem_lget (p + 4); + last_custom_value = (uae_u16)fetched_aga0[nr]; + bplpt[nr] += 8; + break; +#endif + } + if (passed_plfstop == 2 && fetch_cycle >= (fetch_cycle & ~fetchunit_mask) + fetchunit - fetchstart) { + int mod; + if (fmode & 0x4000) { + if (((diwstrt >> 8) ^ vpos) & 1) + mod = bpl2mod; + else + mod = bpl1mod; + } else if (nr & 1) + mod = bpl2mod; + else + mod = bpl1mod; + bplpt[nr] += mod; + } + if (nr == 0) + fetch_state = fetch_was_plane0; +} + +static void clear_fetchbuffer (uae_u32 *ptr, int nwords) +{ + int i; + + if (! thisline_changed) + for (i = 0; i < nwords; i++) + if (ptr[i]) { + thisline_changed = 1; + break; + } + + memset (ptr, 0, nwords * 4); +} + +static void update_toscr_planes (void) +{ + if (toscr_nr_planes > thisline_decision.nr_planes) { + int j; + for (j = thisline_decision.nr_planes; j < toscr_nr_planes; j++) + clear_fetchbuffer ((uae_u32 *)(line_data[next_lineno] + 2 * MAX_WORDS_PER_LINE * j), out_offs); +#if 0 + if (thisline_decision.nr_planes > 0) + printf ("Planes from %d to %d\n", thisline_decision.nr_planes, toscr_nr_planes); +#endif + thisline_decision.nr_planes = toscr_nr_planes; + } +} + +STATIC_INLINE void toscr_3_ecs (int nbits) +{ + int delay1 = toscr_delay1; + int delay2 = toscr_delay2; + int i; + uae_u32 mask = 0xFFFF >> (16 - nbits); + + for (i = 0; i < toscr_nr_planes; i += 2) { + outword[i] <<= nbits; + outword[i] |= (todisplay[i][0] >> (16 - nbits + delay1)) & mask; + todisplay[i][0] <<= nbits; + } + for (i = 1; i < toscr_nr_planes; i += 2) { + outword[i] <<= nbits; + outword[i] |= (todisplay[i][0] >> (16 - nbits + delay2)) & mask; + todisplay[i][0] <<= nbits; + } +} + +STATIC_INLINE void shift32plus (uae_u32 *p, int n) +{ + uae_u32 t = p[1]; + t <<= n; + t |= p[0] >> (32 - n); + p[1] = t; +} + +#ifdef AGA +STATIC_INLINE void aga_shift (uae_u32 *p, int n, int fm) +{ + if (fm == 2) { + shift32plus (p + 2, n); + shift32plus (p + 1, n); + } + shift32plus (p + 0, n); + p[0] <<= n; +} + +STATIC_INLINE void toscr_3_aga (int nbits, int fm) +{ + int delay1 = toscr_delay1; + int delay2 = toscr_delay2; + int i; + uae_u32 mask = 0xFFFF >> (16 - nbits); + + { + int offs = (16 << fm) - nbits + delay1; + int off1 = offs >> 5; + if (off1 == 3) + off1 = 2; + offs -= off1 * 32; + for (i = 0; i < toscr_nr_planes; i += 2) { + uae_u32 t0 = todisplay[i][off1]; + uae_u32 t1 = todisplay[i][off1 + 1]; + uae_u64 t = (((uae_u64)t1) << 32) | t0; + outword[i] <<= nbits; + outword[i] |= (t >> offs) & mask; + aga_shift (todisplay[i], nbits, fm); + } + } + { + int offs = (16 << fm) - nbits + delay2; + int off1 = offs >> 5; + if (off1 == 3) + off1 = 2; + offs -= off1 * 32; + for (i = 1; i < toscr_nr_planes; i += 2) { + uae_u32 t0 = todisplay[i][off1]; + uae_u32 t1 = todisplay[i][off1 + 1]; + uae_u64 t = (((uae_u64)t1) << 32) | t0; + outword[i] <<= nbits; + outword[i] |= (t >> offs) & mask; + aga_shift (todisplay[i], nbits, fm); + } + } +} + +#endif + +static void toscr_2_0 (int nbits) { toscr_3_ecs (nbits); } +#ifdef AGA +static void toscr_2_1 (int nbits) { toscr_3_aga (nbits, 1); } +static void toscr_2_2 (int nbits) { toscr_3_aga (nbits, 2); } +#endif + +STATIC_INLINE void toscr_1 (int nbits, int fm) +{ + switch (fm) { + case 0: + toscr_2_0 (nbits); + break; +#ifdef AGA + case 1: + toscr_2_1 (nbits); + break; + case 2: + toscr_2_2 (nbits); + break; +#endif + } + out_nbits += nbits; + if (out_nbits == 32) { + int i; + uae_u8 *dataptr = line_data[next_lineno] + out_offs * 4; + for (i = 0; i < thisline_decision.nr_planes; i++) { + uae_u32 *dataptr32 = (uae_u32 *)dataptr; + if (i >= toscr_nr_planes) + outword[i] = 0; + if (*dataptr32 != outword[i]) + thisline_changed = 1; + *dataptr32 = outword[i]; + dataptr += MAX_WORDS_PER_LINE * 2; + } + out_offs++; + out_nbits = 0; + } +} + +static void toscr_fm0 (int); +static void toscr_fm1 (int); +static void toscr_fm2 (int); + +STATIC_INLINE void toscr (int nbits, int fm) +{ + switch (fm) { + case 0: toscr_fm0 (nbits); break; +#ifdef AGA + case 1: toscr_fm1 (nbits); break; + case 2: toscr_fm2 (nbits); break; +#endif + } +} + +STATIC_INLINE void toscr_0 (int nbits, int fm) +{ + int t; + + if (nbits > 16) { + toscr (16, fm); + nbits -= 16; + } + + t = 32 - out_nbits; + if (t < nbits) { + toscr_1 (t, fm); + nbits -= t; + } + toscr_1 (nbits, fm); +} + +static void toscr_fm0 (int nbits) { toscr_0 (nbits, 0); } +static void toscr_fm1 (int nbits) { toscr_0 (nbits, 1); } +static void toscr_fm2 (int nbits) { toscr_0 (nbits, 2); } + +static int flush_plane_data (int fm) +{ + int i = 0; + int fetchwidth = 16 << fm; + + if (out_nbits <= 16) { + i += 16; + toscr_1 (16, fm); + } + if (out_nbits != 0) { + i += 32 - out_nbits; + toscr_1 (32 - out_nbits, fm); + } + i += 32; + + toscr_1 (16, fm); + toscr_1 (16, fm); + return i >> (1 + toscr_res); +} + +STATIC_INLINE void flush_display (int fm) +{ + if (toscr_nbits > 0 && thisline_decision.plfleft != -1) + toscr (toscr_nbits, fm); + toscr_nbits = 0; +} + +/* Called when all planes have been fetched, i.e. when a new block + of data is available to be displayed. The data in fetched[] is + moved into todisplay[]. */ +STATIC_INLINE void beginning_of_plane_block (int pos, int fm) +{ + int i; + + flush_display (fm); + if (fm == 0) + for (i = 0; i < MAX_PLANES; i++) + todisplay[i][0] |= fetched[i]; +#ifdef AGA + else + for (i = 0; i < MAX_PLANES; i++) { + if (fm == 2) + todisplay[i][1] = fetched_aga1[i]; + todisplay[i][0] = fetched_aga0[i]; + } +#endif + maybe_first_bpl1dat (pos); + toscr_delay1 = toscr_delay1x; + toscr_delay2 = toscr_delay2x; +} + +#ifdef SPEEDUP + +/* The usual inlining tricks - don't touch unless you know what you are doing. */ +STATIC_INLINE void long_fetch_ecs (int plane, int nwords, int weird_number_of_bits, int dma) +{ + uae_u16 *real_pt = (uae_u16 *)pfield_xlateptr (bplpt[plane] + bpl_off[plane], nwords * 2); + int delay = (plane & 1) ? toscr_delay2 : toscr_delay1; + int tmp_nbits = out_nbits; + uae_u32 shiftbuffer = todisplay[plane][0]; + uae_u32 outval = outword[plane]; + uae_u32 fetchval = fetched[plane]; + uae_u32 *dataptr = (uae_u32 *)(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs); + + if (dma) + bplpt[plane] += nwords * 2; + + if (real_pt == 0) + /* @@@ Don't do this, fall back on chipmem_wget instead. */ + return; + + while (nwords > 0) { + int bits_left = 32 - tmp_nbits; + uae_u32 t; + + shiftbuffer |= fetchval; + + t = (shiftbuffer >> delay) & 0xFFFF; + + if (weird_number_of_bits && bits_left < 16) { + outval <<= bits_left; + outval |= t >> (16 - bits_left); + thisline_changed |= *dataptr ^ outval; + *dataptr++ = outval; + + outval = t; + tmp_nbits = 16 - bits_left; + shiftbuffer <<= 16; + } else { + outval = (outval << 16) | t; + shiftbuffer <<= 16; + tmp_nbits += 16; + if (tmp_nbits == 32) { + thisline_changed |= *dataptr ^ outval; + *dataptr++ = outval; + tmp_nbits = 0; + } + } + nwords--; + if (dma) { + fetchval = do_get_mem_word (real_pt); + real_pt++; + } + } + fetched[plane] = fetchval; + todisplay[plane][0] = shiftbuffer; + outword[plane] = outval; +} + +#ifdef AGA +STATIC_INLINE void long_fetch_aga (int plane, int nwords, int weird_number_of_bits, int fm, int dma) +{ + uae_u32 *real_pt = (uae_u32 *)pfield_xlateptr (bplpt[plane] + bpl_off[plane], nwords * 2); + int delay = (plane & 1) ? toscr_delay2 : toscr_delay1; + int tmp_nbits = out_nbits; + uae_u32 *shiftbuffer = todisplay[plane]; + uae_u32 outval = outword[plane]; + uae_u32 fetchval0 = fetched_aga0[plane]; + uae_u32 fetchval1 = fetched_aga1[plane]; + uae_u32 *dataptr = (uae_u32 *)(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs); + int offs = (16 << fm) - 16 + delay; + int off1 = offs >> 5; + if (off1 == 3) + off1 = 2; + offs -= off1 * 32; + + if (dma) + bplpt[plane] += nwords * 2; + + if (real_pt == 0) + /* @@@ Don't do this, fall back on chipmem_wget instead. */ + return; + + while (nwords > 0) { + int i; + + shiftbuffer[0] = fetchval0; + if (fm == 2) + shiftbuffer[1] = fetchval1; + + for (i = 0; i < (1 << fm); i++) { + int bits_left = 32 - tmp_nbits; + + uae_u32 t0 = shiftbuffer[off1]; + uae_u32 t1 = shiftbuffer[off1 + 1]; + uae_u64 t = (((uae_u64)t1) << 32) | t0; + + t0 = (uae_u32)((t >> offs) & 0xFFFF); + + if (weird_number_of_bits && bits_left < 16) { + outval <<= bits_left; + outval |= t0 >> (16 - bits_left); + + thisline_changed |= *dataptr ^ outval; + *dataptr++ = outval; + + outval = t0; + tmp_nbits = 16 - bits_left; + aga_shift (shiftbuffer, 16, fm); + } else { + outval = (outval << 16) | t0; + aga_shift (shiftbuffer, 16, fm); + tmp_nbits += 16; + if (tmp_nbits == 32) { + thisline_changed |= *dataptr ^ outval; + *dataptr++ = outval; + tmp_nbits = 0; + } + } + } + + nwords -= 1 << fm; + + if (dma) { + if (fm == 1) + fetchval0 = do_get_mem_long (real_pt); + else { + fetchval1 = do_get_mem_long (real_pt); + fetchval0 = do_get_mem_long (real_pt + 1); + } + real_pt += fm; + } + } + fetched_aga0[plane] = fetchval0; + fetched_aga1[plane] = fetchval1; + outword[plane] = outval; +} +#endif + +static void long_fetch_ecs_0 (int hpos, int nwords, int dma) { long_fetch_ecs (hpos, nwords, 0, dma); } +static void long_fetch_ecs_1 (int hpos, int nwords, int dma) { long_fetch_ecs (hpos, nwords, 1, dma); } +#ifdef AGA +static void long_fetch_aga_1_0 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords, 0, 1, dma); } +static void long_fetch_aga_1_1 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords, 1, 1, dma); } +static void long_fetch_aga_2_0 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords, 0, 2, dma); } +static void long_fetch_aga_2_1 (int hpos, int nwords, int dma) { long_fetch_aga (hpos, nwords, 1, 2, dma); } +#endif + +static void do_long_fetch (int hpos, int nwords, int dma, int fm) +{ + int i; + + flush_display (fm); + switch (fm) { + case 0: + if (out_nbits & 15) { + for (i = 0; i < toscr_nr_planes; i++) + long_fetch_ecs_1 (i, nwords, dma); + } else { + for (i = 0; i < toscr_nr_planes; i++) + long_fetch_ecs_0 (i, nwords, dma); + } + break; +#ifdef AGA + case 1: + if (out_nbits & 15) { + for (i = 0; i < toscr_nr_planes; i++) + long_fetch_aga_1_1 (i, nwords, dma); + } else { + for (i = 0; i < toscr_nr_planes; i++) + long_fetch_aga_1_0 (i, nwords, dma); + } + break; + case 2: + if (out_nbits & 15) { + for (i = 0; i < toscr_nr_planes; i++) + long_fetch_aga_2_1 (i, nwords, dma); + } else { + for (i = 0; i < toscr_nr_planes; i++) + long_fetch_aga_2_0 (i, nwords, dma); + } + break; +#endif + } + + out_nbits += nwords * 16; + out_offs += out_nbits >> 5; + out_nbits &= 31; + + if (dma && toscr_nr_planes > 0) + fetch_state = fetch_was_plane0; +} + +#endif + +/* make sure fetch that goes beyond maxhpos is finished */ +static void finish_final_fetch (int i, int fm) +{ + if (thisline_decision.plfleft == -1) + return; + if (passed_plfstop == 3) + return; + passed_plfstop = 3; + ddfstate = DIW_waiting_start; + i += flush_plane_data (fm); + thisline_decision.plfright = i; + thisline_decision.plflinelen = out_offs; + thisline_decision.bplres = toscr_res_first; + finish_playfield_line (); +} + +STATIC_INLINE int one_fetch_cycle_0 (int i, int ddfstop_to_test, int dma, int fm) +{ + if (! passed_plfstop && i == ddfstop_to_test) + passed_plfstop = 1; + + if ((fetch_cycle & fetchunit_mask) == 0) { + if (passed_plfstop == 2) { + finish_final_fetch (i, fm); + return 1; + } + if (passed_plfstop) + passed_plfstop++; + } + + if (dma) { + /* fetchstart_mask can be larger than fm_maxplane if FMODE > 0. This means + that the remaining cycles are idle; we'll fall through the whole switch + without doing anything. */ + int cycle_start = fetch_cycle & fetchstart_mask; + switch (fm_maxplane) { + case 8: + switch (cycle_start) { + case 0: fetch (7, fm); break; + case 1: fetch (3, fm); break; + case 2: fetch (5, fm); break; + case 3: fetch (1, fm); break; + case 4: fetch (6, fm); break; + case 5: fetch (2, fm); break; + case 6: fetch (4, fm); break; + case 7: fetch (0, fm); break; + } + break; + case 4: + switch (cycle_start) { + case 0: fetch (3, fm); break; + case 1: fetch (1, fm); break; + case 2: fetch (2, fm); break; + case 3: fetch (0, fm); break; + } + break; + case 2: + switch (cycle_start) { + case 0: fetch (1, fm); break; + case 1: fetch (0, fm); break; + } + break; + } + } + fetch_cycle++; + toscr_nbits += 2 << toscr_res; + + if (toscr_nbits == 16) + flush_display (fm); + if (toscr_nbits > 16) + uae_abort ("toscr_nbits > 16 (%d)", toscr_nbits); + + return 0; +} + +static int one_fetch_cycle_fm0 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 0); } +static int one_fetch_cycle_fm1 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 1); } +static int one_fetch_cycle_fm2 (int i, int ddfstop_to_test, int dma) { return one_fetch_cycle_0 (i, ddfstop_to_test, dma, 2); } + +STATIC_INLINE int one_fetch_cycle (int i, int ddfstop_to_test, int dma, int fm) +{ + switch (fm) { + case 0: return one_fetch_cycle_fm0 (i, ddfstop_to_test, dma); +#ifdef AGA + case 1: return one_fetch_cycle_fm1 (i, ddfstop_to_test, dma); + case 2: return one_fetch_cycle_fm2 (i, ddfstop_to_test, dma); +#endif + default: uae_abort ("fm corrupt"); return 0; + } +} + +STATIC_INLINE void update_fetch (int until, int fm) +{ + int pos; + int dma = dmaen (DMA_BITPLANE); + + int ddfstop_to_test; + + if (nodraw() || passed_plfstop == 3) + return; + + /* We need an explicit test against HARD_DDF_STOP here to guard against + programs that move the DDFSTOP before our current position before we + reach it. */ + ddfstop_to_test = HARD_DDF_STOP; + if (ddfstop >= last_fetch_hpos && plfstop < ddfstop_to_test) + ddfstop_to_test = plfstop; + + compute_toscr_delay (last_fetch_hpos); + update_toscr_planes (); + + pos = last_fetch_hpos; + cycle_diagram_shift = last_fetch_hpos - fetch_cycle; + + /* First, a loop that prepares us for the speedup code. We want to enter + the SPEEDUP case with fetch_state == fetch_was_plane0, and then unroll + whole blocks, so that we end on the same fetch_state again. */ + for (; ; pos++) { + if (pos == until) { + if (until >= maxhpos) { + finish_final_fetch (pos, fm); + return; + } + flush_display (fm); + return; + } + + if (fetch_state == fetch_was_plane0) + break; + + fetch_state = fetch_started; + if (one_fetch_cycle (pos, ddfstop_to_test, dma, fm)) + return; + } + +#ifdef SPEEDUP + /* Unrolled version of the for loop below. */ + if (! passed_plfstop && ddf_change != vpos && ddf_change + 1 != vpos + && dma + && (fetch_cycle & fetchstart_mask) == (fm_maxplane & fetchstart_mask) + && toscr_delay1 == toscr_delay1x && toscr_delay2 == toscr_delay2x + # if 0 + /* @@@ We handle this case, but the code would be simpler if we + * disallowed it - it may even be possible to guarantee that + * this condition never is false. Later. */ + && (out_nbits & 15) == 0 +# endif + && toscr_nr_planes == thisline_decision.nr_planes) + { + int offs = (pos - fetch_cycle) & fetchunit_mask; + int ddf2 = ((ddfstop_to_test - offs + fetchunit - 1) & ~fetchunit_mask) + offs; + int ddf3 = ddf2 + fetchunit; + int stop = until < ddf2 ? until : until < ddf3 ? ddf2 : ddf3; + int count; + + count = stop - pos; + + if (count >= fetchstart) { + count &= ~fetchstart_mask; + + if (thisline_decision.plfleft == -1) { + compute_delay_offset (); + compute_toscr_delay_1 (); + } + + do_long_fetch (pos, count >> (3 - toscr_res), dma, fm); + + /* This must come _after_ do_long_fetch so as not to confuse flush_display + into thinking the first fetch has produced any output worth emitting to + the screen. But the calculation of delay_offset must happen _before_. */ + maybe_first_bpl1dat (pos); + + if (pos <= ddfstop_to_test && pos + count > ddfstop_to_test) + passed_plfstop = 1; + if (pos <= ddfstop_to_test && pos + count > ddf2) + passed_plfstop = 2; + if (pos <= ddf2 && pos + count >= ddf2 + fm_maxplane) + add_modulos (); + pos += count; + fetch_cycle += count; + } + } else { +#endif + //maybe_first_bpl1dat (pos); +#ifdef SPEEDUP + } +#endif + for (; pos < until; pos++) { + if (fetch_state == fetch_was_plane0) + beginning_of_plane_block (pos, fm); + fetch_state = fetch_started; + + if (one_fetch_cycle (pos, ddfstop_to_test, dma, fm)) + return; + } + if (until >= maxhpos) { + finish_final_fetch (pos, fm); + return; + } + flush_display (fm); +} + +static void update_fetch_0 (int hpos) { update_fetch (hpos, 0); } +static void update_fetch_1 (int hpos) { update_fetch (hpos, 1); } +static void update_fetch_2 (int hpos) { update_fetch (hpos, 2); } + +STATIC_INLINE void decide_fetch (int hpos) +{ + if (fetch_state != fetch_not_started && hpos > last_fetch_hpos) { + switch (fetchmode) { + case 0: update_fetch_0 (hpos); break; +#ifdef AGA + case 1: update_fetch_1 (hpos); break; + case 2: update_fetch_2 (hpos); break; +#endif + default: uae_abort ("fetchmode corrupt"); + } + } + last_fetch_hpos = hpos; +} + +static void start_bpl_dma (int hpos, int hstart) +{ + fetch_state = fetch_started; + fetch_cycle = 0; + last_fetch_hpos = hstart; + out_nbits = 0; + out_offs = 0; + toscr_nbits = 0; + toscr_res_first = GET_RES (bplcon0); + + ddfstate = DIW_waiting_stop; + compute_toscr_delay (last_fetch_hpos); + + /* If someone already wrote BPL1DAT, clear the area between that point and + the real fetch start. */ + if (!nodraw ()) { + if (thisline_decision.plfleft != -1) { + out_nbits = (plfstrt - thisline_decision.plfleft) << (1 + toscr_res); + out_offs = out_nbits >> 5; + out_nbits &= 31; + } + update_toscr_planes (); + } +} + +/* this may turn on datafetch if program turns dma on during the ddf */ +static void maybe_start_bpl_dma (int hpos) +{ + /* OCS: BPL DMA never restarts if DMA is turned on during DDF + * ECS/AGA: BPL DMA restarts but only if DMA was turned off + outside of DDF or during current line, otherwise display + processing jumps immediately to "DDFSTOP passed"-condition */ + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + return; + if (fetch_state != fetch_not_started) + return; + if (diwstate != DIW_waiting_stop) + return; + if (hpos <= plfstrt) + return; + if (hpos > plfstop) + return; + if (ddfstate != DIW_waiting_start) + passed_plfstop = 1; + start_bpl_dma (hpos, hpos); +} + +/* This function is responsible for turning on datafetch if necessary. */ +STATIC_INLINE void decide_line (int hpos) +{ + /* Take care of the vertical DIW. */ + if (vpos == plffirstline) + diwstate = DIW_waiting_stop; + if (vpos == plflastline) + diwstate = DIW_waiting_start; + + if (hpos <= last_decide_line_hpos) + return; + if (fetch_state != fetch_not_started) + return; + + if (dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) { + int ok = 0; + /* Test if we passed the start of the DDF window. */ + if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { + ok = 1; + /* hack warning.. Writing to DDFSTRT when DMA should start must be ignored + * (correct fix would be emulate this delay for every custom register, but why bother..) */ + if (hpos - 2 == ddfstrt_old_hpos && ddfstrt_old_vpos == vpos) + ok = 0; + if (ok) { + start_bpl_dma (hpos, plfstrt); + estimate_last_fetch_cycle (plfstrt); + last_decide_line_hpos = hpos; +#ifndef CUSTOM_SIMPLE + do_sprites (plfstrt); +#endif + return; + } + } + } + +#ifndef CUSTOM_SIMPLE + if (last_sprite_decide_line_hpos < SPR0_HPOS + 4 * MAX_SPRITES) + do_sprites (hpos); +#endif + last_sprite_decide_line_hpos = hpos; + + last_decide_line_hpos = hpos; +} + +/* Called when a color is about to be changed (write to a color register), + * but the new color has not been entered into the table yet. */ +static void record_color_change (int hpos, int regno, unsigned long value) +{ + if (regno == -1 && value) { + thisline_decision.ham_seen = 1; + if (hpos < HARD_DDF_START) + thisline_decision.ham_at_start = 1; + } + + /* Early positions don't appear on-screen. */ + if (nodraw () || vpos < minfirstline || hpos < HARD_DDF_START + /*|| currprefs.emul_accuracy == 0*/) + return; + + decide_diw (hpos); + decide_line (hpos); + + if (thisline_decision.ctable == -1) + remember_ctable (); + +#ifdef OS_WITHOUT_MEMORY_MANAGEMENT + if (next_color_change >= max_color_change) { + ++delta_color_change; + return; + } +#endif + curr_color_changes[next_color_change].linepos = hpos; + curr_color_changes[next_color_change].regno = regno; + curr_color_changes[next_color_change++].value = value; +} + +typedef int sprbuf_res_t, cclockres_t, hwres_t, bplres_t; + +/* handle very rarely needed playfield collision (CLXDAT bit 0) */ +static void do_playfield_collisions (void) +{ + int bplres = GET_RES (bplcon0); + hwres_t ddf_left = thisline_decision.plfleft * 2 << bplres; + hwres_t hw_diwlast = coord_window_to_diw_x (thisline_decision.diwlastword); + hwres_t hw_diwfirst = coord_window_to_diw_x (thisline_decision.diwfirstword); + int i, collided, minpos, maxpos; +#ifdef AGA + int planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6; +#else + int planes = 6; +#endif + + if (clxcon_bpl_enable == 0) { + clxdat |= 1; + return; + } + if (clxdat & 1) + return; + + collided = 0; + minpos = thisline_decision.plfleft * 2; + if (minpos < hw_diwfirst) + minpos = hw_diwfirst; + maxpos = thisline_decision.plfright * 2; + if (maxpos > hw_diwlast) + maxpos = hw_diwlast; + for (i = minpos; i < maxpos && !collided; i+= 32) { + int offs = ((i << bplres) - ddf_left) >> 3; + int j; + uae_u32 total = 0xffffffff; + for (j = 0; j < planes; j++) { + int ena = (clxcon_bpl_enable >> j) & 1; + int match = (clxcon_bpl_match >> j) & 1; + uae_u32 t = 0xffffffff; + if (ena) { + if (j < thisline_decision.nr_planes) { + t = *(uae_u32 *)(line_data[next_lineno] + offs + 2 * j * MAX_WORDS_PER_LINE); + t ^= (match & 1) - 1; + } else { + t = (match & 1) - 1; + } + } + total &= t; + } + if (total) { + collided = 1; +#if 0 + { + int k; + for (k = 0; k < 1; k++) { + uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + offs + 2 * k * MAX_WORDS_PER_LINE); + *ldata ^= 0x5555555555; + } + } +#endif + + } + } + if (collided) + clxdat |= 1; +} + +/* Sprite-to-sprite collisions are taken care of in record_sprite. This one does + playfield/sprite collisions. */ +static void do_sprite_collisions (void) +{ + int nr_sprites = curr_drawinfo[next_lineno].nr_sprites; + int first = curr_drawinfo[next_lineno].first_sprite_entry; + int i; + unsigned int collision_mask = clxmask[clxcon >> 12]; + int bplres = GET_RES (bplcon0); + hwres_t ddf_left = thisline_decision.plfleft * 2 << bplres; + hwres_t hw_diwlast = coord_window_to_diw_x (thisline_decision.diwlastword); + hwres_t hw_diwfirst = coord_window_to_diw_x (thisline_decision.diwfirstword); + + if (clxcon_bpl_enable == 0) { + clxdat |= 0x1FE; + return; + } + + for (i = 0; i < nr_sprites; i++) { + struct sprite_entry *e = curr_sprite_entries + first + i; + sprbuf_res_t j; + sprbuf_res_t minpos = e->pos; + sprbuf_res_t maxpos = e->max; + hwres_t minp1 = minpos >> sprite_buffer_res; + hwres_t maxp1 = maxpos >> sprite_buffer_res; + + if (maxp1 > hw_diwlast) + maxpos = hw_diwlast << sprite_buffer_res; + if (maxp1 > thisline_decision.plfright * 2) + maxpos = thisline_decision.plfright * 2 << sprite_buffer_res; + if (minp1 < hw_diwfirst) + minpos = hw_diwfirst << sprite_buffer_res; + if (minp1 < thisline_decision.plfleft * 2) + minpos = thisline_decision.plfleft * 2 << sprite_buffer_res; + + for (j = minpos; j < maxpos; j++) { + int sprpix = spixels[e->first_pixel + j - e->pos] & collision_mask; + int k, offs, match = 1; + + if (sprpix == 0) + continue; + + offs = ((j << bplres) >> sprite_buffer_res) - ddf_left; + sprpix = sprite_ab_merge[sprpix & 255] | (sprite_ab_merge[sprpix >> 8] << 2); + sprpix <<= 1; + + /* Loop over number of playfields. */ + for (k = 1; k >= 0; k--) { + int l; +#ifdef AGA + int planes = (currprefs.chipset_mask & CSMASK_AGA) ? 8 : 6; +#else + int planes = 6; +#endif + if (bplcon0 & 0x400) + match = 1; + for (l = k; match && l < planes; l += 2) { + int t = 0; + if (l < thisline_decision.nr_planes) { + uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE); + uae_u32 word = ldata[offs >> 5]; + t = (word >> (31 - (offs & 31))) & 1; +#if 0 /* debug: draw collision mask */ + if (1) { + int m; + for (m = 0; m < 5; m++) { + ldata = (uae_u32 *)(line_data[next_lineno] + 2 * m * MAX_WORDS_PER_LINE); + ldata[(offs >> 5) + 1] |= 15 << (31 - (offs & 31)); + } + } +#endif + } + if (clxcon_bpl_enable & (1 << l)) { + if (t != ((clxcon_bpl_match >> l) & 1)) + match = 0; + } + } + if (match) { +#if 0 /* debug: mark lines where collisions are detected */ + if (0) { + int l; + for (l = 0; l < 5; l++) { + uae_u32 *ldata = (uae_u32 *)(line_data[next_lineno] + 2 * l * MAX_WORDS_PER_LINE); + ldata[(offs >> 5) + 1] |= 15 << (31 - (offs & 31)); + } + } +#endif + clxdat |= sprpix << (k * 4); + } + } + } + } +#if 0 + { + static int olx; + if (clxdat != olx) + write_log ("%d: %04.4X\n", vpos, clxdat); + olx = clxdat; + } +#endif +} + +static void expand_sprres (void) +{ + switch ((bplcon3 >> 6) & 3) { + case 0: /* ECS defaults (LORES,HIRES=140ns,SHRES=70ns) */ + if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && GET_RES (bplcon0) == RES_SUPERHIRES) + sprres = RES_HIRES; + else + sprres = RES_LORES; + break; + case 1: + sprres = RES_LORES; + break; + case 2: + sprres = RES_HIRES; + break; + case 3: + sprres = RES_SUPERHIRES; + break; + } +} + +STATIC_INLINE void record_sprite_1 (uae_u16 *buf, uae_u32 datab, int num, int dbl, + unsigned int mask, int do_collisions, uae_u32 collision_mask) +{ + int j = 0; + while (datab) { + unsigned int tmp = *buf; + unsigned int col = (datab & 3) << (2 * num); + tmp |= col; + if ((j & mask) == 0) + *buf++ = tmp; + if (dbl) + *buf++ = tmp; + j++; + datab >>= 2; + if (do_collisions) { + tmp &= collision_mask; + if (tmp) { + unsigned int shrunk_tmp = sprite_ab_merge[tmp & 255] | (sprite_ab_merge[tmp >> 8] << 2); + clxdat |= sprclx[shrunk_tmp]; + } + } + } +} + +/* DATAB contains the sprite data; 16 pixels in two-bit packets. Bits 0/1 + determine the color of the leftmost pixel, bits 2/3 the color of the next + etc. + This function assumes that for all sprites in a given line, SPRXP either + stays equal or increases between successive calls. + + The data is recorded either in lores pixels (if ECS), or in hires pixels + (if AGA). No support for SHRES sprites. */ + +static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 *datb, unsigned int ctl) +{ + struct sprite_entry *e = curr_sprite_entries + next_sprite_entry; + int i; + int word_offs; + uae_u16 *buf; + uae_u32 collision_mask; + int width = sprite_width; + int dbl = 0, half = 0; + unsigned int mask = 0; + + if (sprres != RES_LORES) + thisline_decision.any_hires_sprites = 1; + +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + width = (width << 1) >> sprres; + dbl = sprite_buffer_res - sprres; + if (dbl < 0) { + half = -dbl; + dbl = 0; + } + mask = sprres == RES_SUPERHIRES ? 1 : 0; + } +#endif + + /* Try to coalesce entries if they aren't too far apart. */ + if (! next_sprite_forced && e[-1].max + 16 >= sprxp) { + e--; + } else { + next_sprite_entry++; + e->pos = sprxp; + e->has_attached = 0; + } + + if (sprxp < e->pos) + uae_abort ("sprxp < e->pos"); + + e->max = sprxp + width; + e[1].first_pixel = e->first_pixel + ((e->max - e->pos + 3) & ~3); + next_sprite_forced = 0; + + collision_mask = clxmask[clxcon >> 12]; + word_offs = e->first_pixel + sprxp - e->pos; + + for (i = 0; i < sprite_width; i += 16) { + unsigned int da = *data; + unsigned int db = *datb; + uae_u32 datab = ((sprtaba[da & 0xFF] << 16) | sprtaba[da >> 8] + | (sprtabb[db & 0xFF] << 16) | sprtabb[db >> 8]); + + buf = spixels + word_offs + ((i << dbl) >> half); + if (currprefs.collision_level > 0 && collision_mask) + record_sprite_1 (buf, datab, num, dbl, mask, 1, collision_mask); + else + record_sprite_1 (buf, datab, num, dbl, mask, 0, collision_mask); + data++; + datb++; + } + + /* We have 8 bits per pixel in spixstate, two for every sprite pair. The + low order bit records whether the attach bit was set for this pair. */ + + if ((sprctl[num] & 0x80) || (sprctl[num ^ 1] & 0x80)) { +// if (ctl & 0x80) { + uae_u32 state = 0x01010101 << (num & ~1); + uae_u32 *stbuf = spixstate.words + (word_offs >> 2); + uae_u8 *stb1 = spixstate.bytes + word_offs; + for (i = 0; i < width; i += 8) { + stb1[0] |= state; + stb1[1] |= state; + stb1[2] |= state; + stb1[3] |= state; + stb1[4] |= state; + stb1[5] |= state; + stb1[6] |= state; + stb1[7] |= state; + stb1 += 8; + } + e->has_attached = 1; + } +} + +static void decide_sprites (int hpos) +{ + int nrs[MAX_SPRITES], posns[MAX_SPRITES]; + int count, i; + /* apparantly writes to custom registers happen in the 3/4th of cycle + * and sprite xpos comparator sees it immediately */ + int point = hpos * 2 - 4; + int width = sprite_width; + int window_width = (width << lores_shift) >> sprres; + + if (nodraw () || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point) + return; + + decide_diw (hpos); + decide_line (hpos); + + count = 0; + for (i = 0; i < MAX_SPRITES; i++) { + int sprxp = spr[i].xpos; + int hw_xp = (sprxp >> sprite_buffer_res); + int window_xp = coord_hw_to_window_x (hw_xp) + (DIW_DDF_OFFSET << lores_shift); + int j, bestp; + +#if (SPRITE_MASK) != 255 + if (!((SPRITE_MASK) & (1 << i))) + continue; +#endif + if (! spr[i].armed || sprxp < 0 || hw_xp <= last_sprite_point || hw_xp > point) + continue; + if ( !(bplcon3 & 2) && /* sprites outside playfields enabled? */ + ((thisline_decision.diwfirstword >= 0 && window_xp + window_width < thisline_decision.diwfirstword) + || (thisline_decision.diwlastword >= 0 && window_xp > thisline_decision.diwlastword))) + continue; + + /* Sort the sprites in order of ascending X position before recording them. */ + for (bestp = 0; bestp < count; bestp++) { + if (posns[bestp] > sprxp) + break; + if (posns[bestp] == sprxp && nrs[bestp] < i) + break; + } + for (j = count; j > bestp; j--) { + posns[j] = posns[j-1]; + nrs[j] = nrs[j-1]; + } + posns[j] = sprxp; + nrs[j] = i; + count++; + } + for (i = 0; i < count; i++) { + int nr = nrs[i]; + record_sprite (next_lineno, nr, spr[nr].xpos, sprdata[nr], sprdatb[nr], sprctl[nr]); + } + last_sprite_point = point; +} + +STATIC_INLINE int sprites_differ (struct draw_info *dip, struct draw_info *dip_old) +{ + struct sprite_entry *this_first = curr_sprite_entries + dip->first_sprite_entry; + struct sprite_entry *this_last = curr_sprite_entries + dip->last_sprite_entry; + struct sprite_entry *prev_first = prev_sprite_entries + dip_old->first_sprite_entry; + int npixels; + int i; + + if (dip->nr_sprites != dip_old->nr_sprites) + return 1; + + if (dip->nr_sprites == 0) + return 0; + + for (i = 0; i < dip->nr_sprites; i++) + if (this_first[i].pos != prev_first[i].pos + || this_first[i].max != prev_first[i].max + || this_first[i].has_attached != prev_first[i].has_attached) + return 1; + + npixels = this_last->first_pixel + (this_last->max - this_last->pos) - this_first->first_pixel; + if (memcmp (spixels + this_first->first_pixel, spixels + prev_first->first_pixel, + npixels * sizeof (uae_u16)) != 0) + return 1; + if (memcmp (spixstate.bytes + this_first->first_pixel, spixstate.bytes + prev_first->first_pixel, npixels) != 0) + return 1; + return 0; +} + +STATIC_INLINE int color_changes_differ (struct draw_info *dip, struct draw_info *dip_old) +{ + if (dip->nr_color_changes != dip_old->nr_color_changes) + return 1; + + if (dip->nr_color_changes == 0) + return 0; + if (memcmp (curr_color_changes + dip->first_color_change, + prev_color_changes + dip_old->first_color_change, + dip->nr_color_changes * sizeof *curr_color_changes) != 0) + return 1; + return 0; +} + +/* End of a horizontal scan line. Finish off all decisions that were not + * made yet. */ +static void finish_decisions (void) +{ + struct draw_info *dip; + struct draw_info *dip_old; + struct decision *dp; + int changed; + int hpos = current_hpos (); + + if (nodraw ()) + return; + + decide_diw (hpos); + decide_line (hpos); + decide_fetch (hpos); + + if (thisline_decision.plfleft != -1 && thisline_decision.plflinelen == -1) { + if (fetch_state != fetch_not_started) { + write_log("fetch_state=%d plfleft=%d\n",fetch_state,thisline_decision.plfleft); + uae_abort ("fetch_state != fetch_not_started"); + } + thisline_decision.plfright = thisline_decision.plfleft; + thisline_decision.plflinelen = 0; + thisline_decision.bplres = RES_LORES; + } + + /* Large DIWSTOP values can cause the stop position never to be + * reached, so the state machine always stays in the same state and + * there's a more-or-less full-screen DIW. */ + if (hdiwstate == DIW_waiting_stop || thisline_decision.diwlastword > max_diwlastword) + thisline_decision.diwlastword = max_diwlastword; + + if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword) + MARK_LINE_CHANGED; + if (thisline_decision.diwlastword != line_decisions[next_lineno].diwlastword) + MARK_LINE_CHANGED; + + dip = curr_drawinfo + next_lineno; + dip_old = prev_drawinfo + next_lineno; + dp = line_decisions + next_lineno; + changed = thisline_changed; + + if (thisline_decision.plfleft != -1) + record_diw_line (thisline_decision.plfleft, diwfirstword, diwlastword); + + if (thisline_decision.plfleft != -1 || (bplcon3 & 2)) + decide_sprites (hpos); + + dip->last_sprite_entry = next_sprite_entry; + dip->last_color_change = next_color_change; + + if (thisline_decision.ctable == -1) { + if (thisline_decision.plfleft == -1) + remember_ctable_for_border (); + else + remember_ctable (); + } + + dip->nr_color_changes = next_color_change - dip->first_color_change; + dip->nr_sprites = next_sprite_entry - dip->first_sprite_entry; + + if (thisline_decision.plfleft != line_decisions[next_lineno].plfleft) + changed = 1; + if (! changed && color_changes_differ (dip, dip_old)) + changed = 1; + if (!changed && thisline_decision.plfleft != -1 && sprites_differ (dip, dip_old)) + changed = 1; + + if (changed) { + thisline_changed = 1; + *dp = thisline_decision; + } else + /* The only one that may differ: */ + dp->ctable = thisline_decision.ctable; +} + +/* Set the state of all decisions to "undecided" for a new scanline. */ +static void reset_decisions (void) +{ + if (nodraw ()) + return; + toscr_res_first = 0; + + thisline_decision.any_hires_sprites = 0; + thisline_decision.nr_planes = 0; + + thisline_decision.plfleft = -1; + thisline_decision.plflinelen = -1; + thisline_decision.ham_seen = !! (bplcon0 & 0x800); + thisline_decision.ham_at_start = !! (bplcon0 & 0x800); + + /* decided_res shouldn't be touched before it's initialized by decide_line(). */ + thisline_decision.diwfirstword = -1; + thisline_decision.diwlastword = -1; + if (hdiwstate == DIW_waiting_stop) { + thisline_decision.diwfirstword = 0; + if (thisline_decision.diwfirstword != line_decisions[next_lineno].diwfirstword) + MARK_LINE_CHANGED; + } + thisline_decision.ctable = -1; + + thisline_changed = 0; + curr_drawinfo[next_lineno].first_color_change = next_color_change; + curr_drawinfo[next_lineno].first_sprite_entry = next_sprite_entry; + next_sprite_forced = 1; + + /* memset(sprite_last_drawn_at, 0, sizeof sprite_last_drawn_at); */ + last_sprite_point = 0; + fetch_state = fetch_not_started; + passed_plfstop = 0; + + memset (todisplay, 0, sizeof todisplay); + memset (fetched, 0, sizeof fetched); +#ifdef AGA + memset (fetched_aga0, 0, sizeof fetched_aga0); + memset (fetched_aga1, 0, sizeof fetched_aga1); +#endif + memset (outword, 0, sizeof outword); + + last_decide_line_hpos = -1; + last_sprite_decide_line_hpos = -1; + last_diw_pix_hpos = -1; + last_ddf_pix_hpos = -1; + last_sprite_hpos = -1; + last_fetch_hpos = -1; + +} + +static int isvsync (void) +{ + return currprefs.gfx_vsync && currprefs.gfx_afullscreen; +} + +int vsynctime_orig; +int turbo_emulation; + +void compute_vsynctime (void) +{ + fake_vblank_hz = 0; + if (currprefs.chipset_refreshrate) { + vblank_hz = currprefs.chipset_refreshrate; + if (isvsync()) { + vblank_skip = 1; + if (!fake_vblank_hz && vblank_hz > 85) { + vblank_hz /= 2; + vblank_skip = -1; + } + } + } + if (!fake_vblank_hz) + fake_vblank_hz = vblank_hz; + if (turbo_emulation) + vsynctime = vsynctime_orig = 1; + else + vsynctime = vsynctime_orig = syncbase / fake_vblank_hz; +#ifdef OPENGL + OGL_refresh (); +#endif +#ifdef D3D + D3D_refresh (); +#endif + if (currprefs.produce_sound > 1) + update_sound (fake_vblank_hz); +} + + +/* set PAL or NTSC timing variables */ +void init_hz (void) +{ + int isntsc; + + if ((currprefs.chipset_refreshrate == 50 && !currprefs.ntscmode) || + (currprefs.chipset_refreshrate == 60 && currprefs.ntscmode)) { + currprefs.chipset_refreshrate = 0; + changed_prefs.chipset_refreshrate = 0; + } + if (currprefs.gfx_vsync && currprefs.gfx_afullscreen) { + currprefs.chipset_refreshrate = abs (currprefs.gfx_refreshrate); + changed_prefs.chipset_refreshrate = abs (currprefs.gfx_refreshrate); + } + + beamcon0 = new_beamcon0; + isntsc = beamcon0 & 0x20 ? 0 : 1; + if (hack_vpos > 0) { + if (maxvpos == hack_vpos) + return; + maxvpos = hack_vpos; + vblank_hz = 15600 / hack_vpos; + hack_vpos = -1; + } else if (hack_vpos < 0) { + hack_vpos = 0; + } + if (hack_vpos == 0) { + if (!isntsc) { + maxvpos = MAXVPOS_PAL; + maxhpos = MAXHPOS_PAL; + minfirstline = VBLANK_ENDLINE_PAL; + vblank_hz = VBLANK_HZ_PAL; + sprite_vblank_endline = VBLANK_SPRITE_PAL; + } else { + maxvpos = MAXVPOS_NTSC; + maxhpos = MAXHPOS_NTSC; + minfirstline = VBLANK_ENDLINE_NTSC; + vblank_hz = VBLANK_HZ_NTSC; + sprite_vblank_endline = VBLANK_SPRITE_NTSC; + } + } + if (beamcon0 & 0x80) { + if (vtotal >= MAXVPOS) + vtotal = MAXVPOS - 1; + maxvpos = vtotal + 1; + if (htotal >= MAXHPOS) + htotal = MAXHPOS - 1; + maxhpos = htotal + 1; + vblank_hz = 227 * 312 * 50 / (maxvpos * maxhpos); + } + /* limit to sane values */ + if (vblank_hz < 10) + vblank_hz = 10; + if (vblank_hz > 300) + vblank_hz = 300; + eventtab[ev_hsync].oldcycles = get_cycles (); + eventtab[ev_hsync].evtime = get_cycles() + HSYNCTIME; + events_schedule (); + compute_vsynctime (); +#ifdef OPENGL + OGL_refresh (); +#endif +#ifdef PICASSO96 + init_hz_p96 (); +#endif + write_log ("%s mode, %dHz (h=%d v=%d)\n", + isntsc ? "NTSC" : "PAL", vblank_hz, maxhpos, maxvpos); +} + +static void calcdiw (void) +{ + int hstrt = diwstrt & 0xFF; + int hstop = diwstop & 0xFF; + int vstrt = diwstrt >> 8; + int vstop = diwstop >> 8; + + if (diwhigh_written) { + hstrt |= ((diwhigh >> 5) & 1) << 8; + hstop |= ((diwhigh >> 13) & 1) << 8; + vstrt |= (diwhigh & 7) << 8; + vstop |= ((diwhigh >> 8) & 7) << 8; + } else { + hstop += 0x100; + if ((vstop & 0x80) == 0) + vstop |= 0x100; + } + + diwfirstword = coord_diw_to_window_x (hstrt); + diwlastword = coord_diw_to_window_x (hstop); + if (diwfirstword >= diwlastword) { + diwfirstword = 0; + diwlastword = max_diwlastword; + } + if (diwfirstword < 0) + diwfirstword = 0; + + plffirstline = vstrt; + plflastline = vstop; + +#if 0 + /* This happens far too often. */ + if (plffirstline < minfirstline_bpl) { + write_log ("Warning: Playfield begins before line %d (%d)!\n", minfirstline_bpl, plffirstline); + } +#endif + +#if 0 /* this comparison is not needed but previous is.. */ + if (plflastline > 313) { + /* Turrican does this */ + write_log ("Warning: Playfield out of range!\n"); + plflastline = 313; + } +#endif + + plfstrt = ddfstrt; + plfstop = ddfstop; + /* probably not the correct place.. */ + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + if (ddfstop > maxhpos) + plfstrt = 0; + if (plfstrt < HARD_DDF_START) + plfstrt = HARD_DDF_START; + } +} + +/* display mode changed (lores, doubling etc..), recalculate everything */ +void init_custom (void) +{ + reset_drawing (); + init_hz (); + calcdiw (); +} + +static int timehack_alive = 0; + +static uae_u32 timehack_helper (void) +{ +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; + if (m68k_dreg (regs, 0) == 0) + return timehack_alive; + + timehack_alive = 10; + + gettimeofday (&tv, NULL); + put_long (m68k_areg (regs, 0), tv.tv_sec - (((365 * 8 + 2) * 24) * 60 * 60)); + put_long (m68k_areg (regs, 0) + 4, tv.tv_usec); + return 0; +#else + return 2; +#endif +} + + /* + * register functions + */ +STATIC_INLINE uae_u16 DENISEID (void) +{ +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) + return 0xF8; +#endif + if (currprefs.chipset_mask & CSMASK_ECS_DENISE) + return 0xFC; + return 0xffff; +} +STATIC_INLINE uae_u16 DMACONR (void) +{ + uae_u16 v; + decide_blitter (current_hpos ()); + v = dmacon | (bltstate == BLT_done ? 0 : 0x4000) + | (blt_info.blitzero ? 0x2000 : 0); +#if 0 + if (!dmaen (DMA_BLITTER)) + v &= ~0x4000; +#endif + return v; +} +STATIC_INLINE uae_u16 INTENAR (void) +{ + return intena; +} +uae_u16 INTREQR (void) +{ + return intreq; +} +STATIC_INLINE uae_u16 ADKCONR (void) +{ + return adkcon; +} +STATIC_INLINE uae_u16 VPOSR (void) +{ + unsigned int csbit = currprefs.ntscmode ? 0x1000 : 0; + int vp = (vpos >> 8) & 7; +#ifdef AGA + csbit |= (currprefs.chipset_mask & CSMASK_AGA) ? 0x2300 : 0; +#endif + csbit |= (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0x2000 : 0; + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + vp &= 1; + vp = vp | lof | csbit; + return vp; +} +static void VPOSW (uae_u16 v) +{ +#if 0 + write_log ("vposw %x at %x\n", v, m68k_getpc()); +#endif + if (lof != (v & 0x8000)) + lof_changed = 1; + lof = v & 0x8000; + if ( (v & 1) && vpos > 0) + hack_vpos = vpos; +} + +STATIC_INLINE uae_u16 VHPOSR (void) +{ + uae_u16 v = vpos << 8; + uae_u16 hp = current_hpos (); + v |= hp; + return v; +} + +STATIC_INLINE void COP1LCH (uae_u16 v) { cop1lc = (cop1lc & 0xffff) | ((uae_u32)v << 16); } +STATIC_INLINE void COP1LCL (uae_u16 v) { cop1lc = (cop1lc & ~0xffff) | (v & 0xfffe); } +STATIC_INLINE void COP2LCH (uae_u16 v) { cop2lc = (cop2lc & 0xffff) | ((uae_u32)v << 16); } +STATIC_INLINE void COP2LCL (uae_u16 v) { cop2lc = (cop2lc & ~0xffff) | (v & 0xfffe); } + +static void COPJMP (int num) +{ + int was_active = eventtab[ev_copper].active; + int oldstrobe = cop_state.strobe; + + eventtab[ev_copper].active = 0; + if (was_active) + events_schedule (); + + cop_state.ignore_next = 0; + cop_state.state = COP_read1; + cop_state.vpos = vpos; + cop_state.hpos = current_hpos () & ~1; + copper_enabled_thisline = 0; + cop_state.strobe = num; + + if (dmaen (DMA_COPPER)) { + copper_enabled_thisline = 1; + set_special (SPCFLAG_COPPER); + } else if (oldstrobe != num) { + /* dma disabled and accessing both COPxJMPs -> copper stops! */ + cop_state.state = COP_stop; + copper_enabled_thisline = 0; + unset_special (SPCFLAG_COPPER); + } +} + +STATIC_INLINE void COPCON (uae_u16 a) +{ + copcon = a; +} + +static void compute_spcflag_copper (void); +static void DMACON (int hpos, uae_u16 v) +{ + int oldcop, newcop; + uae_u16 changed; + + uae_u16 oldcon = dmacon; + + decide_line (hpos); + decide_fetch (hpos); + decide_blitter (hpos); + + setclr (&dmacon, v); + dmacon &= 0x1FFF; + + changed = dmacon ^ oldcon; + + oldcop = (oldcon & DMA_COPPER) && (oldcon & DMA_MASTER); + newcop = (dmacon & DMA_COPPER) && (dmacon & DMA_MASTER); + + if (oldcop != newcop) { + eventtab[ev_copper].active = 0; + if (newcop && !oldcop) { + compute_spcflag_copper (); + } else if (!newcop) { + copper_enabled_thisline = 0; + unset_special (SPCFLAG_COPPER); + } + } + if ((dmacon & DMA_BLITPRI) > (oldcon & DMA_BLITPRI) && bltstate != BLT_done) { + static int count = 0; + if (!count) { + count = 1; + write_log ("warning: program is doing blitpri hacks.\n"); + } + set_special (SPCFLAG_BLTNASTY); + decide_blitter (hpos); + } + if (dmaen (DMA_BLITTER) && bltstate == BLT_init) + bltstate = BLT_work; + if ((dmacon & (DMA_BLITPRI | DMA_BLITTER | DMA_MASTER)) != (DMA_BLITPRI | DMA_BLITTER | DMA_MASTER)) { + unset_special (SPCFLAG_BLTNASTY); + decide_blitter (hpos); + } + if (changed & (DMA_MASTER | 0x0f)) + audio_hsync (0); + if (changed & (DMA_MASTER | DMA_BITPLANE)) { + ddf_change = vpos; + if (dmaen (DMA_BITPLANE)) + maybe_start_bpl_dma (hpos); + } + + events_schedule(); +} + + +#define INTDELAY + +static int intlev_2 (void) +{ + uae_u16 imask = intreq & intena; + unsigned long cycles = get_cycles (); + int c = 4; + int i; + + if (!(imask && (intena & 0x4000))) { + unset_special (SPCFLAG_INT); + return -1; + } + for (i = 14; i >= 0; i--) { + if (imask & (1 << i)) { +#ifdef INTDELAY + if (!(irqdelay[i] && (cycles - irqcycles[i]) < c * CYCLE_UNIT)) { +#endif + irqdelay[i] = 0; + if (i == 13 || i == 14) + return 6; + else if (i == 11 || i == 12) + return 5; + else if (i >= 7 && i <= 10) + return 4; + else if (i >= 4 && i <= 6) + return 3; + else if (i == 3) + return 2; + else + return 1; + } +#ifdef INTDELAY + } +#endif + } + return -1; +} + +int intlev (void) +{ + int il = -1; +#ifdef JIT + if (currprefs.cachesize) { + uae_u16 imask = intreq & intena; + if (imask && (intena & 0x4000)) { + if (imask & 0x6000) + il = 6; + if (imask & 0x1800) + il = 5; + if (imask & 0x0780) + il = 4; + if (imask & 0x0070) + il = 3; + if (imask & 0x0008) + il = 2; + if (imask & 0x0007) + il = 1; + } + } else { +#endif + il = intlev_2 (); + if (il >= 0 && il <= regs.intmask) + unset_special (SPCFLAG_INT); +#ifdef JIT + } +#endif + return il; +} + +static void doint (void) +{ + int i; + uae_u16 imask; + + set_special (SPCFLAG_INT); +#ifdef JIT + if (currprefs.cachesize) + return; +#endif + imask = intreq & intena; + if (imask && (intena & 0x4000)) { + for (i = 0; i < 14; i++) { + if ((imask & (1 << i)) && irqdelay[i] == 0) { + irqdelay[i] = 1; + irqcycles[i] = get_cycles (); + } + } + } +} + +STATIC_INLINE void INTENA (uae_u16 v) +{ + setclr (&intena,v); +#if 0 + if (v & 0x40) + write_log("INTENA %04.4X (%04.4X) %p\n", intena, v, m68k_getpc()); +#endif + if (v & 0x8000) + doint (); +} + +void INTREQ_0 (uae_u16 v) +{ + setclr (&intreq,v); + doint (); +} + +void INTREQ (uae_u16 v) +{ + INTREQ_0 (v); + serial_check_irq (); + rethink_cias (); +#if 0 + if (0 || (v & (0x8010)) == 0x8010) + write_log("%d INTREQ %04.4X (%04.4X) %x %x %x\n", + vpos, intreq, v, m68k_getpc(), cop1lc, cop2lc); +#endif +} + +static void ADKCON (int hpos, uae_u16 v) +{ + if (currprefs.produce_sound > 0) + update_audio (); + + setclr (&adkcon,v); + update_adkmasks (); + DISK_update (hpos); + if ((v >> 11) & 1) + serial_uartbreak ((adkcon >> 11) & 1); +} + +static void BEAMCON0 (uae_u16 v) +{ + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) + v &= 0x20; + if (v != new_beamcon0) { + new_beamcon0 = v; + if (v & ~0x20) + write_log ("warning: %04.4X written to BEAMCON0\n", v); + } + } +} + +#ifndef CUSTOM_SIMPLE + +static void dumpsync (void) +{ +#if 0 + write_log ("BEAMCON0 = %04.4X VTOTAL=%04.4X HTOTAL=%04.4X\n", new_beamcon0, vtotal, htotal); + write_log ("HSSTOP=%04.4X HBSTRT=%04.4X HBSTOP=%04.4X\n", hsstop, hbstrt, hbstop); + write_log ("VSSTOP=%04.4X VBSTRT=%04.4X VBSTOP=%04.4X\n", vsstop, vbstrt, vbstop); + write_log ("HSSTRT=%04.4X VSSTRT=%04.4X HCENTER=%04.4X\n", hsstrt, vsstrt, hcenter); +#endif +} + +static void varsync (void) +{ +#ifdef PICASSO96 + if (p96refresh_active) + { + extern int p96hack_vpos2; + static int p96hack_vpos_old; + if (p96hack_vpos_old == p96hack_vpos2) return; + vtotal = p96hack_vpos2; + p96hack_vpos_old = p96hack_vpos2; + hack_vpos = -1; + return; + } +#endif + if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) + return; + if (!(beamcon0 & 0x80)) + return; + hack_vpos = -1; + dumpsync (); +} +#endif + +int is_bitplane_dma (int hpos) +{ + if (fetch_state == fetch_not_started || hpos < thisline_decision.plfleft) + return 0; + if ((passed_plfstop == 3 && hpos >= thisline_decision.plfright) + || hpos >= estimated_last_fetch_cycle) + return 0; + return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; +} + +STATIC_INLINE int is_bitplane_dma_inline (int hpos) +{ + if (fetch_state == fetch_not_started || hpos < thisline_decision.plfleft) + return 0; + if ((passed_plfstop == 3 && hpos >= thisline_decision.plfright) + || hpos >= estimated_last_fetch_cycle) + return 0; + return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; +} + +static void BPLxPTH (int hpos, uae_u16 v, int num) +{ + decide_line (hpos); + decide_fetch (hpos); + bplpt[num] = (bplpt[num] & 0xffff) | ((uae_u32)v << 16); + //write_log("%d:%d:BPL%dPTH %08.8X\n", hpos, vpos, num, v); +} +static void BPLxPTL (int hpos, uae_u16 v, int num) +{ + int delta = 0; + decide_line (hpos); + decide_fetch (hpos); + /* fix for "bitplane dma fetch at the same time while updating BPLxPTL" */ + /* fixes "3v Demo" by Cave and "New Year Demo" by Phoenix */ + if (is_bitplane_dma(hpos - 1) == num + 1) + delta = 2 << fetchmode; + bplpt[num] = (bplpt[num] & ~0xffff) | ((v + delta) & 0xfffe); + //write_log("%d:%d:BPL%dPTL %08.8X\n", hpos, vpos, num, v); +} + +static void BPLCON0 (int hpos, uae_u16 v) +{ + if (! (currprefs.chipset_mask & CSMASK_ECS_DENISE)) + v &= ~0x00F1; + else if (! (currprefs.chipset_mask & CSMASK_AGA)) + v &= ~0x00B1; + + if (bplcon0 == v) + return; + + ddf_change = vpos; + decide_line (hpos); + decide_fetch (hpos); + decide_blitter (hpos); + + /* HAM change? */ + if ((bplcon0 ^ v) & 0x800) { + record_color_change (hpos, -1, !! (v & 0x800)); + } + bplcon0 = v; + +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + decide_sprites (hpos); + expand_sprres (); + } +#endif + + expand_fmodes (); + calcdiw (); + estimate_last_fetch_cycle (hpos); +} + +STATIC_INLINE void BPLCON1 (int hpos, uae_u16 v) +{ + if (!(currprefs.chipset_mask & CSMASK_AGA)) + v &= 0xff; + if (bplcon1 == v) + return; + ddf_change = vpos; + decide_line (hpos); + decide_fetch (hpos); + bplcon1 = v; +} + +STATIC_INLINE void BPLCON2 (int hpos, uae_u16 v) +{ + if (!(currprefs.chipset_mask & CSMASK_AGA)) + v &= 0x7f; + if (bplcon2 == v) + return; + decide_line (hpos); + bplcon2 = v; +} + +#ifdef AGA +STATIC_INLINE void BPLCON3 (int hpos, uae_u16 v) +{ + if (! (currprefs.chipset_mask & CSMASK_AGA)) + return; + if (bplcon3 == v) + return; + decide_line (hpos); + decide_sprites (hpos); + bplcon3 = v; + expand_sprres (); +} + +STATIC_INLINE void BPLCON4 (int hpos, uae_u16 v) +{ + if (! (currprefs.chipset_mask & CSMASK_AGA)) + return; + if (bplcon4 == v) + return; + decide_line (hpos); + bplcon4 = v; +} +#endif + +static void BPL1MOD (int hpos, uae_u16 v) +{ + v &= ~1; + if ((uae_s16)bpl1mod == (uae_s16)v) + return; + decide_line (hpos); + decide_fetch (hpos); + bpl1mod = v; +} + +static void BPL2MOD (int hpos, uae_u16 v) +{ + v &= ~1; + if ((uae_s16)bpl2mod == (uae_s16)v) + return; + decide_line (hpos); + decide_fetch (hpos); + bpl2mod = v; +} + +STATIC_INLINE void BPL1DAT (int hpos, uae_u16 v) +{ + decide_line (hpos); + bpl1dat = v; + + maybe_first_bpl1dat (hpos); +} + +#if 0 +/* We could do as well without those... */ +STATIC_INLINE void BPL2DAT (uae_u16 v) { bpl2dat = v; } +STATIC_INLINE void BPL3DAT (uae_u16 v) { bpl3dat = v; } +STATIC_INLINE void BPL4DAT (uae_u16 v) { bpl4dat = v; } +STATIC_INLINE void BPL5DAT (uae_u16 v) { bpl5dat = v; } +STATIC_INLINE void BPL6DAT (uae_u16 v) { bpl6dat = v; } +STATIC_INLINE void BPL7DAT (uae_u16 v) { bpl7dat = v; } +STATIC_INLINE void BPL8DAT (uae_u16 v) { bpl8dat = v; } +#endif + +static void DIWSTRT (int hpos, uae_u16 v) +{ + if (diwstrt == v && ! diwhigh_written) + return; + decide_line (hpos); + diwhigh_written = 0; + diwstrt = v; + calcdiw (); +} + +static void DIWSTOP (int hpos, uae_u16 v) +{ + if (diwstop == v && ! diwhigh_written) + return; + decide_line (hpos); + diwhigh_written = 0; + diwstop = v; + calcdiw (); +} + +static void DIWHIGH (int hpos, uae_u16 v) +{ + if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + return; + if (diwhigh_written && diwhigh == v) + return; + decide_line (hpos); + diwhigh_written = 1; + diwhigh = v; + calcdiw (); +} + +static void DDFSTRT (int hpos, uae_u16 v) +{ + v &= 0xfe; + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + v &= 0xfc; + if (ddfstrt == v && hpos != plfstrt - 2) + return; + ddf_change = vpos; + decide_line (hpos); + ddfstrt_old_hpos = hpos; + ddfstrt_old_vpos = vpos; + ddfstrt = v; + calcdiw (); + if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) { + static int last_warned; + last_warned = (last_warned + 1) & 4095; + if (last_warned == 0) + write_log ("WARNING! Very strange DDF values (%x %x).\n", ddfstrt, ddfstop); + } +} + +static void DDFSTOP (int hpos, uae_u16 v) +{ + v &= 0xfe; + if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + v &= 0xfc; + if (ddfstop == v) + return; + decide_line (hpos); + decide_fetch (hpos); + decide_blitter (hpos); + ddfstop = v; + calcdiw (); + if (fetch_state != fetch_not_started) + estimate_last_fetch_cycle (hpos); + if (ddfstop > 0xD4 && (ddfstrt & 4) == 4) { + static int last_warned; + if (last_warned == 0) + write_log ("WARNING! Very strange DDF values (%x).\n", ddfstop); + last_warned = (last_warned + 1) & 4095; + } +} + +static void FMODE (uae_u16 v) +{ + if (! (currprefs.chipset_mask & CSMASK_AGA)) + v = 0; + ddf_change = vpos; + fmode = v; + sprite_width = GET_SPRITEWIDTH (fmode); + switch (fmode & 3) { + case 0: + fetchmode = 0; + break; + case 1: + case 2: + fetchmode = 1; + break; + case 3: + fetchmode = 2; + break; + } + expand_fmodes (); + calcdiw (); +} + +static void BLTADAT (uae_u16 v) +{ + maybe_blit (current_hpos(), 0); + + blt_info.bltadat = v; +} +/* + * "Loading data shifts it immediately" says the HRM. Well, that may + * be true for BLTBDAT, but not for BLTADAT - it appears the A data must be + * loaded for every word so that AFWM and ALWM can be applied. + */ +static void BLTBDAT (uae_u16 v) +{ + maybe_blit (current_hpos(), 0); + + if (bltcon1 & 2) + blt_info.bltbhold = v << (bltcon1 >> 12); + else + blt_info.bltbhold = v >> (bltcon1 >> 12); + blt_info.bltbdat = v; +} +static void BLTCDAT (uae_u16 v) { maybe_blit (current_hpos(), 0); blt_info.bltcdat = v; reset_blit (0); } + +static void BLTAMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltamod = (uae_s16)(v & 0xFFFE); reset_blit (0); } +static void BLTBMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltbmod = (uae_s16)(v & 0xFFFE); reset_blit (0); } +static void BLTCMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltcmod = (uae_s16)(v & 0xFFFE); reset_blit (0); } +static void BLTDMOD (uae_u16 v) { maybe_blit (current_hpos(), 1); blt_info.bltdmod = (uae_s16)(v & 0xFFFE); reset_blit (0); } + +static void BLTCON0 (uae_u16 v) { maybe_blit (current_hpos(), 2); bltcon0 = v; blinea_shift = v >> 12; reset_blit (1); } +/* The next category is "Most useless hardware register". + * And the winner is... */ +static void BLTCON0L (uae_u16 v) +{ + if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + return; + maybe_blit (current_hpos(), 2); bltcon0 = (bltcon0 & 0xFF00) | (v & 0xFF); + reset_blit (1); +} +static void BLTCON1 (uae_u16 v) { maybe_blit (current_hpos(), 2); bltcon1 = v; reset_blit (2); } + +static void BLTAFWM (uae_u16 v) { maybe_blit (current_hpos(), 2); blt_info.bltafwm = v; reset_blit (0); } +static void BLTALWM (uae_u16 v) { maybe_blit (current_hpos(), 2); blt_info.bltalwm = v; reset_blit (0); } + +static void BLTAPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltapt = (bltapt & 0xffff) | ((uae_u32)v << 16); } +static void BLTAPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltapt = (bltapt & ~0xffff) | (v & 0xFFFE); } +static void BLTBPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltbpt = (bltbpt & 0xffff) | ((uae_u32)v << 16); } +static void BLTBPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltbpt = (bltbpt & ~0xffff) | (v & 0xFFFE); } +static void BLTCPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltcpt = (bltcpt & 0xffff) | ((uae_u32)v << 16); } +static void BLTCPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltcpt = (bltcpt & ~0xffff) | (v & 0xFFFE); } +static void BLTDPTH (uae_u16 v) { maybe_blit (current_hpos(), 0); bltdpt = (bltdpt & 0xffff) | ((uae_u32)v << 16); } +static void BLTDPTL (uae_u16 v) { maybe_blit (current_hpos(), 0); bltdpt = (bltdpt & ~0xffff) | (v & 0xFFFE); } + +static void BLTSIZE (uae_u16 v) +{ + maybe_blit (current_hpos(), 0); + + blt_info.vblitsize = v >> 6; + blt_info.hblitsize = v & 0x3F; + if (!blt_info.vblitsize) blt_info.vblitsize = 1024; + if (!blt_info.hblitsize) blt_info.hblitsize = 64; + do_blitter (current_hpos()); +} + +static void BLTSIZV (uae_u16 v) +{ + if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + return; + maybe_blit (current_hpos(), 0); + blt_info.vblitsize = v & 0x7FFF; +} + +static void BLTSIZH (uae_u16 v) +{ + if (! (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + return; + maybe_blit (current_hpos(), 0); + blt_info.hblitsize = v & 0x7FF; + if (!blt_info.vblitsize) + blt_info.vblitsize = 32768; + if (!blt_info.hblitsize) + blt_info.hblitsize = 0x800; + do_blitter (current_hpos()); +} + +STATIC_INLINE spr_arm (int num, int state) +{ + switch (state) + { + case 0: + nr_armed -= spr[num].armed; + spr[num].armed = 0; + break; + default: + nr_armed += 1 - spr[num].armed; + spr[num].armed = 1; + break; + } +} + +STATIC_INLINE void sprstartstop (struct sprite *s) +{ + if (vpos == s->vstart) + s->dmastate = 1; + if (vpos == s->vstop) + s->dmastate = 0; +} + +STATIC_INLINE void SPRxCTLPOS (int num) +{ + int sprxp; + struct sprite *s = &spr[num]; + + sprstartstop (s); + sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1); + /* Quite a bit salad in this register... */ +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + /* We ignore the SHRES 35ns increment for now; SHRES support doesn't + work anyway, so we may as well restrict AGA sprites to a 70ns + resolution. */ + sprxp <<= 1; + sprxp |= (sprctl[num] >> 4) & 1; + } +#endif + s->xpos = sprxp; + s->vstart = (sprpos[num] >> 8) | ((sprctl[num] << 6) & 0x100); + s->vstop = (sprctl[num] >> 8) | ((sprctl[num] << 7) & 0x100); + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { + s->vstart |= (sprctl[num] << 3) & 0x200; + s->vstop |= (sprctl[num] << 4) & 0x200; + } + sprstartstop (s); +} + +STATIC_INLINE void SPRxCTL_1 (uae_u16 v, int num, int hpos) +{ + struct sprite *s = &spr[num]; + sprctl[num] = v; + spr_arm (num, 0); + SPRxCTLPOS (num); +#if SPRITE_DEBUG > 0 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + write_log ("%d:%d:SPR%dCTL %04.4X P=%06.6X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n", + vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, m68k_getpc()); + } +#endif + +} +STATIC_INLINE void SPRxPOS_1 (uae_u16 v, int num, int hpos) +{ + struct sprite *s = &spr[num]; + sprpos[num] = v; + SPRxCTLPOS (num); +#if SPRITE_DEBUG > 0 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + write_log ("%d:%d:SPR%dPOS %04.4X P=%06.6X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n", + vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, m68k_getpc()); + } +#endif +} +STATIC_INLINE void SPRxDATA_1 (uae_u16 v, int num, int hpos) +{ + sprdata[num][0] = v; +#ifdef AGA + sprdata[num][1] = v; + sprdata[num][2] = v; + sprdata[num][3] = v; +#endif + spr_arm (num, 1); +#if SPRITE_DEBUG > 1 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + write_log ("%d:%d:SPR%dDATA %04.4X P=%06.6X D=%d A=%d PC=%x\n", + vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, m68k_getpc()); + } +#endif +} +STATIC_INLINE void SPRxDATB_1 (uae_u16 v, int num, int hpos) +{ + sprdatb[num][0] = v; +#ifdef AGA + sprdatb[num][1] = v; + sprdatb[num][2] = v; + sprdatb[num][3] = v; +#endif +#if SPRITE_DEBUG > 1 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + write_log ("%d:%d:SPR%dDATB %04.4X P=%06.6X D=%d A=%d PC=%x\n", + vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, m68k_getpc()); + } +#endif +} +static void SPRxDATA (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxDATA_1 (v, num, hpos); } +static void SPRxDATB (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxDATB_1 (v, num, hpos); } +static void SPRxCTL (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxCTL_1 (v, num, hpos); } +static void SPRxPOS (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxPOS_1 (v, num, hpos); } +static void SPRxPTH (int hpos, uae_u16 v, int num) +{ + decide_sprites (hpos); + spr[num].pt &= 0xffff; + spr[num].pt |= (uae_u32)v << 16; +#if SPRITE_DEBUG > 0 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + write_log ("%d:%d:SPR%dPTH %06.6X\n", vpos, hpos, num, spr[num].pt); + } +#endif +} +static void SPRxPTL (int hpos, uae_u16 v, int num) +{ + decide_sprites (hpos); + spr[num].pt &= ~0xffff; + spr[num].pt |= v; +#if SPRITE_DEBUG > 0 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + write_log ("%d:%d:SPR%dPTL %06.6X\n", vpos, hpos, num, spr[num].pt); + } +#endif +} + +static void CLXCON (uae_u16 v) +{ + clxcon = v; + clxcon_bpl_enable = (v >> 6) & 63; + clxcon_bpl_match = v & 63; + //write_log("CLXCON: %04.4X PC=%x\n", v, m68k_getpc()); +} + +static void CLXCON2 (uae_u16 v) +{ + if (!(currprefs.chipset_mask & CSMASK_AGA)) + return; + clxcon2 = v; + clxcon_bpl_enable |= v & (0x40|0x80); + clxcon_bpl_match |= (v & (0x01|0x02)) << 6; + //write_log("CLXCON2: %04.4X\n", v); +} + +static uae_u16 CLXDAT (void) +{ + uae_u16 v = clxdat | 0x8000; + //write_log("%d:CLXDAT %04.4X PC=%x\n", vpos, v, m68k_getpc()); + clxdat = 0; + return v; +} + +#ifdef AGA +static uae_u16 COLOR_READ (int num) +{ + int cr, cg, cb, colreg; + uae_u16 cval; + + if (!(currprefs.chipset_mask & CSMASK_AGA) || !(bplcon2 & 0x0100)) + return 0xffff; + + colreg = ((bplcon3 >> 13) & 7) * 32 + num; + cr = current_colors.color_regs_aga[colreg] >> 16; + cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF; + cb = current_colors.color_regs_aga[colreg] & 0xFF; + if (bplcon3 & 0x200) + cval = ((cr & 15) << 8) | ((cg & 15) << 4) | ((cb & 15) << 0); + else + cval = ((cr >> 4) << 8) | ((cg >> 4) << 4) | ((cb >> 4) << 0); + return cval; +} +#endif + +static void COLOR_WRITE (int hpos, uae_u16 v, int num) +{ + v &= 0xFFF; +#ifdef AGA + if (currprefs.chipset_mask & CSMASK_AGA) { + int r,g,b; + int cr,cg,cb; + int colreg; + uae_u32 cval; + + /* writing is disabled when RDRAM=1 */ + if (bplcon2 & 0x0100) + return; + + colreg = ((bplcon3 >> 13) & 7) * 32 + num; + r = (v & 0xF00) >> 8; + g = (v & 0xF0) >> 4; + b = (v & 0xF) >> 0; + cr = current_colors.color_regs_aga[colreg] >> 16; + cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF; + cb = current_colors.color_regs_aga[colreg] & 0xFF; + + if (bplcon3 & 0x200) { + cr &= 0xF0; cr |= r; + cg &= 0xF0; cg |= g; + cb &= 0xF0; cb |= b; + } else { + cr = r + (r << 4); + cg = g + (g << 4); + cb = b + (b << 4); + } + cval = (cr << 16) | (cg << 8) | cb; + if (cval == current_colors.color_regs_aga[colreg]) + return; + + /* Call this with the old table still intact. */ + record_color_change (hpos, colreg, cval); + remembered_color_entry = -1; + current_colors.color_regs_aga[colreg] = cval; + current_colors.acolors[colreg] = CONVERT_RGB (cval); + } else { +#endif + if (current_colors.color_regs_ecs[num] == v) + return; + /* Call this with the old table still intact. */ + record_color_change (hpos, num, v); + remembered_color_entry = -1; + current_colors.color_regs_ecs[num] = v; + current_colors.acolors[num] = xcolors[v]; +#ifdef AGA + } +#endif +} + +/* The copper code. The biggest nightmare in the whole emulator. + + Alright. The current theory: + 1. Copper moves happen 2 cycles after state READ2 is reached. + It can't happen immediately when we reach READ2, because the + data needs time to get back from the bus. An additional 2 + cycles are needed for non-Agnus registers, to take into account + the delay for moving data from chip to chip. + 2. As stated in the HRM, a WAIT really does need an extra cycle + to wake up. This is implemented by _not_ falling through from + a successful wait to READ1, but by starting the next cycle. + (Note: the extra cycle for the WAIT apparently really needs a + free cycle; i.e. contention with the bitplane fetch can slow + it down). + 3. Apparently, to compensate for the extra wake up cycle, a WAIT + will use the _incremented_ horizontal position, so the WAIT + cycle normally finishes two clocks earlier than the position + it was waiting for. The extra cycle then takes us to the + position that was waited for. + If the earlier cycle is busy with a bitplane, things change a bit. + E.g., waiting for position 0x50 in a 6 plane display: In cycle + 0x4e, we fetch BPL5, so the wait wakes up in 0x50, the extra cycle + takes us to 0x54 (since 0x52 is busy), then we have READ1/READ2, + and the next register write is at 0x5c. + 4. The last cycle in a line is not usable for the copper. + 5. A 4 cycle delay also applies to the WAIT instruction. This means + that the second of two back-to-back WAITs (or a WAIT whose + condition is immediately true) takes 8 cycles. + 6. This also applies to a SKIP instruction. The copper does not + fetch the next instruction while waiting for the second word of + a WAIT or a SKIP to arrive. + 7. A SKIP also seems to need an unexplained additional two cycles + after its second word arrives; this is _not_ a memory cycle (I + think, the documentation is pretty clear on this). + 8. Two additional cycles are inserted when writing to COPJMP1/2. */ + +/* Determine which cycles are available for the copper in a display + * with a agiven number of planes. */ + +STATIC_INLINE int copper_cant_read (int hpos) +{ + if (hpos + 1 >= maxhpos) + return 1; + return is_bitplane_dma_inline (hpos); +} + +STATIC_INLINE int dangerous_reg (int reg) +{ + /* Safe: + * Bitplane pointers, control registers, modulos and data. + * Sprite pointers, control registers, and data. + * Color registers. */ + if (reg >= 0xE0 && reg < 0x1C0) + return 0; + return 1; +} + +#define FAST_COPPER 1 + +/* The future, Conan? + We try to look ahead in the copper list to avoid doing continuous calls + to updat_copper (which is what happens when SPCFLAG_COPPER is set). If + we find that the same effect can be achieved by setting a delayed event + and then doing multiple copper insns in one batch, we can get a massive + speedup. + + We don't try to be precise here. All copper reads take exactly 2 cycles, + the effect of bitplane contention is ignored. Trying to get it exactly + right would be much more complex and as such carry a huge risk of getting + it subtly wrong; and it would also be more expensive - we want this code + to be fast. */ +static void predict_copper (void) +{ + uaecptr ip = cop_state.ip; + unsigned int c_hpos = cop_state.hpos; + enum copper_states state = cop_state.state; + unsigned int w1, w2, cycle_count; + + switch (state) { + case COP_read1_wr_in2: + case COP_read2_wr_in2: + case COP_read1_wr_in4: + if (dangerous_reg (cop_state.saved_i1)) + return; + state = state == COP_read2_wr_in2 ? COP_read2 : COP_read1; + break; + + case COP_read1_in2: + c_hpos += 2; + state = COP_read1; + break; + + case COP_stop: + case COP_bltwait: + case COP_wait1: + case COP_skip_in4: + case COP_skip_in2: + case COP_skip1: + case COP_strobe_delay: + return; + + case COP_wait_in4: + c_hpos += 2; + /* fallthrough */ + case COP_wait_in2: + c_hpos += 2; + /* fallthrough */ + case COP_wait: + state = COP_wait; + break; + + default: + break; + } + + /* Only needed for COP_wait, but let's shut up the compiler. */ + w1 = cop_state.saved_i1; + w2 = cop_state.saved_i2; + cop_state.first_sync = c_hpos; + cop_state.regtypes_modified = REGTYPE_FORCE; + + /* Get this case out of the way, so that the loop below only has to deal + with read1 and wait. */ + if (state == COP_read2) { + w1 = cop_state.i1; + if (w1 & 1) { + w2 = chipmem_agnus_wget (ip); + if (w2 & 1) + goto done; + state = COP_wait; + c_hpos += 4; + } else if (dangerous_reg (w1)) { + c_hpos += 4; + goto done; + } else { + cop_state.regtypes_modified |= regtypes[w1 & 0x1FE]; + state = COP_read1; + c_hpos += 2; + } + ip += 2; + } + + while (c_hpos + 1 < maxhpos) { + if (state == COP_read1) { + w1 = chipmem_agnus_wget (ip); + if (w1 & 1) { + w2 = chipmem_agnus_wget (ip + 2); + if (w2 & 1) + break; + state = COP_wait; + c_hpos += 6; + } else if (dangerous_reg (w1)) { + c_hpos += 6; + break; + } else { + cop_state.regtypes_modified |= regtypes[w1 & 0x1FE]; + c_hpos += 4; + } + ip += 4; + } else if (state == COP_wait) { + if ((w2 & 0xFE) != 0xFE) + break; + else { + unsigned int vcmp = (w1 & (w2 | 0x8000)) >> 8; + unsigned int hcmp = (w1 & 0xFE); + + unsigned int vp = vpos & (((w2 >> 8) & 0x7F) | 0x80); + if (vp < vcmp) { + /* Whee. We can wait until the end of the line! */ + c_hpos = maxhpos; + } else if (vp > vcmp || hcmp <= c_hpos) { + state = COP_read1; + /* minimum wakeup time */ + c_hpos += 2; + } else { + state = COP_read1; + c_hpos = hcmp; + } + /* If this is the current instruction, remember that we don't + need to sync CPU and copper anytime soon. */ + if (cop_state.ip == ip) { + cop_state.first_sync = c_hpos; + } + } + } else + uae_abort ("predict copper %d", state); + } + + done: + cycle_count = c_hpos - cop_state.hpos; + if (cycle_count >= 8) { + unset_special (SPCFLAG_COPPER); + eventtab[ev_copper].active = 1; + eventtab[ev_copper].oldcycles = get_cycles (); + eventtab[ev_copper].evtime = get_cycles () + cycle_count * CYCLE_UNIT; + events_schedule (); + } +} + +static int test_copper_dangerous (unsigned int address) +{ + if ((address & 0x1fe) < (copcon & 2 ? ((currprefs.chipset_mask & CSMASK_AGA) ? 0 : 0x40u) : 0x80u)) { + cop_state.state = COP_stop; + copper_enabled_thisline = 0; + unset_special (SPCFLAG_COPPER); + return 1; + } + return 0; +} + +static void perform_copper_write (int old_hpos) +{ + unsigned int address = cop_state.saved_i1 & 0x1FE; + + record_copper (cop_state.saved_ip - 4, old_hpos, vpos); + + if (test_copper_dangerous (address)) + return; + if (address == 0x88) { + cop_state.ip = cop1lc; + cop_state.state = COP_strobe_delay; + } else if (address == 0x8A) { + cop_state.ip = cop2lc; + cop_state.state = COP_strobe_delay; + } else { + custom_wput_1 (old_hpos, cop_state.saved_i1, cop_state.saved_i2, 0); + cop_state.last_write = cop_state.saved_i1; + cop_state.last_write_hpos = old_hpos; + old_hpos++; + if (cop_state.saved_i1 >= 0x140 && cop_state.saved_i1 < 0x180 && old_hpos >= SPR0_HPOS && old_hpos < SPR0_HPOS + 4 * MAX_SPRITES) { + //write_log ("%d:%d %04.4X:%04.4X\n", vpos, old_hpos, cop_state.saved_i1, cop_state.saved_i2); + do_sprites (old_hpos); + } + } +} + +static int isagnus[]= { + 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 27 0x40 - 0x74 */ + + 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 21 */ + 1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0, /* 32 0xa0 - 0xde + /* BPLxPTH/BPLxPTL */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */ + /* BPLCON0-3,BPLMOD1-2 */ + 0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, /* 16 */ + /* SPRxPTH/SPRxPTL */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */ + /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + /* COLORxx */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + /* RESERVED */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static void dump_copper (char *error, int until_hpos) +{ + write_log("%s: vpos=%d until_hpos=%d\n", + error, vpos, until_hpos); + write_log("cvcmp=%d chcmp=%d chpos=%d cvpos=%d ci1=%04.4X ci2=%04.4X\n", + cop_state.vcmp,cop_state.hcmp,cop_state.hpos,cop_state.vpos,cop_state.saved_i1,cop_state.saved_i2); + write_log("cstate=%d ip=%08.8X ev_copper=%d\n", + cop_state.state,cop_state.ip,eventtab[ev_copper].active); +} + +static void update_copper (int until_hpos) +{ + int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); + int c_hpos = cop_state.hpos; + + if (eventtab[ev_copper].active) { + static int warned; + if (!warned) { + dump_copper ("error1",until_hpos); + warned = 1; + } + eventtab[ev_copper].active = 0; + return; + uae_abort ("update_copper1"); + } + + if (cop_state.state == COP_wait && vp < cop_state.vcmp) { + static int warned; + if (!warned) { + dump_copper ("error2",until_hpos); + warned = 1; + } + copper_enabled_thisline = 0; + return; + uae_abort ("update_copper2"); + } + + until_hpos &= ~1; + + if (until_hpos > (maxhpos & ~1)) + until_hpos = maxhpos & ~1; + + until_hpos += 2; + for (;;) { + int old_hpos = c_hpos; + int hp; + + if (c_hpos >= until_hpos) + break; + + /* So we know about the fetch state. */ + decide_line (c_hpos); + + switch (cop_state.state) { + case COP_read1_in2: + cop_state.state = COP_read1; + break; + case COP_read1_wr_in2: + cop_state.state = COP_read1; + perform_copper_write (old_hpos); + /* That could have turned off the copper. */ + if (! copper_enabled_thisline) + goto out; + + break; + case COP_read1_wr_in4: + cop_state.state = COP_read1_wr_in2; + break; + case COP_read2_wr_in2: + cop_state.state = COP_read2; + perform_copper_write (old_hpos); + /* That could have turned off the copper. */ + if (! copper_enabled_thisline) + goto out; + + break; + case COP_wait_in2: + cop_state.state = COP_wait1; + break; + case COP_wait_in4: + cop_state.state = COP_wait_in2; + break; + case COP_skip_in2: + cop_state.state = COP_skip1; + break; + case COP_skip_in4: + cop_state.state = COP_skip_in2; + break; + case COP_strobe_delay: + cop_state.state = COP_read1_in2; + break; + + default: + break; + } + + c_hpos += 2; +#if 0 + if (copper_cant_read (old_hpos)) + continue; +#endif + if (cop_state.strobe) { + if (cop_state.strobe > 0) + cop_state.ip = cop_state.strobe == 1 ? cop1lc : cop2lc; + cop_state.strobe = 0; + } + + switch (cop_state.state) { + + case COP_read1_wr_in4: + uae_abort ("COP_read1_wr_in4"); + + case COP_read1_wr_in2: + case COP_read1: + if (copper_cant_read (old_hpos)) + continue; + cop_state.i1 = chipmem_agnus_wget (cop_state.ip); +#ifdef CPUEMU_6 + cycle_line[old_hpos] |= CYCLE_COPPER; +#endif + cop_state.ip += 2; + cop_state.state = cop_state.state == COP_read1 ? COP_read2 : COP_read2_wr_in2; + break; + + case COP_read2_wr_in2: + uae_abort ("read2_wr_in2"); + + case COP_read2: + if (copper_cant_read (old_hpos)) + continue; + cop_state.i2 = chipmem_agnus_wget (cop_state.ip); +#ifdef CPUEMU_6 + cycle_line[old_hpos] |= CYCLE_COPPER; +#endif + cop_state.ip += 2; + if (cop_state.ignore_next) { + cop_state.ignore_next = 0; + cop_state.state = COP_read1; + break; + } + + cop_state.saved_i1 = cop_state.i1; + cop_state.saved_i2 = cop_state.i2; + cop_state.saved_ip = cop_state.ip; + + if (cop_state.i1 & 1) { + if (cop_state.i2 & 1) + cop_state.state = COP_skip_in4; + else + cop_state.state = COP_wait_in4; + } else { + unsigned int reg = cop_state.i1 & 0x1FE; + cop_state.state = isagnus[reg >> 1] ? COP_read1_wr_in2 : COP_read1_wr_in4; + } + break; + + case COP_wait1: + /* There's a nasty case here. As stated in the "Theory" comment above, we + test against the incremented copper position. I believe this means that + we have to increment the _vertical_ position at the last cycle in the line, + and set the horizontal position to 0. + Normally, this isn't going to make a difference, since we consider these + last cycles unavailable for the copper, so waking up in the last cycle has + the same effect as waking up at the start of the line. However, there is + one possible problem: If we're at 0xFFE0, any wait for an earlier position + must _not_ complete (since, in effect, the current position will be back + at 0/0). This can be seen in the Superfrog copper list. + Things get monstrously complicated if we try to handle this "properly" by + incrementing vpos and setting c_hpos to 0. Especially the various speedup + hacks really assume that vpos remains constant during one line. Hence, + this hack: defer the entire decision until the next line if necessary. */ + if (c_hpos >= (maxhpos & ~1)) + break; + + cop_state.state = COP_wait; + + cop_state.vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; + cop_state.hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xFE); + + vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); + + if (cop_state.saved_i1 == 0xFFFF && cop_state.saved_i2 == 0xFFFE) { + cop_state.state = COP_stop; + copper_enabled_thisline = 0; + unset_special (SPCFLAG_COPPER); + goto out; + } + if (vp < cop_state.vcmp) { + copper_enabled_thisline = 0; + unset_special (SPCFLAG_COPPER); + goto out; + } + + /* fall through */ + case COP_wait: + if (vp < cop_state.vcmp) + uae_abort ("vp < cop_state.vcmp"); + if (copper_cant_read (old_hpos)) + continue; + + hp = c_hpos & (cop_state.saved_i2 & 0xFE); + if (vp == cop_state.vcmp && hp < cop_state.hcmp) { + /* Position not reached yet. */ + if (currprefs.fast_copper && FAST_COPPER && (cop_state.saved_i2 & 0xFE) == 0xFE) { + int wait_finish = cop_state.hcmp - 2; + /* This will leave c_hpos untouched if it's equal to wait_finish. */ + if (wait_finish < c_hpos) + uae_abort ("wait_finish < c_hpos"); + else if (wait_finish <= until_hpos) { + c_hpos = wait_finish; + } else + c_hpos = until_hpos; + } + break; + } + + /* Now we know that the comparisons were successful. We might still + have to wait for the blitter though. */ + if ((cop_state.saved_i2 & 0x8000) == 0 && (DMACONR() & 0x4000)) { + /* We need to wait for the blitter. */ + cop_state.state = COP_bltwait; + copper_enabled_thisline = 0; + unset_special (SPCFLAG_COPPER); + goto out; + } + + record_copper (cop_state.ip - 4, old_hpos, vpos); + + cop_state.state = COP_read1; + break; + + case COP_skip1: + { + static int skipped_before; + unsigned int vcmp, hcmp, vp1, hp1; + + if (! skipped_before) { + skipped_before = 1; + write_log ("Program uses Copper SKIP instruction.\n"); + } + + if (c_hpos >= (maxhpos & ~1)) + break; + + vcmp = (cop_state.saved_i1 & (cop_state.saved_i2 | 0x8000)) >> 8; + hcmp = (cop_state.saved_i1 & cop_state.saved_i2 & 0xFE); + 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() & 0x4000))) + cop_state.ignore_next = 1; + if (chipmem_agnus_wget (cop_state.ip) & 1) { /* FIXME: HACK!!! */ + /* copper never skips if following instruction is WAIT or another SKIP... */ + cop_state.ignore_next = 0; + } + + cop_state.state = COP_read1; + + if (cop_state.ignore_next && (chipmem_agnus_wget (cop_state.ip) & 1) == 0) { + /* another undocumented copper feature: + copper stops if skipped instruction is MOVE to dangerous register... + */ + test_copper_dangerous (chipmem_agnus_wget(cop_state.ip)); + } + + record_copper (cop_state.ip - 4, old_hpos, vpos); + + break; + } + default: + break; + } + } + + out: + cop_state.hpos = c_hpos; + + /* The test against maxhpos also prevents us from calling predict_copper + when we are being called from hsync_handler, which would not only be + stupid, but actively harmful. */ + if (currprefs.fast_copper && FAST_COPPER && (regs.spcflags & SPCFLAG_COPPER) && c_hpos + 8 < maxhpos) + predict_copper (); +} + +static void compute_spcflag_copper (void) +{ + copper_enabled_thisline = 0; + unset_special (SPCFLAG_COPPER); + if (! dmaen (DMA_COPPER) || cop_state.state == COP_stop || cop_state.state == COP_bltwait) + return; + + if (cop_state.state == COP_wait) { + int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); + + if (vp < cop_state.vcmp) + return; + } + copper_enabled_thisline = 1; + + if (currprefs.fast_copper && FAST_COPPER) + predict_copper (); + + if (! eventtab[ev_copper].active) + set_special (SPCFLAG_COPPER); +} + +static void copper_handler (void) +{ + /* This will take effect immediately, within the same cycle. */ + set_special (SPCFLAG_COPPER); + + if (! copper_enabled_thisline) + uae_abort ("copper_handler"); + + eventtab[ev_copper].active = 0; +} + +void blitter_done_notify (void) +{ + if (cop_state.state != COP_bltwait) + return; + + cop_state.hpos = current_hpos () & ~1; + cop_state.vpos = vpos; + cop_state.state = COP_wait; + compute_spcflag_copper (); +} + +void do_copper (void) +{ + int hpos = current_hpos (); + update_copper (hpos); +} + +/* ADDR is the address that is going to be read/written; this access is + the reason why we want to update the copper. This function is also + used from hsync_handler to finish up the line; for this case, we check + hpos against maxhpos. */ +STATIC_INLINE void sync_copper_with_cpu (int hpos, int do_schedule, unsigned int addr) +{ + /* Need to let the copper advance to the current position. */ + if (eventtab[ev_copper].active) { + if (hpos != maxhpos) { + /* There might be reasons why we don't actually need to bother + updating the copper. */ + if (hpos < cop_state.first_sync) + return; + + if ((cop_state.regtypes_modified & regtypes[addr & 0x1FE]) == 0) + return; + } + + eventtab[ev_copper].active = 0; + if (do_schedule) + events_schedule (); + set_special (SPCFLAG_COPPER); + } + if (copper_enabled_thisline) + update_copper (hpos); +} + +STATIC_INLINE uae_u16 sprite_fetch (struct sprite *s, int dma, int hpos, int cycle, int mode) +{ + uae_u16 data = last_custom_value; + if (dma) { + data = last_custom_value = chipmem_agnus_wget (s->pt); +#ifdef CPUEMU_6 + cycle_line[hpos] |= CYCLE_SPRITE; +#endif + } + s->pt += 2; + return data; +} + +STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) +{ + struct sprite *s = &spr[num]; + int dma, posctl = 0; + uae_u16 data; + + if (vpos == sprite_vblank_endline) + spr_arm (num, 0); + +#if SPRITE_DEBUG > 3 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) + write_log("%d:%d:slot%d:%d\n", vpos, hpos, num, cycle); +#endif + if (vpos == s->vstart) { +#if SPRITE_DEBUG > 0 + if (!s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) + write_log ("%d:%d:SPR%d START\n", vpos, hpos, num); +#endif + s->dmastate = 1; + } + if (vpos == s->vstop || vpos == sprite_vblank_endline) { +#if SPRITE_DEBUG > 0 + if (s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) + write_log ("%d:%d:SPR%d STOP\n", vpos, hpos, num); +#endif + s->dmastate = 0; + } + if (!dmaen (DMA_SPRITE)) + return; + if (cycle && !s->dmacycle) + return; /* Superfrog intro flashing bee fix */ + + + dma = hpos < plfstrt || diwstate != DIW_waiting_stop || !dmaen (DMA_BITPLANE); + if (vpos == s->vstop || vpos == sprite_vblank_endline) { + s->dmastate = 0; + posctl = 1; + if (dma) { + data = sprite_fetch (s, dma, hpos, cycle, 0); + switch (sprite_width) + { + case 64: + sprite_fetch (s, dma, hpos, cycle, 0); + sprite_fetch (s, dma, hpos, cycle, 0); + case 32: + sprite_fetch (s, dma, hpos, cycle, 0); + break; + } + } else { + data = cycle == 0 ? sprpos[num] : sprctl[num]; + } +#if SPRITE_DEBUG > 1 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + write_log ("%d:%d:dma:P=%06.6X ", vpos, hpos, s->pt); + } +#endif + //write_log ("%d:%d: %04.4X=%04.4X\n", vpos, hpos, 0x140 + cycle * 2 + num * 8, data); + if (cycle == 0) { + SPRxPOS_1 (data, num, hpos); + s->dmacycle = 1; + } else { + SPRxCTL_1 (data, num, hpos); + s->dmastate = 0; + sprstartstop (s); + } + } + if (s->dmastate && !posctl) { + uae_u16 data; + + data = sprite_fetch (s, dma, hpos, cycle, 1); + /* Hack for X mouse auto-calibration */ + if (num == 0 && cycle == 0) + mousehack_handle (sprctl[0], sprpos[0]); +#if SPRITE_DEBUG > 1 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + write_log ("%d:%d:dma:P=%06.6X ", vpos, hpos, s->pt); + } +#endif + if (cycle == 0) { + SPRxDATA_1 (dma ? data : sprdata[num][0], num, hpos); + s->dmacycle = 1; + } else { + SPRxDATB_1 (dma ? data : sprdatb[num][0], num, hpos); + spr_arm (num, 1); + } +#ifdef AGA + switch (sprite_width) + { + case 64: + { + uae_u16 data32 = sprite_fetch (s, dma, hpos, cycle, 1); + uae_u16 data641 = sprite_fetch (s, dma, hpos, cycle, 1); + uae_u16 data642 = sprite_fetch (s, dma, hpos, cycle, 1); + if (dma) { + if (cycle == 0) { + sprdata[num][3] = data642; + sprdata[num][2] = data641; + sprdata[num][1] = data32; + } else { + sprdatb[num][3] = data642; + sprdatb[num][2] = data641; + sprdatb[num][1] = data32; + } + } + } + break; + case 32: + { + uae_u16 data32 = sprite_fetch (s, dma, hpos, cycle, 1); + if (dma) { + if (cycle == 0) + sprdata[num][1] = data32; + else + sprdatb[num][1] = data32; + } + } + break; + } +#endif + } +} + +static void do_sprites (int hpos) +{ + int maxspr, minspr; + int i; + + /* I don't know whether this is right. Some programs write the sprite pointers + * directly at the start of the copper list. With the test against currvp, the + * first two words of data are read on the second line in the frame. The problem + * occurs when the program jumps to another copperlist a few lines further down + * which _also_ writes the sprite pointer registers. This means that a) writing + * to the sprite pointers sets the state to SPR_restart; or b) that sprite DMA + * is disabled until the end of the vertical blanking interval. The HRM + * isn't clear - it says that the vertical sprite position can be set to any + * value, but this wouldn't be the first mistake... */ + /* Update: I modified one of the programs to write the sprite pointers the + * second time only _after_ the VBlank interval, and it showed the same behaviour + * as it did unmodified under UAE with the above check. This indicates that the + * solution below is correct. */ + /* Another update: seems like we have to use the NTSC value here (see Sanity Turmoil + * demo). */ + /* Maximum for Sanity Turmoil: 27. + Minimum for Sanity Arte: 22. */ + if (vpos < sprite_vblank_endline) + return; + +#ifndef CUSTOM_SIMPLE + maxspr = hpos; + minspr = last_sprite_hpos; + + if (minspr >= SPR0_HPOS + MAX_SPRITES * 4 || maxspr < SPR0_HPOS) + return; + + if (maxspr > SPR0_HPOS + MAX_SPRITES * 4) + maxspr = SPR0_HPOS + MAX_SPRITES * 4; + if (minspr < SPR0_HPOS) + minspr = SPR0_HPOS; + + for (i = minspr; i < maxspr; i++) { + int cycle = -1; + int num = (i - SPR0_HPOS) / 4; + switch ((i - SPR0_HPOS) & 3) + { + case 0: + cycle = 0; + spr[num].dmacycle = 0; + break; + case 2: + cycle = 1; + break; + } + if (cycle >= 0) + do_sprites_1 (num, cycle, i); + } + last_sprite_hpos = hpos; +#else + for (i = 0; i < MAX_SPRITES * 2; i++) { + spr[i / 2].dmacycle = 1; + do_sprites_1 (i / 2, i & 1, 0); + } +#endif +} + +static void init_sprites (void) +{ + memset (sprpos, 0, sizeof sprpos); + memset (sprctl, 0, sizeof sprctl); +} + +static void adjust_array_sizes (void) +{ +#ifdef OS_WITHOUT_MEMORY_MANAGEMENT + if (delta_sprite_entry) { + void *p1,*p2; + int mcc = max_sprite_entry + 50 + delta_sprite_entry; + delta_sprite_entry = 0; + p1 = realloc (sprite_entries[0], mcc * sizeof (struct sprite_entry)); + p2 = realloc (sprite_entries[1], mcc * sizeof (struct sprite_entry)); + if (p1) sprite_entries[0] = p1; + if (p2) sprite_entries[1] = p2; + if (p1 && p2) { + write_log ("new max_sprite_entry=%d\n",mcc); + max_sprite_entry = mcc; + } + } + if (delta_color_change) { + void *p1,*p2; + int mcc = max_color_change + 200 + delta_color_change; + delta_color_change = 0; + p1 = realloc (color_changes[0], mcc * sizeof (struct color_change)); + p2 = realloc (color_changes[1], mcc * sizeof (struct color_change)); + if (p1) color_changes[0] = p1; + if (p2) color_changes[1] = p2; + if (p1 && p2) { + write_log ("new max_color_change=%d\n",mcc); + max_color_change = mcc; + } + } +#endif +} + +static void init_hardware_frame (void) +{ + next_lineno = 0; + nextline_how = nln_normal; + diwstate = DIW_waiting_start; + hdiwstate = DIW_waiting_start; + ddfstate = DIW_waiting_start; +} + +void init_hardware_for_drawing_frame (void) +{ + adjust_array_sizes (); + + /* Avoid this code in the first frame after a customreset. */ + if (prev_sprite_entries) { + int first_pixel = prev_sprite_entries[0].first_pixel; + int npixels = prev_sprite_entries[prev_next_sprite_entry].first_pixel - first_pixel; + memset (spixels + first_pixel, 0, npixels * sizeof *spixels); + memset (spixstate.bytes + first_pixel, 0, npixels * sizeof *spixstate.bytes); + } + prev_next_sprite_entry = next_sprite_entry; + + next_color_change = 0; + next_sprite_entry = 0; + next_color_entry = 0; + remembered_color_entry = -1; + + prev_sprite_entries = sprite_entries[current_change_set]; + curr_sprite_entries = sprite_entries[current_change_set ^ 1]; + prev_color_changes = color_changes[current_change_set]; + curr_color_changes = color_changes[current_change_set ^ 1]; + prev_color_tables = color_tables[current_change_set]; + curr_color_tables = color_tables[current_change_set ^ 1]; + + prev_drawinfo = line_drawinfo[current_change_set]; + curr_drawinfo = line_drawinfo[current_change_set ^ 1]; + current_change_set ^= 1; + + color_src_match = color_dest_match = -1; + + /* Use both halves of the array in alternating fashion. */ + curr_sprite_entries[0].first_pixel = current_change_set * MAX_SPR_PIXELS; + next_sprite_forced = 1; +} + +static void do_savestate(void); + +static int rpt_vsync (void) +{ + int v = read_processor_time () - vsyncmintime; + if (v > (int)syncbase || v < -((int)syncbase)) { + vsyncmintime = read_processor_time(); + v = 0; + } + return v; +} + +static void framewait (void) +{ + frame_time_t curr_time; + int start; + + for (;;) { + double v = rpt_vsync () / (syncbase / 1000.0); + if (v >= -4) + break; + sleep_millis_busy (2); + } + curr_time = start = read_processor_time(); + if (!isvsync()) { + do { + curr_time = read_processor_time (); + } while (rpt_vsync () < 0); + } + vsyncmintime = curr_time + vsynctime; + idletime += read_processor_time() - start; +} + +static int frametime2; + +void fpscounter_reset (void) +{ + timeframes = 0; + frametime2 = 0; + bogusframe = 2; + lastframetime = read_processor_time (); + idletime = 0; +} + +static void fpscounter (void) +{ + int now, last; + + now = read_processor_time (); + last = now - lastframetime; + lastframetime = now; + + if (bogusframe) + return; + + frametime += last; + frametime2 += last; + timeframes++; + if ((timeframes & 31) == 0) { + double idle = 1000 - (idletime == 0 ? 0.0 : (double)idletime * 1000.0 / (vsynctime * 32.0)); + int fps = frametime2 == 0 ? 0 : syncbase * 32 / (frametime2 / 10); + if (fps > 9999) + fps = 9999; + if (idle < 0) + idle = 0; + if (idle > 100 * 10) + idle = 100 * 10; + if (fake_vblank_hz * 10 > fps) { + double mult = (double)fake_vblank_hz * 10.0 / fps; + idle *= mult; + } + if (turbo_emulation && idle < 100 * 10) + idle = 100 * 10; + gui_fps (fps, (int)idle); + frametime2 = 0; + idletime = 0; + } +} + +static void vsync_handler (void) +{ + fpscounter (); + + if (!isvsync() +#ifdef AVIOUTPUT + && ((avioutput_framelimiter && avioutput_enabled) || !avioutput_enabled) +#endif + ) { +#ifdef JIT + if (!compiled_code) { +#endif + if (currprefs.m68k_speed == -1) { + frame_time_t curr_time = read_processor_time (); + vsyncmintime += vsynctime; + /* @@@ Mathias? How do you think we should do this? */ + /* If we are too far behind, or we just did a reset, adjust the + * needed time. */ + if ((long int)(curr_time - vsyncmintime) > 0 || rpt_did_reset) + vsyncmintime = curr_time + vsynctime; + rpt_did_reset = 0; + } else if (rpt_available) { + framewait (); + } +#ifdef JIT + } else { + if (rpt_available && currprefs.m68k_speed == 0) { + framewait (); + } + } +#endif + } + + if (bogusframe > 0) + bogusframe--; + + handle_events (); + + INTREQ (0x8020); + if (bplcon0 & 4) + lof ^= 0x8000; + +#ifdef PICASSO96 + /* And now let's update the Picasso palette, if required */ + DX_SetPalette_vsync(); + if (picasso_on) + picasso_handle_vsync (); +#endif + + vsync_handle_redraw (lof, lof_changed); + + if (quit_program > 0) { + /* prevent possible infinite loop at wait_cycles().. */ + framecnt = 0; + reset_decisions (); + return; + } + + { + static int cnt = 0; + if (cnt == 0) { + /* resolution_check_change (); */ + DISK_check_change (); + cnt = 5; + } + cnt--; + } + + /* Start a new set of copper records. */ + curr_cop_set ^= 1; + nr_cop_records[curr_cop_set] = 0; + + /* For now, let's only allow this to change at vsync time. It gets too + * hairy otherwise. */ + if ((beamcon0 & (0x20|0x80)) != (new_beamcon0 & (0x20|0x80)) || hack_vpos) + init_hz (); + + lof_changed = 0; + + eventtab[ev_copper].active = 0; + COPJMP (1); + + init_hardware_frame (); + + if (timehack_alive > 0) + timehack_alive--; + inputdevice_vsync (); +} + +#ifdef JIT + +#define N_LINES 8 + +static __inline__ int trigger_frh(int v) +{ + return (v & (N_LINES - 1)) == 0; +} + +extern int gonebad; + +static long int diff32(frame_time_t x, frame_time_t y) +{ + return (long int)(x-y); +} +static void frh_handler(void) +{ + if (currprefs.m68k_speed == -1) { + frame_time_t curr_time = read_processor_time (); + vsyncmintime += vsynctime * N_LINES / maxvpos; + /* @@@ Mathias? How do you think we should do this? */ + /* If we are too far behind, or we just did a reset, adjust the + * needed time. */ + if (rpt_did_reset) { + vsyncmintime = curr_time + vsynctime; + rpt_did_reset = 0; + } + /* Allow this to be one frame's worth of cycles out */ + while (diff32 (curr_time, vsyncmintime + vsynctime) > 0) { + vsyncmintime += vsynctime * N_LINES / maxvpos; + gonebad++; + if (turbo_emulation) + break; + } + } +} +#endif + +static void copper_check (int n) +{ + if (cop_state.state == COP_wait) { + int vp = vpos & (((cop_state.saved_i2 >> 8) & 0x7F) | 0x80); + if (vp < cop_state.vcmp) { + if (eventtab[ev_copper].active || copper_enabled_thisline) + write_log ("COPPER BUG %d: vp=%d vpos=%d vcmp=%d act=%d thisline=%d\n", n, vp, vpos, cop_state.vcmp, eventtab[ev_copper].active, copper_enabled_thisline); + } + } +} + +static void hsync_handler (void) +{ + static int ciahsync; + int hpos = current_hpos (); + + /* Using 0x8A makes sure that we don't accidentally trip over the + modified_regtypes check. */ + sync_copper_with_cpu (maxhpos, 0, 0x8A); + + //copper_check (1); + + finish_decisions (); + if (thisline_decision.plfleft != -1) { + if (currprefs.collision_level > 1) + do_sprite_collisions (); + if (currprefs.collision_level > 2) + do_playfield_collisions (); + } + hsync_record_line_state (next_lineno, nextline_how, thisline_changed); + + eventtab[ev_hsync].evtime += get_cycles () - eventtab[ev_hsync].oldcycles; + eventtab[ev_hsync].oldcycles = get_cycles (); + CIA_hsync_handler (); +#ifdef CD32 + AKIKO_hsync_handler (); +#endif + +#ifdef PICASSO96 + picasso_handle_hsync (); +#endif + + ciahsync++; + if (ciahsync >= (currprefs.ntscmode ? MAXVPOS_NTSC : MAXVPOS_PAL) * MAXHPOS_PAL / maxhpos) { /* not so perfect.. */ + CIA_vsync_handler (); + ciahsync = 0; + } + +#ifdef CPUEMU_6 + if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) { + decide_blitter (hpos); + memset (cycle_line, 0, MAXHPOS); +#if 1 +{ + cycle_line[maxhpos - 1] = CYCLE_REFRESH; + cycle_line[2] = CYCLE_REFRESH; + cycle_line[4] = CYCLE_REFRESH; + cycle_line[6] = CYCLE_REFRESH; +} +#else +{ + int i; + for (i = 12; i < 0x16; i += 2) + cycle_line[i] = CYCLE_NOCPU; + cycle_line[4] = CYCLE_REFRESH; + cycle_line[6] = CYCLE_REFRESH; + cycle_line[8] = CYCLE_REFRESH; + cycle_line[10] = CYCLE_REFRESH; +} +#endif + } +#endif + if ((currprefs.chipset_mask & CSMASK_AGA) || (!currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + last_custom_value = rand (); + else + last_custom_value = 0xffff; + + if (!currprefs.blitter_cycle_exact && bltstate != BLT_done && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) + blitter_slowdown (thisline_decision.plfleft, thisline_decision.plfright - (16 << fetchmode), + cycle_diagram_total_cycles[fmode][GET_RES (bplcon0)][GET_PLANES_LIMIT (bplcon0)], + cycle_diagram_free_cycles[fmode][GET_RES (bplcon0)][GET_PLANES_LIMIT (bplcon0)]); + + if (currprefs.produce_sound) + audio_hsync (1); + + hardware_line_completed (next_lineno); + + /* In theory only an equality test is needed here - but if a program + goes haywire with the VPOSW register, it can cause us to miss this, + with vpos going into the thousands (and all the nasty consequences + this has). */ + + if (++vpos >= (maxvpos + (lof == 0 ? 0 : 1))) { + vpos = 0; + vsync_handler (); + } + + DISK_hsync (maxhpos); + +#ifdef JIT + if (compiled_code) { + if (currprefs.m68k_speed == -1) { + static int count=0; + + count++; + if (trigger_frh(count)) { + frh_handler(); + } + is_lastline = trigger_frh(count+1) && ! rpt_did_reset; + } + else + is_lastline=0; + } else { +#endif + is_lastline = vpos + 1 == maxvpos + (lof == 0 ? 0 : 1) && currprefs.m68k_speed == -1 && ! rpt_did_reset; +#ifdef JIT + } +#endif + + if ((bplcon0 & 4) && currprefs.gfx_linedbl) + notice_interlace_seen (); + + if (!nodraw ()) { + int lineno = vpos; + nextline_how = nln_normal; + if (currprefs.gfx_linedbl) { + lineno *= 2; + nextline_how = currprefs.gfx_linedbl == 1 ? nln_doubled : nln_nblack; + if (bplcon0 & 4) { + if (!lof) { + lineno++; + nextline_how = nln_lower; + } else { + nextline_how = nln_upper; + } + } + } + next_lineno = lineno; + reset_decisions (); + } +#ifdef FILESYS + if (uae_int_requested) { + set_uae_int_flag (); + INTREQ (0x8000 | 0x0008); + } +#endif + /* See if there's a chance of a copper wait ending this line. */ + cop_state.hpos = 0; + cop_state.last_write = 0; + compute_spcflag_copper (); + inputdevice_hsync (); + serial_hsynchandler (); +#ifdef CUSTOM_SIMPLE + do_sprites (0); +#endif + //copper_check (2); +} + +static void init_regtypes (void) +{ + int i; + for (i = 0; i < 512; i += 2) { + regtypes[i] = REGTYPE_ALL; + if ((i >= 0x20 && i < 0x28) || i == 0x08 || i == 0x7E) + regtypes[i] = REGTYPE_DISK; + else if (i >= 0x68 && i < 0x70) + regtypes[i] = REGTYPE_NONE; + else if (i >= 0x40 && i < 0x78) + regtypes[i] = REGTYPE_BLITTER; + else if (i >= 0xA0 && i < 0xE0 && (i & 0xF) < 0xE) + regtypes[i] = REGTYPE_AUDIO; + else if (i >= 0xA0 && i < 0xE0) + regtypes[i] = REGTYPE_NONE; + else if (i >= 0xE0 && i < 0x100) + regtypes[i] = REGTYPE_PLANE; + else if (i >= 0x120 && i < 0x180) + regtypes[i] = REGTYPE_SPRITE; + else if (i >= 0x180 && i < 0x1C0) + regtypes[i] = REGTYPE_COLOR; + else switch (i) { + case 0x02: + /* DMACONR - setting this to REGTYPE_BLITTER will cause it to + conflict with DMACON (since that is REGTYPE_ALL), and the + blitter registers (for the BBUSY bit), but nothing else, + which is (I think) what we want. */ + regtypes[i] = REGTYPE_BLITTER; + break; + case 0x04: case 0x06: case 0x2A: case 0x2C: + regtypes[i] = REGTYPE_POS; + break; + case 0x0A: case 0x0C: + case 0x12: case 0x14: case 0x16: + case 0x36: + regtypes[i] = REGTYPE_JOYPORT; + break; + case 0x104: + case 0x102: + regtypes[i] = REGTYPE_PLANE; + break; + case 0x88: case 0x8A: + case 0x8E: case 0x90: case 0x92: case 0x94: + case 0x96: + case 0x100: + regtypes[i] |= REGTYPE_FORCE; + break; + } + } +} + +void init_eventtab (void) +{ + int i; + + nextevent = 0; + set_cycles (0); + for (i = 0; i < ev_max; i++) { + eventtab[i].active = 0; + eventtab[i].oldcycles = 0; + } + + eventtab[ev_cia].handler = CIA_handler; + eventtab[ev_hsync].handler = hsync_handler; + eventtab[ev_hsync].evtime = get_cycles () + HSYNCTIME; + eventtab[ev_hsync].active = 1; + + eventtab[ev_copper].handler = copper_handler; + eventtab[ev_copper].active = 0; + eventtab[ev_blitter].handler = blitter_handler; + eventtab[ev_blitter].active = 0; + eventtab[ev_disk].handler = DISK_handler; + eventtab[ev_disk].active = 0; + eventtab[ev_audio].handler = audio_evhandler; + eventtab[ev_audio].active = 0; + events_schedule (); +} + +void customreset (void) +{ + int i; + int zero = 0; + + write_log ("reset at %x\n", m68k_getpc()); + if (! savestate_state) { + currprefs.chipset_mask = changed_prefs.chipset_mask; + if ((currprefs.chipset_mask & CSMASK_AGA) == 0) { + for (i = 0; i < 32; i++) { + current_colors.color_regs_ecs[i] = 0; + current_colors.acolors[i] = xcolors[0]; + } +#ifdef AGA + } else { + for (i = 0; i < 256; i++) { + current_colors.color_regs_aga[i] = 0; + current_colors.acolors[i] = CONVERT_RGB (zero); + } +#endif + } + + clxdat = 0; + + /* Clear the armed flags of all sprites. */ + memset (spr, 0, sizeof spr); + nr_armed = 0; + + dmacon = intena = 0; + + copcon = 0; + DSKLEN (0, 0); + + bplcon0 = 0; + bplcon4 = 0x11; /* Get AGA chipset into ECS compatibility mode */ + bplcon3 = 0xC00; + + FMODE (0); + CLXCON (0); + } + +#ifdef AUTOCONFIG + expamem_reset (); +#endif + a1000_reset (); + DISK_reset (); + CIA_reset (); +#ifdef JIT + compemu_reset (); +#endif + unset_special (~(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)); + + vpos = 0; + + inputdevice_reset (); + timehack_alive = 0; + + curr_sprite_entries = 0; + prev_sprite_entries = 0; + sprite_entries[0][0].first_pixel = 0; + sprite_entries[1][0].first_pixel = MAX_SPR_PIXELS; + sprite_entries[0][1].first_pixel = 0; + sprite_entries[1][1].first_pixel = MAX_SPR_PIXELS; + memset (spixels, 0, sizeof spixels); + memset (&spixstate, 0, sizeof spixstate); + + bltstate = BLT_done; + cop_state.state = COP_stop; + diwstate = DIW_waiting_start; + hdiwstate = DIW_waiting_start; + set_cycles (0); + + new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; + hack_vpos = 0; + init_hz (); + + audio_reset (); + if (savestate_state != STATE_RESTORE) { + /* must be called after audio_reset */ + adkcon = 0; + serial_uartbreak (0); + update_adkmasks (); + } + + init_sprites (); + + init_hardware_frame (); + drawing_init (); + + reset_decisions (); + + bogusframe = 1; + + init_regtypes (); + + sprite_buffer_res = currprefs.chipset_mask & CSMASK_AGA ? RES_HIRES : RES_LORES; + if (savestate_state == STATE_RESTORE) { + uae_u16 v; + uae_u32 vv; + + update_adkmasks (); + INTENA (0); + INTREQ (0); +#if 0 + DMACON (0, 0); +#endif + COPJMP (1); + v = bplcon0; + BPLCON0 (0, 0); + BPLCON0 (0, v); + FMODE (fmode); + if (!(currprefs.chipset_mask & CSMASK_AGA)) { + for(i = 0 ; i < 32 ; i++) { + vv = current_colors.color_regs_ecs[i]; + current_colors.color_regs_ecs[i] = -1; + record_color_change (0, i, vv); + remembered_color_entry = -1; + current_colors.color_regs_ecs[i] = vv; + current_colors.acolors[i] = xcolors[vv]; + } +#ifdef AGA + } else { + for(i = 0 ; i < 256 ; i++) { + vv = current_colors.color_regs_aga[i]; + current_colors.color_regs_aga[i] = -1; + record_color_change (0, i, vv); + remembered_color_entry = -1; + current_colors.color_regs_aga[i] = vv; + current_colors.acolors[i] = CONVERT_RGB(vv); + } +#endif + } + CLXCON (clxcon); + CLXCON2 (clxcon2); + calcdiw (); + write_log ("State restored\n"); + dumpcustom (); + for (i = 0; i < 8; i++) + nr_armed += spr[i].armed != 0; + } + expand_sprres (); + + #ifdef ACTION_REPLAY + /* Doing this here ensures we can use the 'reset' command from within AR */ + action_replay_reset (); + #endif + #if defined(ENFORCER) + enforcer_disable(); + #endif +} + +void dumpcustom (void) +{ + write_log ("DMACON: %x INTENA: %x INTREQ: %x VPOS: %x HPOS: %x\n", DMACONR(), + (unsigned int)intena, (unsigned int)intreq, (unsigned int)vpos, (unsigned int)current_hpos()); + write_log ("COP1LC: %08lx, COP2LC: %08lx COPPTR: %08lx\n", (unsigned long)cop1lc, (unsigned long)cop2lc, cop_state.ip); + write_log ("DIWSTRT: %04x DIWSTOP: %04x DDFSTRT: %04x DDFSTOP: %04x\n", + (unsigned int)diwstrt, (unsigned int)diwstop, (unsigned int)ddfstrt, (unsigned int)ddfstop); + write_log ("BPLCON 0: %04x 1: %04x 2: %04x 3: %04x 4: %04x\n", bplcon0, bplcon1, bplcon2, bplcon3, bplcon4); + if (timeframes) { + write_log ("Average frame time: %f ms [frames: %d time: %d]\n", + (double)frametime / timeframes, timeframes, frametime); + if (total_skipped) + write_log ("Skipped frames: %d\n", total_skipped); + } + /*for (i=0; i<256; i++) if (blitcount[i]) write_log ("minterm %x = %d\n",i,blitcount[i]); blitter debug */ +} + +static void gen_custom_tables (void) +{ + int i; + for (i = 0; i < 256; i++) { + sprtaba[i] = ((((i >> 7) & 1) << 0) + | (((i >> 6) & 1) << 2) + | (((i >> 5) & 1) << 4) + | (((i >> 4) & 1) << 6) + | (((i >> 3) & 1) << 8) + | (((i >> 2) & 1) << 10) + | (((i >> 1) & 1) << 12) + | (((i >> 0) & 1) << 14)); + sprtabb[i] = sprtaba[i] * 2; + sprite_ab_merge[i] = (((i & 15) ? 1 : 0) + | ((i & 240) ? 2 : 0)); + } + for (i = 0; i < 16; i++) { + clxmask[i] = (((i & 1) ? 0xF : 0x3) + | ((i & 2) ? 0xF0 : 0x30) + | ((i & 4) ? 0xF00 : 0x300) + | ((i & 8) ? 0xF000 : 0x3000)); + sprclx[i] = (((i & 0x3) == 0x3 ? 1 : 0) + | ((i & 0x5) == 0x5 ? 2 : 0) + | ((i & 0x9) == 0x9 ? 4 : 0) + | ((i & 0x6) == 0x6 ? 8 : 0) + | ((i & 0xA) == 0xA ? 16 : 0) + | ((i & 0xC) == 0xC ? 32 : 0)) << 9; + } +} + +void custom_init (void) +{ + +#ifdef OS_WITHOUT_MEMORY_MANAGEMENT + int num; + + for (num = 0; num < 2; num++) { + sprite_entries[num] = xmalloc (max_sprite_entry * sizeof (struct sprite_entry)); + color_changes[num] = xmalloc (max_color_change * sizeof (struct color_change)); + } +#endif + +#ifdef AUTOCONFIG + { + uaecptr pos; + pos = here (); + + org (RTAREA_BASE+0xFF70); + calltrap (deftrap (mousehack_helper)); + dw (RTS); + + org (RTAREA_BASE+0xFFA0); + calltrap (deftrap (timehack_helper)); + dw (RTS); + + org (pos); + } +#endif + + gen_custom_tables (); + build_blitfilltable (); + + drawing_init (); + + mousehack_set (mousehack_unknown); + if (needmousehack ()) + mousehack_set (mousehack_follow); + + create_cycle_diagram_table (); +} + +/* Custom chip memory bank */ + +static uae_u32 custom_lget (uaecptr) REGPARAM; +static uae_u32 custom_wget (uaecptr) REGPARAM; +static uae_u32 custom_bget (uaecptr) REGPARAM; +static void custom_lput (uaecptr, uae_u32) REGPARAM; +static void custom_wput (uaecptr, uae_u32) REGPARAM; +static void custom_bput (uaecptr, uae_u32) REGPARAM; + +addrbank custom_bank = { + custom_lget, custom_wget, custom_bget, + custom_lput, custom_wput, custom_bput, + default_xlate, default_check, NULL +}; + +STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (uaecptr addr, int noput) +{ + uae_u16 v; +#ifdef JIT + special_mem |= S_READ; +#endif + addr &= 0xfff; +#ifdef CUSTOM_DEBUG + write_log ("%d:%d:wget: %04.4X=%04.4X pc=%p\n", current_hpos(), vpos, addr, addr & 0x1fe, m68k_getpc()); +#endif + switch (addr & 0x1fe) { + case 0x002: v = DMACONR (); break; + case 0x004: v = VPOSR (); break; + case 0x006: v = VHPOSR (); break; + + case 0x00A: v = JOY0DAT (); break; + case 0x00C: v = JOY1DAT (); break; + case 0x00E: v = CLXDAT (); break; + case 0x010: v = ADKCONR (); break; + + case 0x012: v = POT0DAT (); break; + case 0x014: v = POT1DAT (); break; + case 0x016: v = POTGOR (); break; + case 0x018: v = SERDATR (); break; + case 0x01A: v = DSKBYTR (current_hpos ()); break; + case 0x01C: v = INTENAR (); break; + case 0x01E: v = INTREQR (); break; + case 0x07C: v = DENISEID (); break; + + case 0x02E: v = 0xffff; break; /* temporary hack */ + +#ifdef AGA + case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: + case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: + case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2: + case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE: + case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA: + case 0x1BC: case 0x1BE: + v = COLOR_READ ((addr & 0x3E) / 2); + break; +#endif + + default: + /* reading write-only register causes write with last value in bus */ + v = last_custom_value; + if (!noput) { + int r; + int hpos = current_hpos (); + decide_line (hpos); + decide_fetch (hpos); + decide_blitter (hpos); + v = last_custom_value; + r = custom_wput_1 (hpos, addr, v, 1); + } + return v; + } + return v; +} + + STATIC_INLINE custom_wget2 (uaecptr addr) + { + uae_u32 v; + sync_copper_with_cpu (current_hpos (), 1, addr); + if (currprefs.cpu_level >= 2) { + if(addr >= 0xde0000 && addr <= 0xdeffff) { + return 0x7f7f; + } + if(addr >= 0xdd0000 && addr <= 0xddffff) { + return 0xffff; + } + } + v = custom_wget_1 (addr, 0); +#ifdef ACTION_REPLAY +#ifdef ACTION_REPLAY_COMMON + addr &= 0x1ff; + ar_custom[addr + 0] = (uae_u8)(v >> 8); + ar_custom[addr + 1] = (uae_u8)(v); +#endif +#endif + return v; +} + +uae_u32 REGPARAM2 custom_wget (uaecptr addr) +{ + uae_u32 v; + + if (addr & 1) { + /* think about move.w $dff005,d0.. (68020+ only) */ + addr &= ~1; + v = custom_wget2 (addr) << 8; + v |= custom_wget2 (addr + 2) >> 8; + return v; + } + return custom_wget2 (addr); + } + +uae_u32 REGPARAM2 custom_bget (uaecptr addr) +{ +#ifdef JIT + special_mem |= S_READ; +#endif + return custom_wget2 (addr & ~1) >> (addr & 1 ? 0 : 8); +} + +uae_u32 REGPARAM2 custom_lget (uaecptr addr) +{ +#ifdef JIT + special_mem |= S_READ; +#endif + return ((uae_u32)custom_wget (addr) << 16) | custom_wget (addr + 2); +} + +int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int noget) +{ + addr &= 0x1FE; + value &= 0xffff; +#ifdef ACTION_REPLAY +#ifdef ACTION_REPLAY_COMMON + ar_custom[addr+0]=(uae_u8)(value>>8); + ar_custom[addr+1]=(uae_u8)(value); +#endif +#endif + last_custom_value = value; + switch (addr) { + case 0x00E: CLXDAT (); break; + + case 0x020: DSKPTH (value); break; + case 0x022: DSKPTL (value); break; + case 0x024: DSKLEN (value, hpos); break; + case 0x026: DSKDAT (value); break; + + case 0x02A: VPOSW (value); break; + case 0x02E: COPCON (value); break; + case 0x030: SERDAT (value); break; + case 0x032: SERPER (value); break; + case 0x034: POTGO (value); break; + case 0x040: BLTCON0 (value); break; + case 0x042: BLTCON1 (value); break; + + case 0x044: BLTAFWM (value); break; + case 0x046: BLTALWM (value); break; + + case 0x050: BLTAPTH (value); break; + case 0x052: BLTAPTL (value); break; + case 0x04C: BLTBPTH (value); break; + case 0x04E: BLTBPTL (value); break; + case 0x048: BLTCPTH (value); break; + case 0x04A: BLTCPTL (value); break; + case 0x054: BLTDPTH (value); break; + case 0x056: BLTDPTL (value); break; + + case 0x058: BLTSIZE (value); break; + + case 0x064: BLTAMOD (value); break; + case 0x062: BLTBMOD (value); break; + case 0x060: BLTCMOD (value); break; + case 0x066: BLTDMOD (value); break; + + case 0x070: BLTCDAT (value); break; + case 0x072: BLTBDAT (value); break; + case 0x074: BLTADAT (value); break; + + case 0x07E: DSKSYNC (hpos, value); break; + + case 0x080: COP1LCH (value); break; + case 0x082: COP1LCL (value); break; + case 0x084: COP2LCH (value); break; + case 0x086: COP2LCL (value); break; + + case 0x088: COPJMP (1); break; + case 0x08A: COPJMP (2); break; + + case 0x08E: DIWSTRT (hpos, value); break; + case 0x090: DIWSTOP (hpos, value); break; + case 0x092: DDFSTRT (hpos, value); break; + case 0x094: DDFSTOP (hpos, value); break; + + case 0x096: DMACON (hpos, value); break; + case 0x098: CLXCON (value); break; + case 0x09A: INTENA (value); break; + case 0x09C: INTREQ (value); break; + case 0x09E: ADKCON (hpos, value); break; + + case 0x0A0: AUDxLCH (0, value); break; + case 0x0A2: AUDxLCL (0, value); break; + case 0x0A4: AUDxLEN (0, value); break; + case 0x0A6: AUDxPER (0, value); break; + case 0x0A8: AUDxVOL (0, value); break; + case 0x0AA: AUDxDAT (0, value); break; + + case 0x0B0: AUDxLCH (1, value); break; + case 0x0B2: AUDxLCL (1, value); break; + case 0x0B4: AUDxLEN (1, value); break; + case 0x0B6: AUDxPER (1, value); break; + case 0x0B8: AUDxVOL (1, value); break; + case 0x0BA: AUDxDAT (1, value); break; + + case 0x0C0: AUDxLCH (2, value); break; + case 0x0C2: AUDxLCL (2, value); break; + case 0x0C4: AUDxLEN (2, value); break; + case 0x0C6: AUDxPER (2, value); break; + case 0x0C8: AUDxVOL (2, value); break; + case 0x0CA: AUDxDAT (2, value); break; + + case 0x0D0: AUDxLCH (3, value); break; + case 0x0D2: AUDxLCL (3, value); break; + case 0x0D4: AUDxLEN (3, value); break; + case 0x0D6: AUDxPER (3, value); break; + case 0x0D8: AUDxVOL (3, value); break; + case 0x0DA: AUDxDAT (3, value); break; + + case 0x0E0: BPLxPTH (hpos, value, 0); break; + case 0x0E2: BPLxPTL (hpos, value, 0); break; + case 0x0E4: BPLxPTH (hpos, value, 1); break; + case 0x0E6: BPLxPTL (hpos, value, 1); break; + case 0x0E8: BPLxPTH (hpos, value, 2); break; + case 0x0EA: BPLxPTL (hpos, value, 2); break; + case 0x0EC: BPLxPTH (hpos, value, 3); break; + case 0x0EE: BPLxPTL (hpos, value, 3); break; + case 0x0F0: BPLxPTH (hpos, value, 4); break; + case 0x0F2: BPLxPTL (hpos, value, 4); break; + case 0x0F4: BPLxPTH (hpos, value, 5); break; + case 0x0F6: BPLxPTL (hpos, value, 5); break; + case 0x0F8: BPLxPTH (hpos, value, 6); break; + case 0x0FA: BPLxPTL (hpos, value, 6); break; + case 0x0FC: BPLxPTH (hpos, value, 7); break; + case 0x0FE: BPLxPTL (hpos, value, 7); break; + + case 0x100: BPLCON0 (hpos, value); break; + case 0x102: BPLCON1 (hpos, value); break; + case 0x104: BPLCON2 (hpos, value); break; +#ifdef AGA + case 0x106: BPLCON3 (hpos, value); break; +#endif + + case 0x108: BPL1MOD (hpos, value); break; + case 0x10A: BPL2MOD (hpos, value); break; +#ifdef AGA + case 0x10E: CLXCON2 (value); break; +#endif + + case 0x110: BPL1DAT (hpos, value); break; +#if 0 /* no point */ + case 0x112: BPL2DAT (value); break; + case 0x114: BPL3DAT (value); break; + case 0x116: BPL4DAT (value); break; + case 0x118: BPL5DAT (value); break; + case 0x11A: BPL6DAT (value); break; + case 0x11C: BPL7DAT (value); break; + case 0x11E: BPL8DAT (value); break; +#endif + + case 0x180: case 0x182: case 0x184: case 0x186: case 0x188: case 0x18A: + case 0x18C: case 0x18E: case 0x190: case 0x192: case 0x194: case 0x196: + case 0x198: case 0x19A: case 0x19C: case 0x19E: case 0x1A0: case 0x1A2: + case 0x1A4: case 0x1A6: case 0x1A8: case 0x1AA: case 0x1AC: case 0x1AE: + case 0x1B0: case 0x1B2: case 0x1B4: case 0x1B6: case 0x1B8: case 0x1BA: + case 0x1BC: case 0x1BE: + COLOR_WRITE (hpos, value & 0xFFF, (addr & 0x3E) / 2); + break; + case 0x120: case 0x124: case 0x128: case 0x12C: + case 0x130: case 0x134: case 0x138: case 0x13C: + SPRxPTH (hpos, value, (addr - 0x120) / 4); + break; + case 0x122: case 0x126: case 0x12A: case 0x12E: + case 0x132: case 0x136: case 0x13A: case 0x13E: + SPRxPTL (hpos, value, (addr - 0x122) / 4); + break; + case 0x140: case 0x148: case 0x150: case 0x158: + case 0x160: case 0x168: case 0x170: case 0x178: + SPRxPOS (hpos, value, (addr - 0x140) / 8); + break; + case 0x142: case 0x14A: case 0x152: case 0x15A: + case 0x162: case 0x16A: case 0x172: case 0x17A: + SPRxCTL (hpos, value, (addr - 0x142) / 8); + break; + case 0x144: case 0x14C: case 0x154: case 0x15C: + case 0x164: case 0x16C: case 0x174: case 0x17C: + SPRxDATA (hpos, value, (addr - 0x144) / 8); + break; + case 0x146: case 0x14E: case 0x156: case 0x15E: + case 0x166: case 0x16E: case 0x176: case 0x17E: + SPRxDATB (hpos, value, (addr - 0x146) / 8); + break; + + case 0x36: JOYTEST (value); break; + case 0x5A: BLTCON0L (value); break; + case 0x5C: BLTSIZV (value); break; + case 0x5E: BLTSIZH (value); break; + case 0x1E4: DIWHIGH (hpos, value); break; +#ifdef AGA + case 0x10C: BPLCON4 (hpos, value); break; +#endif + +#ifndef CUSTOM_SIMPLE + case 0x1DC: BEAMCON0 (value); break; + case 0x1C0: if (htotal != value) { htotal = value; varsync (); } break; + case 0x1C2: if (hsstop != value) { hsstop = value; varsync (); } break; + case 0x1C4: if (hbstrt != value) { hbstrt = value; varsync (); } break; + case 0x1C6: if (hbstop != value) { hbstop = value; varsync (); } break; + case 0x1C8: if (vtotal != value) { vtotal = value; varsync (); } break; + case 0x1CA: if (vsstop != value) { vsstop = value; varsync (); } break; + case 0x1CC: if (vbstrt != value) { vbstrt = value; varsync (); } break; + case 0x1CE: if (vbstop != value) { vbstop = value; varsync (); } break; + case 0x1DE: if (hsstrt != value) { hsstrt = value; varsync (); } break; + case 0x1E0: if (vsstrt != value) { vsstrt = value; varsync (); } break; + case 0x1E2: if (hcenter != value) { hcenter = value; varsync (); } break; +#endif + +#ifdef AGA + case 0x1FC: FMODE (value); break; +#endif + + /* writing to read-only register causes read access */ + default: + if (!noget) + custom_wget_1 (addr, 1); + if (!(currprefs.chipset_mask & CSMASK_AGA) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) + last_custom_value = 0xffff; + return 1; + } + return 0; +} + +void REGPARAM2 custom_wput (uaecptr addr, uae_u32 value) +{ + int hpos = current_hpos (); +#ifdef JIT + special_mem |= S_WRITE; +#endif +#ifdef CUSTOM_DEBUG + write_log ("%d:%d:wput: %04.4X %04.4X pc=%p\n", hpos, vpos, addr & 0x01fe, value & 0xffff, m68k_getpc()); +#endif + sync_copper_with_cpu (hpos, 1, addr); + custom_wput_1 (hpos, addr, value, 0); +} + +void REGPARAM2 custom_bput (uaecptr addr, uae_u32 value) +{ + static int warned; + /* Is this correct now? (There are people who bput things to the upper byte of AUDxVOL). */ + uae_u16 rval = (value << 8) | (value & 0xFF); +#ifdef JIT + special_mem |= S_WRITE; +#endif + custom_wput (addr & ~1, rval); + if (warned < 10) { + write_log ("Byte put to custom register %04.4X PC=%08.8X\n", addr, m68k_getpc()); + warned++; + } +} + +void REGPARAM2 custom_lput(uaecptr addr, uae_u32 value) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + custom_wput (addr & 0xfffe, value >> 16); + custom_wput ((addr + 2) & 0xfffe, (uae_u16)value); +} + +void custom_prepare_savestate (void) +{ +} + +#define RB restore_u8 () +#define RW restore_u16 () +#define RL restore_u32 () + +uae_u8 *restore_custom (uae_u8 *src) +{ + uae_u16 dsklen, dskbytr; + int dskpt; + int i; + + audio_reset (); + + changed_prefs.chipset_mask = currprefs.chipset_mask = RL; + RW; /* 000 ? */ + RW; /* 002 DMACONR */ + RW; /* 004 VPOSR */ + RW; /* 006 VHPOSR */ + RW; /* 008 DSKDATR (dummy register) */ + RW; /* 00A JOY0DAT */ + RW; /* 00C JOY1DAT */ + clxdat = RW; /* 00E CLXDAT */ + RW; /* 010 ADKCONR */ + RW; /* 012 POT0DAT* */ + RW; /* 014 POT1DAT* */ + RW; /* 016 POTINP* */ + RW; /* 018 SERDATR* */ + dskbytr = RW; /* 01A DSKBYTR */ + RW; /* 01C INTENAR */ + RW; /* 01E INTREQR */ + dskpt = RL; /* 020-022 DSKPT */ + dsklen = RW; /* 024 DSKLEN */ + RW; /* 026 DSKDAT */ + RW; /* 028 REFPTR */ + lof = RW; /* 02A VPOSW */ + RW; /* 02C VHPOSW */ + COPCON(RW); /* 02E COPCON */ + RW; /* 030 SERDAT* */ + RW; /* 032 SERPER* */ + POTGO(RW); /* 034 POTGO */ + RW; /* 036 JOYTEST* */ + RW; /* 038 STREQU */ + RW; /* 03A STRVHBL */ + RW; /* 03C STRHOR */ + RW; /* 03E STRLONG */ + BLTCON0(RW); /* 040 BLTCON0 */ + BLTCON1(RW); /* 042 BLTCON1 */ + BLTAFWM(RW); /* 044 BLTAFWM */ + BLTALWM(RW); /* 046 BLTALWM */ + BLTCPTH(RL); /* 048-04B BLTCPT */ + BLTBPTH(RL); /* 04C-04F BLTBPT */ + BLTAPTH(RL); /* 050-053 BLTAPT */ + BLTDPTH(RL); /* 054-057 BLTDPT */ + RW; /* 058 BLTSIZE */ + RW; /* 05A BLTCON0L */ + blt_info.vblitsize = RW; /* 05C BLTSIZV */ + blt_info.hblitsize = RW; /* 05E BLTSIZH */ + BLTCMOD(RW); /* 060 BLTCMOD */ + BLTBMOD(RW); /* 062 BLTBMOD */ + BLTAMOD(RW); /* 064 BLTAMOD */ + BLTDMOD(RW); /* 066 BLTDMOD */ + RW; /* 068 ? */ + RW; /* 06A ? */ + RW; /* 06C ? */ + RW; /* 06E ? */ + BLTCDAT(RW); /* 070 BLTCDAT */ + BLTBDAT(RW); /* 072 BLTBDAT */ + BLTADAT(RW); /* 074 BLTADAT */ + RW; /* 076 ? */ + RW; /* 078 ? */ + RW; /* 07A ? */ + RW; /* 07C LISAID */ + DSKSYNC(-1, RW); /* 07E DSKSYNC */ + cop1lc = RL; /* 080/082 COP1LC */ + cop2lc = RL; /* 084/086 COP2LC */ + RW; /* 088 ? */ + RW; /* 08A ? */ + RW; /* 08C ? */ + diwstrt = RW; /* 08E DIWSTRT */ + diwstop = RW; /* 090 DIWSTOP */ + ddfstrt = RW; /* 092 DDFSTRT */ + ddfstop = RW; /* 094 DDFSTOP */ + dmacon = RW & ~(0x2000|0x4000); /* 096 DMACON */ + CLXCON(RW); /* 098 CLXCON */ + intena = RW; /* 09A INTENA */ + intreq = RW; /* 09C INTREQ */ + adkcon = RW; /* 09E ADKCON */ + for (i = 0; i < 8; i++) + bplpt[i] = RL; + bplcon0 = RW; /* 100 BPLCON0 */ + bplcon1 = RW; /* 102 BPLCON1 */ + bplcon2 = RW; /* 104 BPLCON2 */ + bplcon3 = RW; /* 106 BPLCON3 */ + bpl1mod = RW; /* 108 BPL1MOD */ + bpl2mod = RW; /* 10A BPL2MOD */ + bplcon4 = RW; /* 10C BPLCON4 */ + clxcon2 = RW; /* 10E CLXCON2* */ + for(i = 0; i < 8; i++) + RW; /* BPLXDAT */ + for(i = 0; i < 32; i++) + current_colors.color_regs_ecs[i] = RW; /* 180 COLORxx */ + htotal = RW; /* 1C0 HTOTAL */ + RW; /* 1C2 ? */ + RW; /* 1C4 ? */ + RW; /* 1C6 ? */ + vtotal = RW; /* 1C8 VTOTAL */ + RW; /* 1CA ? */ + RW; /* 1CC ? */ + RW; /* 1CE ? */ + RW; /* 1D0 ? */ + RW; /* 1D2 ? */ + RW; /* 1D4 ? */ + RW; /* 1D6 ? */ + RW; /* 1D8 ? */ + RW; /* 1DA ? */ + new_beamcon0 = RW; /* 1DC BEAMCON0 */ + RW; /* 1DE ? */ + RW; /* 1E0 ? */ + RW; /* 1E2 ? */ + diwhigh = RW; /* 1E4 ? */ + if (diwhigh & 0x8000) + diwhigh_written = 1; + diwhigh &= 0x7fff; + RW; /* 1E6 ? */ + RW; /* 1E8 ? */ + RW; /* 1EA ? */ + RW; /* 1EC ? */ + RW; /* 1EE ? */ + RW; /* 1F0 ? */ + RW; /* 1F2 ? */ + RW; /* 1F4 ? */ + RW; /* 1F6 ? */ + RW; /* 1F8 ? */ + RW; /* 1FA ? */ + fmode = RW; /* 1FC FMODE */ + last_custom_value = RW; /* 1FE ? */ + + DISK_restore_custom (dskpt, dsklen, dskbytr); + + return src; +} + + +#define SB save_u8 +#define SW save_u16 +#define SL save_u32 + +extern uae_u16 serper; + +uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full) +{ + uae_u8 *dstbak, *dst; + int i; + uae_u32 dskpt; + uae_u16 dsklen, dsksync, dskbytr; + + DISK_save_custom (&dskpt, &dsklen, &dsksync, &dskbytr); + + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = malloc (8+256*2); + + SL (currprefs.chipset_mask); + SW (0); /* 000 ? */ + SW (dmacon); /* 002 DMACONR */ + SW (VPOSR()); /* 004 VPOSR */ + SW (VHPOSR()); /* 006 VHPOSR */ + SW (0); /* 008 DSKDATR */ + SW (JOY0DAT()); /* 00A JOY0DAT */ + SW (JOY1DAT()); /* 00C JOY1DAT */ + SW (clxdat); /* 00E CLXDAT */ + SW (ADKCONR()); /* 010 ADKCONR */ + SW (POT0DAT()); /* 012 POT0DAT */ + SW (POT0DAT()); /* 014 POT1DAT */ + SW (0) ; /* 016 POTINP * */ + SW (0); /* 018 SERDATR * */ + SW (dskbytr); /* 01A DSKBYTR */ + SW (INTENAR()); /* 01C INTENAR */ + SW (INTREQR()); /* 01E INTREQR */ + SL (dskpt); /* 020-023 DSKPT */ + SW (dsklen); /* 024 DSKLEN */ + SW (0); /* 026 DSKDAT */ + SW (0); /* 028 REFPTR */ + SW (lof); /* 02A VPOSW */ + SW (0); /* 02C VHPOSW */ + SW (copcon); /* 02E COPCON */ + SW (serper); /* 030 SERDAT * */ + SW (serdat); /* 032 SERPER * */ + SW (potgo_value); /* 034 POTGO */ + SW (0); /* 036 JOYTEST * */ + SW (0); /* 038 STREQU */ + SW (0); /* 03A STRVBL */ + SW (0); /* 03C STRHOR */ + SW (0); /* 03E STRLONG */ + SW (bltcon0); /* 040 BLTCON0 */ + SW (bltcon1); /* 042 BLTCON1 */ + SW (blt_info.bltafwm); /* 044 BLTAFWM */ + SW (blt_info.bltalwm); /* 046 BLTALWM */ + SL (bltcpt); /* 048-04B BLTCPT */ + SL (bltbpt); /* 04C-04F BLTCPT */ + SL (bltapt); /* 050-053 BLTCPT */ + SL (bltdpt); /* 054-057 BLTCPT */ + SW (0); /* 058 BLTSIZE */ + SW (0); /* 05A BLTCON0L (use BLTCON0 instead) */ + SW (blt_info.vblitsize); /* 05C BLTSIZV */ + SW (blt_info.hblitsize); /* 05E BLTSIZH */ + SW (blt_info.bltcmod); /* 060 BLTCMOD */ + SW (blt_info.bltbmod); /* 062 BLTBMOD */ + SW (blt_info.bltamod); /* 064 BLTAMOD */ + SW (blt_info.bltdmod); /* 066 BLTDMOD */ + SW (0); /* 068 ? */ + SW (0); /* 06A ? */ + SW (0); /* 06C ? */ + SW (0); /* 06E ? */ + SW (blt_info.bltcdat); /* 070 BLTCDAT */ + SW (blt_info.bltbdat); /* 072 BLTBDAT */ + SW (blt_info.bltadat); /* 074 BLTADAT */ + SW (0); /* 076 ? */ + SW (0); /* 078 ? */ + SW (0); /* 07A ? */ + SW (DENISEID()); /* 07C DENISEID/LISAID */ + SW (dsksync); /* 07E DSKSYNC */ + SL (cop1lc); /* 080-083 COP1LC */ + SL (cop2lc); /* 084-087 COP2LC */ + SW (0); /* 088 ? */ + SW (0); /* 08A ? */ + SW (0); /* 08C ? */ + SW (diwstrt); /* 08E DIWSTRT */ + SW (diwstop); /* 090 DIWSTOP */ + SW (ddfstrt); /* 092 DDFSTRT */ + SW (ddfstop); /* 094 DDFSTOP */ + SW (dmacon); /* 096 DMACON */ + SW (clxcon); /* 098 CLXCON */ + SW (intena); /* 09A INTENA */ + SW (intreq); /* 09C INTREQ */ + SW (adkcon); /* 09E ADKCON */ + for (i = 0; full && i < 32; i++) + SW (0); + for (i = 0; i < 8; i++) + SL (bplpt[i]); /* 0E0-0FE BPLxPT */ + SW (bplcon0); /* 100 BPLCON0 */ + SW (bplcon1); /* 102 BPLCON1 */ + SW (bplcon2); /* 104 BPLCON2 */ + SW (bplcon3); /* 106 BPLCON3 */ + SW (bpl1mod); /* 108 BPL1MOD */ + SW (bpl2mod); /* 10A BPL2MOD */ + SW (bplcon4); /* 10C BPLCON4 */ + SW (clxcon2); /* 10E CLXCON2 */ + for (i = 0;i < 8; i++) + SW (0); /* 110 BPLxDAT */ + if (full) { + for (i = 0; i < 8; i++) { + SL (spr[i].pt); /* 120-13E SPRxPT */ + SW (sprpos[i]); /* 1x0 SPRxPOS */ + SW (sprctl[i]); /* 1x2 SPRxPOS */ + SW (sprdata[i][0]); /* 1x4 SPRxDATA */ + SW (sprdatb[i][0]); /* 1x6 SPRxDATB */ + } + } + for ( i = 0; i < 32; i++) + SW (current_colors.color_regs_ecs[i]); /* 180-1BE COLORxx */ + SW (htotal); /* 1C0 HTOTAL */ + SW (0); /* 1C2 */ + SW (0); /* 1C4 */ + SW (0); /* 1C6 */ + SW (vtotal); /* 1C8 VTOTAL */ + SW (0); /* 1CA */ + SW (0); /* 1CC */ + SW (0); /* 1CE */ + SW (0); /* 1D0 */ + SW (0); /* 1D2 */ + SW (0); /* 1D4 */ + SW (0); /* 1D6 */ + SW (0); /* 1D8 */ + SW (0); /* 1DA */ + SW (beamcon0); /* 1DC BEAMCON0 */ + SW (0); /* 1DE */ + SW (0); /* 1E0 */ + SW (0); /* 1E2 */ + SW (diwhigh | (diwhigh_written ? 0x8000 : 0)); /* 1E4 */ + SW (0); /* 1E6 */ + SW (0); /* 1E8 */ + SW (0); /* 1EA */ + SW (0); /* 1EC */ + SW (0); /* 1EE */ + SW (0); /* 1F0 */ + SW (0); /* 1F2 */ + SW (0); /* 1F4 */ + SW (0); /* 1F6 */ + SW (0); /* 1F8 */ + SW (0); /* 1FA */ + SW (fmode); /* 1FC FMODE */ + SW (last_custom_value); /* 1FE */ + + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *restore_custom_agacolors (uae_u8 *src) +{ + int i; + + for (i = 0; i < 256; i++) +#ifdef AGA + current_colors.color_regs_aga[i] = RL; +#else + RL; +#endif + return src; +} + +uae_u8 *save_custom_agacolors (int *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak, *dst; + int i; + + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = malloc (256*4); + for (i = 0; i < 256; i++) +#ifdef AGA + SL (current_colors.color_regs_aga[i]); +#else + SL (0); +#endif + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *restore_custom_sprite (int num, uae_u8 *src) +{ + spr[num].pt = RL; /* 120-13E SPRxPT */ + sprpos[num] = RW; /* 1x0 SPRxPOS */ + sprctl[num] = RW; /* 1x2 SPRxPOS */ + sprdata[num][0] = RW; /* 1x4 SPRxDATA */ + sprdatb[num][0] = RW; /* 1x6 SPRxDATB */ + sprdata[num][1] = RW; + sprdatb[num][1] = RW; + sprdata[num][2] = RW; + sprdatb[num][2] = RW; + sprdata[num][3] = RW; + sprdatb[num][3] = RW; + spr[num].armed = RB; + return src; +} + +uae_u8 *save_custom_sprite(int num, int *len, uae_u8 *dstptr) +{ + uae_u8 *dstbak, *dst; + + if (dstptr) + dstbak = dst = dstptr; + else + dstbak = dst = malloc (25); + SL (spr[num].pt); /* 120-13E SPRxPT */ + SW (sprpos[num]); /* 1x0 SPRxPOS */ + SW (sprctl[num]); /* 1x2 SPRxPOS */ + SW (sprdata[num][0]); /* 1x4 SPRxDATA */ + SW (sprdatb[num][0]); /* 1x6 SPRxDATB */ + SW (sprdata[num][1]); + SW (sprdatb[num][1]); + SW (sprdata[num][2]); + SW (sprdatb[num][2]); + SW (sprdata[num][3]); + SW (sprdatb[num][3]); + SB (spr[num].armed ? 1 : 0); + *len = dst - dstbak; + return dstbak; +} + +void check_prefs_changed_custom (void) +{ + currprefs.gfx_framerate = changed_prefs.gfx_framerate; + if (inputdevice_config_change_test ()) { + inputdevice_copyconfig (&changed_prefs, &currprefs); + inputdevice_updateconfig (&currprefs); + } + currprefs.immediate_blits = changed_prefs.immediate_blits; + currprefs.collision_level = changed_prefs.collision_level; + currprefs.fast_copper = changed_prefs.fast_copper; + + if (currprefs.chipset_mask != changed_prefs.chipset_mask || + currprefs.gfx_vsync != changed_prefs.gfx_vsync || + currprefs.ntscmode != changed_prefs.ntscmode) { + currprefs.gfx_vsync = changed_prefs.gfx_vsync; + currprefs.chipset_mask = changed_prefs.chipset_mask; + if (currprefs.ntscmode != changed_prefs.ntscmode) { + currprefs.ntscmode = changed_prefs.ntscmode; + new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; + } + init_custom (); + } + currprefs.gfx_filter_horiz_zoom = changed_prefs.gfx_filter_horiz_zoom; + currprefs.gfx_filter_vert_zoom = changed_prefs.gfx_filter_vert_zoom; + currprefs.gfx_filter_horiz_offset = changed_prefs.gfx_filter_horiz_offset; + currprefs.gfx_filter_vert_offset = changed_prefs.gfx_filter_vert_offset; + currprefs.gfx_filter_scanlines = changed_prefs.gfx_filter_scanlines; + currprefs.gfx_filter_filtermode = changed_prefs.gfx_filter_filtermode; +} + +#ifdef CPUEMU_6 + +STATIC_INLINE void sync_copper (int hpos) +{ + if (eventtab[ev_copper].active) { + eventtab[ev_copper].active = 0; + update_copper (hpos); + return; + } + if (copper_enabled_thisline) + update_copper (hpos); +} + +STATIC_INLINE decide_fetch_ce (int hpos) +{ + if (ddf_change == vpos && vpos < maxvpos) + decide_fetch (hpos); +} + +STATIC_INLINE int dma_cycle(void) +{ + int hpos, cycles = 0, bnasty = 0; + + for (;;) { + int bpldma; + int blitpri = dmaen (DMA_BLITPRI); + do_cycles (1 * CYCLE_UNIT); + cycles += CYCLE_UNIT; + hpos = current_hpos (); + sync_copper (hpos); + decide_line (hpos); + decide_fetch_ce (hpos); + bpldma = is_bitplane_dma (hpos); + if (cycle_line[hpos] == 0 && !bpldma) { + if (bltstate == BLT_done || bnasty >= 3) + break; + decide_blitter (hpos); + if (cycle_line[hpos] == 0) + break; + if (!blitpri || blit_singlechannel) + bnasty++; + } else if (bpldma && (blit_singlechannel || !blitpri)) { + bnasty++; + } + /* bus was allocated to dma channel, wait for next cycle.. */ + } + cycle_line[hpos] |= CYCLE_CPU; + return cycles; +} + +uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode) +{ + uae_u32 v = 0; + dma_cycle (); + if (mode > 0) + v = get_word (addr); + else if (mode == 0) + v = get_byte (addr); + do_cycles (1 * CYCLE_UNIT); + return v; +} + +uae_u32 wait_cpu_cycle_read_cycles (uaecptr addr, int mode, int *cycles) +{ + uae_u32 v = 0; + *cycles = dma_cycle () + CYCLE_UNIT; + if (mode > 0) + v = get_word (addr); + else if (mode == 0) + v = get_byte (addr); + do_cycles (1 * CYCLE_UNIT); + return v; +} + +void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v) +{ + dma_cycle (); + if (mode > 0) + put_word (addr, v); + else if (mode == 0) + put_byte (addr, v); + do_cycles (1 * CYCLE_UNIT); +} + +void do_cycles_ce (long cycles) +{ + int hpos, bpldma; + while (cycles > 0) { + do_cycles (1 * CYCLE_UNIT); + cycles -= CYCLE_UNIT; + hpos = current_hpos (); + sync_copper (hpos); + decide_line (hpos); + decide_fetch_ce (hpos); + bpldma = is_bitplane_dma (hpos); + if (cycle_line[hpos] == 0 && !bpldma) + decide_blitter (hpos); + } +} + +#endif diff --git a/debug.c b/debug.c index 83256964..d92da773 100755 --- a/debug.c +++ b/debug.c @@ -100,7 +100,7 @@ static char help[] = { " T Show exec tasks and their PCs\n" " h,? Show this help page\n" " b Step to previous state capture position\n" - " am Enable or disable audio channels\n" + " am Enable or disable audio channels\n" " di [] Break on disk access. R=DMA read,W=write,RW=both,P=PIO\n" " q Quit the emulator. You don't want to use this command.\n\n" }; @@ -153,7 +153,7 @@ static uae_u32 readint (char **c) return readhex (c); } if (**c == '0' && toupper((*c)[1]) == 'X') { - (*c)+= 2; + (*c)+= 2; return readhex (c); } if (**c == '-') @@ -276,7 +276,7 @@ static void foundmod (uae_u32 ptr, char *type) ptr2 += 0x2A; for (i = 0; i < 31; i++, ptr2 += 30) length += 2*((ptr2[0]<<8)+ptr2[1]); - + console_out ("Name \"%s\", Length 0x%lx bytes.\n", name, length); } @@ -486,7 +486,7 @@ static uaecptr decode_copperlist (FILE* file, uaecptr address, int nolines) } return address; /* You may wonder why I don't stop this at the end of the copperlist? - * Well, often nice things are hidden at the end and it is debatable the actual + * Well, often nice things are hidden at the end and it is debatable the actual * values that mean the end of the copperlist */ } @@ -530,7 +530,7 @@ static void cheatsearch (char **c) } else { for (count = 0; count<255; count++) { if (p[vlist[count]+3] == (val & 0xff) - && p[vlist[count]+2] == (val>>8 & 0xff) + && p[vlist[count]+2] == (val>>8 & 0xff) && p[vlist[count]+1] == (val>>16 & 0xff) && p[vlist[count]] == (val>>24 & 0xff)) { @@ -647,15 +647,15 @@ static void illg_debug_do (uaecptr addr, int rw, int size, uae_u32 val) else write_log ("RW: %08.8X %c PC=%08.8X\n", ad, rws, pc); if (illgdebug_break) - activate_debugger (); + activate_debugger (); } else if ((mask & 1) && rw) { write_log ("RO: %08.8X=%02.2X %c PC=%08.8X\n", ad, v, rws, pc); if (illgdebug_break) - activate_debugger (); + activate_debugger (); } else if ((mask & 2) && !rw) { write_log ("WO: %08.8X %c PC=%08.8X\n", ad, rws, pc); if (illgdebug_break) - activate_debugger (); + activate_debugger (); } } } @@ -692,7 +692,7 @@ static void memwatch_func (uaecptr addr, int rw, int size, uae_u32 val) brk = 1; if (brk && mwnodes[i].modval_written) { if (!rw) { - brk = 0; + brk = 0; } else if (mwnodes[i].modval_written == 1) { mwnodes[i].modval_written = 2; mwnodes[i].modval = val; @@ -745,19 +745,19 @@ static void debug_lput (uaecptr addr, uae_u32 v) int off = debug_mem_off (addr); memwatch_func (addr, 1, 4, v); debug_mem_banks[off]->lput(addr, v); -} +} static void debug_wput (uaecptr addr, uae_u32 v) { int off = debug_mem_off (addr); memwatch_func (addr, 1, 2, v); debug_mem_banks[off]->wput(addr, v); -} +} static void debug_bput (uaecptr addr, uae_u32 v) { int off = debug_mem_off (addr); memwatch_func (addr, 1, 1, v); debug_mem_banks[off]->bput(addr, v); -} +} static int debug_check (uaecptr addr, uae_u32 size) { return debug_mem_banks[munge24 (addr) >> 16]->check (addr, size); @@ -1016,7 +1016,7 @@ static int instruction_breakpoint (char **c) console_out ("No breakpoints\n"); else console_out ("\n"); - return 0; + return 0; } skipaddr_doskip = 1; skipaddr_start = readhex (c); @@ -1040,15 +1040,15 @@ static int instruction_breakpoint (char **c) bpn->addr = skipaddr_start; bpn->enabled = 1; console_out ("Breakpoint added\n"); - skipaddr_start = 0xffffffff; - skipaddr_doskip = 0; + skipaddr_start = 0xffffffff; + skipaddr_doskip = 0; break; } return 0; } } if (skipaddr_start == 0xC0DEDBAD) { - trace_same_insn_count = 0; + trace_same_insn_count = 0; logfile = fopen ("uae.trace", "w"); memcpy (trace_insn_copy, regs.pc_p, 10); memcpy (&trace_prev_regs, ®s, sizeof regs); @@ -1188,14 +1188,14 @@ static void searchmem (char **cc) if (!got) console_out ("nothing found"); console_out ("\n"); -} +} static int staterecorder (char **cc) { char nc; if (!more_params (cc)) { - if (savestate_dorewind (1)) { + if (savestate_dorewind (1)) { debug_rewind = 1; return 1; } @@ -1244,7 +1244,7 @@ static void m68k_modify (char **inptr) uae_u32 v; char parm[10]; char c1, c2; - + if (!next_string (inptr, parm, sizeof (parm), 1)) return; c1 = toupper (parm[0]); @@ -1296,7 +1296,7 @@ static void debug_1 (void) console_out (">"); console_flush (); - if (!console_get (input, 80)) + if (!console_get (input, 80)) continue; inptr = input; cmd = next_char (&inptr); @@ -1310,7 +1310,7 @@ static void debug_1 (void) m68k_dumpstate (stdout, &nextpc); break; case 'M': modulesearch (); break; - case 'C': cheatsearch (&inptr); break; + case 'C': cheatsearch (&inptr); break; case 'W': writeintomem (&inptr); break; case 'w': memwatch (&inptr); break; case 'S': savemem (&inptr); break; @@ -1327,7 +1327,7 @@ static void debug_1 (void) next_char(&inptr); disk_debug(&inptr); } else { - uae_u32 daddr; + uae_u32 daddr; int count; if (more_params(&inptr)) daddr = readhex(&inptr); @@ -1404,9 +1404,9 @@ static void debug_1 (void) temp--; } while (temp != lasthist) { - regs = history[temp]; + regs = history[temp]; regflags = historyf[temp]; - m68k_setpc(history[temp].pc); + m68k_setpc(history[temp].pc); if (badly) { m68k_dumpstate(stdout, NULL); } else { @@ -1438,11 +1438,11 @@ static void debug_1 (void) { uae_u32 maddr; int lines; - + if (more_params(&inptr)) { maddr = readhex(&inptr); if (maddr == 1 || maddr == 2) - maddr = get_copper_address (maddr); + maddr = get_copper_address (maddr); } else maddr = nxcopper; @@ -1469,7 +1469,7 @@ static void debug_1 (void) break; case 'b': if (staterecorder (&inptr)) - return; + return; break; case 'a': if (more_params (&inptr)) { @@ -1534,7 +1534,7 @@ void debug (void) int bp = 0; for (i = 0; i < BREAKPOINT_TOTAL; i++) { - if (!bpnodes[i].enabled) + if (!bpnodes[i].enabled) continue; if (bpnodes[i].addr == pc) { bp = 1; @@ -1562,12 +1562,12 @@ void debug (void) } } if (!bp) { - set_special (SPCFLAG_BRK); + set_special (SPCFLAG_BRK); return; } } } else { - write_log ("Memwatch %d: break at %08.8X.%c %c %08.8X\n", memwatch_triggered - 1, mwhit.addr, + write_log ("Memwatch %d: break at %08.8X.%c %c %08.8X\n", memwatch_triggered - 1, mwhit.addr, mwhit.size == 1 ? 'B' : (mwhit.size == 2 ? 'W' : 'L'), mwhit.rw ? 'W' : 'R', mwhit.val); memwatch_triggered = 0; } @@ -1607,7 +1607,7 @@ void debug (void) do_skip = 1; } if (do_skip) { - set_special (SPCFLAG_BRK); + set_special (SPCFLAG_BRK); debugging = 1; } resume_sound (); diff --git a/dms/getbits.c b/dms/getbits.c index d4749770..bfaa835c 100755 --- a/dms/getbits.c +++ b/dms/getbits.c @@ -3,7 +3,7 @@ * xDMS v1.3 - Portable DMS archive unpacker - Public Domain * Written by Andre Rodrigues de la Rocha * Functions/macros to get a variable number of bits - * + * */ #include "cdata.h" @@ -29,6 +29,6 @@ void initbitbuf(UCHAR *in){ bitcount = 0; indata = in; DROPBITS(0); -} +} diff --git a/dms/pfile.c b/dms/pfile.c index f7c2204a..1a129a57 100755 --- a/dms/pfile.c +++ b/dms/pfile.c @@ -95,7 +95,7 @@ USHORT DMS_Process_File(struct zfile *fi, struct zfile *fo, USHORT cmd, USHORT o free(text); return ERR_HCRC; } - + geninfo = (USHORT) ((b1[10]<<8) | b1[11]); /* General info about archive */ date = (time_t) ((((ULONG)b1[12])<<24) | (((ULONG)b1[13])<<16) | (((ULONG)b1[14])<<8) | (ULONG)b1[15]); /* date in standard UNIX/ANSI format */ from = (USHORT) ((b1[16]<<8) | b1[17]); /* Lowest track in archive. May be incorrect if archive is "appended" */ @@ -289,7 +289,7 @@ static USHORT Process_Track(struct zfile *fi, struct zfile *fo, UCHAR *b1, UCHAR if ((cmd == CMD_UNPACK) && (number<80) && (unpklen>2048)) { r = Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags); - if (r != NO_PROBLEM) + if (r != NO_PROBLEM) if (pwd) return ERR_BADPASSWD; else @@ -304,7 +304,7 @@ static USHORT Process_Track(struct zfile *fi, struct zfile *fo, UCHAR *b1, UCHAR if ((cmd == CMD_SHOWBANNER) && (number == 0xffff)){ r = Unpack_Track(b1, b2, pklen2, unpklen, cmode, flags); - if (r != NO_PROBLEM) + if (r != NO_PROBLEM) if (pwd) return ERR_BADPASSWD; else diff --git a/dms/u_heavy.c b/dms/u_heavy.c index fff93d36..d717bb59 100755 --- a/dms/u_heavy.c +++ b/dms/u_heavy.c @@ -3,7 +3,7 @@ * xDMS v1.3 - Portable DMS archive unpacker - Public Domain * Written by Andre Rodrigues de la Rocha * - * Lempel-Ziv-Huffman decompression functions used in Heavy 1 & 2 + * Lempel-Ziv-Huffman decompression functions used in Heavy 1 & 2 * compression modes. Based on LZH decompression functions from * UNIX LHA made by Masaru Oki * diff --git a/dms/u_medium.c b/dms/u_medium.c index 6dd0b659..cc3e8678 100755 --- a/dms/u_medium.c +++ b/dms/u_medium.c @@ -47,7 +47,7 @@ USHORT Unpack_MEDIUM(UCHAR *in, UCHAR *out, USHORT origsize){ i = (USHORT) (medium_text_loc - c - 1); while(j--) *out++ = text[medium_text_loc++ & MBITMASK] = text[i++ & MBITMASK]; - + } } medium_text_loc = (USHORT)((medium_text_loc+66) & MBITMASK); diff --git a/enforcer.c b/enforcer.c index f01c81bb..23a105a1 100755 --- a/enforcer.c +++ b/enforcer.c @@ -1,6 +1,6 @@ /* * UAE - The Un*x Amiga Emulator - * + * * Enforcer Like Support * * Copyright 2000-2003 Bernd Roesch and Sebastian Bauer @@ -17,6 +17,18 @@ #include "uae.h" #include "enforcer.h" +#if defined(AHI) + +#if defined(JIT) +#define special_mem_r special_mem |= S_READ +#define special_mem_w special_mem |= S_WRITE +#define NMEM_OFFSET NATMEM_OFFSET +#else +#define special_mem_r +#define special_mem_w +#define NMEM_OFFSET 0 +#endif + /* Configurable options */ #define ENFORCESIZE 1024 #define STACKLINES 5 @@ -123,7 +135,7 @@ static int enforcer_decode_hunk_and_offset(char *buf, uae_u32 pc) * Source of segtracker can be found at: * http://www.sinz.org/Michael.Sinz/Enforcer/SegTracker.c.html */ - + uae_u32 seg_list = node + 46 + 4; /* sizeof(struct SignalSemaphore) + seg find */ node = amiga_list_first(seg_list); @@ -182,13 +194,13 @@ static void enforcer_display_hit(const char *addressmode, uae_u32 pc, uaecptr ad static int bestpc_idxs[INSTRUCTIONLINES/2]; char *enforcer_buf_ptr = enforcer_buf; uaecptr bestpc,pospc,nextpc,temppc; - + if (enforcer_hit) return; /* our function itself generated a hit ;), avoid endless loop */ enforcer_hit = 1; if (!(sysbase = get_long(4))) return; if (!(this_task = get_long(sysbase + 276))) return; - + task_name = get_long(this_task + 10); /* ln_Name */ native_task_name = amiga2native(task_name,100); /*if (strcmp(native_task_name,"c:MCP")!=0) @@ -262,7 +274,7 @@ static void enforcer_display_hit(const char *addressmode, uae_u32 pc, uaecptr ad * At first, the area before the pc, this not always done correctly because * it's done backwards */ temppc = pc; - + memset(bestpc_array,0,sizeof(bestpc_array)); for (i=0;i= 0x00F10000 && addr <= 0x00F7FFFF ) @@ -513,12 +525,12 @@ uae_u32 REGPARAM2 dummy_wget2 (uaecptr addr) if( !warned_JIT_0xF10000 ) { warned_JIT_0xF10000 = 1; - enforcer_display_hit("LONG READ from",(uae_u32)(regs.pc_p - NATMEM_OFFSET),addr); + enforcer_display_hit("LONG READ from",(uae_u32)(regs.pc_p - NMEM_OFFSET),addr); } return 0; } #endif - enforcer_display_hit("WORD READ from",(uae_u32)(regs.pc_p - NATMEM_OFFSET),addr); + enforcer_display_hit("WORD READ from",(uae_u32)(regs.pc_p - NMEM_OFFSET),addr); if (enforcermode==1) { set_special (SPCFLAG_TRAP); @@ -529,8 +541,8 @@ uae_u32 REGPARAM2 dummy_wget2 (uaecptr addr) uae_u32 REGPARAM2 dummy_bget2 (uaecptr addr) { - special_mem |= S_READ; - enforcer_display_hit("BYTE READ from",(uae_u32)(regs.pc_p - NATMEM_OFFSET),addr); + special_mem_r; + enforcer_display_hit("BYTE READ from",(uae_u32)(regs.pc_p - NMEM_OFFSET),addr); if (enforcermode==1) { set_special (SPCFLAG_TRAP); @@ -541,8 +553,8 @@ uae_u32 REGPARAM2 dummy_bget2 (uaecptr addr) void REGPARAM2 dummy_lput2 (uaecptr addr, uae_u32 l) { - special_mem |= S_WRITE; - enforcer_display_hit("LONG WRITE to",(uae_u32)(regs.pc_p - NATMEM_OFFSET),addr); + special_mem_w; + enforcer_display_hit("LONG WRITE to",(uae_u32)(regs.pc_p - NMEM_OFFSET),addr); if (enforcermode==1) { set_special (SPCFLAG_TRAP); @@ -552,8 +564,8 @@ void REGPARAM2 dummy_lput2 (uaecptr addr, uae_u32 l) void REGPARAM2 dummy_wput2 (uaecptr addr, uae_u32 w) { - special_mem |= S_WRITE; - enforcer_display_hit("WORD WRITE to",(uae_u32)(regs.pc_p - NATMEM_OFFSET),addr); + special_mem_w; + enforcer_display_hit("WORD WRITE to",(uae_u32)(regs.pc_p - NMEM_OFFSET),addr); if (enforcermode==1) { set_special (SPCFLAG_TRAP); @@ -563,8 +575,8 @@ void REGPARAM2 dummy_wput2 (uaecptr addr, uae_u32 w) void REGPARAM2 dummy_bput2 (uaecptr addr, uae_u32 b) { - special_mem |= S_WRITE; - enforcer_display_hit("BYTE WRITE to",(uae_u32)(regs.pc_p - NATMEM_OFFSET),addr); + special_mem_w; + enforcer_display_hit("BYTE WRITE to",(uae_u32)(regs.pc_p - NMEM_OFFSET),addr); if (enforcermode==1) { set_special (SPCFLAG_TRAP); @@ -574,8 +586,8 @@ void REGPARAM2 dummy_bput2 (uaecptr addr, uae_u32 b) int REGPARAM2 dummy_check2 (uaecptr addr, uae_u32 size) { - special_mem |= S_READ; - enforcer_display_hit("CHECK from ",(uae_u32)(regs.pc_p - NATMEM_OFFSET),addr); + special_mem_r; + enforcer_display_hit("CHECK from ",(uae_u32)(regs.pc_p - NMEM_OFFSET),addr); return 0; } @@ -653,3 +665,4 @@ int enforcer_disable(void) return 1; } +#endif \ No newline at end of file diff --git a/expansion.c b/expansion.c index a5b156ff..92393127 100755 --- a/expansion.c +++ b/expansion.c @@ -997,7 +997,7 @@ static void expamem_init_z3fastmem (void) } -#ifdef PICASSO96 +#if defined(PICASSO96) /* * Fake Graphics Card (ZORRO III) - BDK */ @@ -1082,6 +1082,7 @@ static void allocate_expamem (void) } clearexec (); } +#if defined(PICASSO96) if (allocated_gfxmem != currprefs.gfxmem_size) { if (gfxmemory) mapped_free (gfxmemory); @@ -1099,6 +1100,7 @@ static void allocate_expamem (void) } clearexec (); } +#endif z3fastmem_bank.baseaddr = z3fastmem; fastmem_bank.baseaddr = fastmemory; @@ -1114,11 +1116,13 @@ static void allocate_expamem (void) map_banks (&z3fastmem_bank, z3fastmem_start >> 16, currprefs.z3fastmem_size >> 16, allocated_z3fastmem); } +#if defined(PICASSO96) if (allocated_gfxmem > 0 && gfxmem_start > 0) { restore_ram (p96_filepos, gfxmemory); map_banks (&gfxmem_bank, gfxmem_start >> 16, currprefs.gfxmem_size >> 16, allocated_gfxmem); } +#endif } } @@ -1183,7 +1187,7 @@ void expamem_reset (void) card_map[cardno++] = expamem_map_filesys; } #ifdef CATWEASEL - if (catweasel_init ()) { + if (currprefs.catweasel && catweasel_init ()) { card_init[cardno] = expamem_init_catweasel; card_map[cardno++] = expamem_map_catweasel; } @@ -1206,8 +1210,10 @@ void expansion_init (void) allocated_fastmem = 0; fastmem_mask = fastmem_start = 0; fastmemory = 0; +#if defined(PICASSO96) gfxmem_mask = gfxmem_start = 0; gfxmemory = 0; +#endif catweasel_mask = catweasel_start = 0; filesys_start = 0; filesysory = 0; diff --git a/filesys.c b/filesys.c index 709c26eb..40421242 100755 --- a/filesys.c +++ b/filesys.c @@ -285,8 +285,8 @@ char *set_filesys_unit (struct uaedev_mount_info *mountinfo, int nr, int blocksize, int bootpri, char *filesysdir, int flags) { char *result; - UnitInfo ui = mountinfo->ui[nr]; + UnitInfo ui = mountinfo->ui[nr]; hdf_close (&ui.hf); result = set_filesys_unit_1 (mountinfo, nr, devname, volname, rootdir, readonly, secspertrack, surfaces, reserved, blocksize, bootpri, filesysdir, flags); @@ -3588,6 +3588,26 @@ void filesys_prepare_reset (void) } } +/* +static uaecptr uaeresource_startup (uaecptr resaddr) +{ + uaecptr ROM_uaeresource_resname, ROM_uaeresource_resid; + + ROM_uaeresource_resname = ds ("uae.resource"); + ROM_uaeresource_resid = ds ("uae.resource 0.1"); + put_word(resaddr + 0x0, 0x4AFC); + put_long(resaddr + 0x2, resaddr); + put_long(resaddr + 0x6, resaddr + 0x1A); // Continue scan here + put_word(resaddr + 0xA, 0x0001); // RTF_COLDSTART; Version 1 + put_word(resaddr + 0xC, 0x0801); // NT_RESOURCE; pri 01 + put_long(resaddr + 0xE, ROM_uaeresource_resname); + put_long(resaddr + 0x12, ROM_uaeresource_resid); + put_long(resaddr + 0x16, 0); + resaddr += 0x1A; + return resaddr; +} +*/ + static uae_u32 filesys_diagentry (void) { uaecptr resaddr = m68k_areg (regs, 2) + 0x10; @@ -3623,6 +3643,7 @@ static uae_u32 filesys_diagentry (void) * Resident structures and call InitResident() for them at the end of the * diag entry. */ + //resaddr = uaeresource_startup(resaddr); resaddr = scsidev_startup(resaddr); /* scan for Residents and return pointer to array of them */ diff --git a/fpp.c b/fpp.c index 2dd93a62..b7942f33 100755 --- a/fpp.c +++ b/fpp.c @@ -62,11 +62,11 @@ static __inline__ void native_set_fpucw (uae_u32 m68k_cw) } x=0x107f + (iprec<<8) + (iround<<10); -#ifdef _MSC_VER +#if defined(X86_MSVC_ASSEMBLY) __asm { fldcw x } -#else +#elif defined(X86_ASSEMBLY) __asm__ ("fldcw %0" : : "m" (*&x)); #endif #endif diff --git a/fsdb.c b/fsdb.c index da01bed0..385c01bb 100755 --- a/fsdb.c +++ b/fsdb.c @@ -63,7 +63,7 @@ char *fsdb_search_dir (const char *dirname, char *rel) /* This really shouldn't happen... */ if (! dir) return 0; - + while (p == 0 && (de = my_readdir (dir, fn)) != 0) { if (strcmp (fn, rel) == 0) p = rel; @@ -79,7 +79,7 @@ static FILE *get_fsdb (a_inode *dir, const char *mode) { char *n; FILE *f; - + n = build_nname (dir->nname, FSDB_FILE); f = fopen (n, mode); free (n); @@ -103,7 +103,7 @@ static void fsdb_fixup (FILE *f, char *buf, int size, a_inode *base) nname = build_nname (base->nname, buf + 5 + 257); ret = fsdb_exists (nname); if (ret) { - free (nname); + free (nname); return; } TRACE (("uaefsdb '%s' deleted\n", nname)); @@ -217,12 +217,12 @@ int fsdb_used_as_nname (a_inode *base, const char *nname) { FILE *f; char buf[1 + 4 + 257 + 257 + 81]; - + f = get_fsdb (base, "r+b"); if (f == 0) { if (currprefs.filesys_custom_uaefsdb && (base->volflags & MYVOLUMEINFO_STREAMS)) return custom_fsdb_used_as_nname (base, nname); - return 0; + return 0; } for (;;) { if (fread (buf, 1, sizeof buf, f) < sizeof buf) @@ -244,7 +244,7 @@ static int needs_dbentry (a_inode *aino) if (aino->deleted) return 0; - + if (! fsdb_mode_representable_p (aino) || aino->comment != 0) return 1; diff --git a/fsusage.c b/fsusage.c index 4e702ec6..cb63b1d4 100755 --- a/fsusage.c +++ b/fsusage.c @@ -69,10 +69,10 @@ int get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp) } /* HACK ALERT! WinNT returns 0 in TotalNumberOfClusters for an audio-CD, which calls the GURU! */ - if( ( TotalNumberOfClusters == 0 ) && - ( GetDriveType( buf2 ) == DRIVE_CDROM ) ) + if( ( TotalNumberOfClusters == 0 ) && + ( GetDriveType( buf2 ) == DRIVE_CDROM ) ) { - TotalNumberOfClusters = 327680; + TotalNumberOfClusters = 327680; } BytesPerSector *= SectorsPerCluster; diff --git a/gencomp.c b/gencomp.c index 39710edd..1573cc4a 100755 --- a/gencomp.c +++ b/gencomp.c @@ -81,7 +81,7 @@ static int *opcode_next_clev; static int *opcode_last_postfix; static unsigned long *counts; -static void +static void read_counts (void) { FILE *file; @@ -123,14 +123,14 @@ read_counts (void) static int n_braces = 0; static int insn_n_cycles; -static void +static void start_brace (void) { n_braces++; comprintf ("{"); } -static void +static void close_brace (void) { assert (n_braces > 0); @@ -138,21 +138,21 @@ close_brace (void) comprintf ("}"); } -static void +static void finish_braces (void) { while (n_braces > 0) close_brace (); } -static void +static void pop_braces (int to) { while (n_braces > to) close_brace (); } -static int +static int bit_size (int size) { switch (size) @@ -230,7 +230,7 @@ gen_nextilong (void) sprintf (buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)"); insn_n_cycles += 4; - + long_opcode=1; return buffer; } @@ -259,16 +259,16 @@ gen_nextibyte (void) return buffer; } -static void +static void sync_m68k_pc (void) { - comprintf("\t if (m68k_pc_offset>100) sync_m68k_pc();\n"); + comprintf("\t if (m68k_pc_offset>100) sync_m68k_pc();\n"); } /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, * the calling routine handles Apdi and Aipi modes. */ -static void +static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem) { start_brace (); @@ -277,7 +277,7 @@ genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int move case Dreg: /* Do we need to check dodgy here? */ if (movem) abort (); - if (getv == 1 || getv==2) { + if (getv == 1 || getv==2) { /* We generate the variable even for getv==2, so we can use it as a destination for MOVE */ comprintf ("\tint %s=%s;\n",name,reg); @@ -306,8 +306,8 @@ genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int move comprintf ("\tint %sa=scratchie++;\n",name,reg); comprintf ("\tmov_l_rr(%sa,%s+8);\n",name, reg); break; - case Apdi: - switch (size) + case Apdi: + switch (size) { case sz_byte: if (movem) { @@ -507,7 +507,7 @@ genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int move } } -static void +static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to) { switch (mode) @@ -559,7 +559,7 @@ genastore (char *from, amodes mode, char *reg, wordsizes size, char *to) { char astring[80]; sprintf(astring,"%sa",to); - + switch (size) { case sz_byte: @@ -596,7 +596,7 @@ static void genmov16(uae_u32 opcode, struct instr *curi) comprintf("\tint dst=scratchie++;\n"); if ((opcode & 0xfff8) == 0xf620) { - /* MOVE16 (Ax)+,(Ay)+ */ + /* MOVE16 (Ax)+,(Ay)+ */ comprintf("\tuae_u16 dstreg=((%s)>>12)&0x07;\n", gen_nextiword()); comprintf("\tmov_l_rr(src,8+srcreg);\n"); comprintf("\tmov_l_rr(dst,8+dstreg);\n"); @@ -607,14 +607,14 @@ static void genmov16(uae_u32 opcode, struct instr *curi) comprintf("\tmov_l_rr(src,srca);\n"); comprintf("\tmov_l_rr(dst,dsta);\n"); } - + /* Align on 16-byte boundaries */ comprintf("\tand_l_ri(src,~15);\n"); comprintf("\tand_l_ri(dst,~15);\n"); - - + + if ((opcode & 0xfff8) == 0xf620) { - comprintf("\tif (srcreg != dstreg)\n"); + comprintf("\tif (srcreg != dstreg)\n"); comprintf("\tadd_l_ri(srcreg+8,16);\n"); comprintf("\tadd_l_ri(dstreg+8,16);\n"); } else if ((opcode & 0xfff8) == 0xf600) @@ -706,7 +706,7 @@ static void genmov16(void) } #endif -static void +static void genmovemel (uae_u16 opcode) { comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); @@ -723,12 +723,12 @@ genmovemel (uae_u16 opcode) comprintf("\tfor (i=0;i<16;i++) {\n" "\t\tif ((mask>>i)&1) {\n"); switch(table68k[opcode].size) { - case sz_long: + case sz_long: comprintf("\t\t\tmov_l_rR(i,native,offset);\n" "\t\t\tbswap_32(i);\n" "\t\t\toffset+=4;\n"); break; - case sz_word: + case sz_word: comprintf("\t\t\tmov_w_rR(i,native,offset);\n" "\t\t\tbswap_16(i);\n" "\t\t\tsign_extend_16_rr(i,i);\n" @@ -739,7 +739,7 @@ genmovemel (uae_u16 opcode) comprintf("\t\t}\n" "\t}"); if (table68k[opcode].dmode == Aipi) { - comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n"); + comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n"); } /* End fast but unsafe. */ @@ -751,7 +751,7 @@ genmovemel (uae_u16 opcode) comprintf("\tfor (i=0;i<16;i++) {\n" "\t\tif ((mask>>i)&1) {\n"); switch(table68k[opcode].size) { - case sz_long: + case sz_long: comprintf("\t\t\treadlong(tmp,i,scratchie);\n" "\t\t\tadd_l_ri(tmp,4);\n"); break; @@ -772,7 +772,7 @@ genmovemel (uae_u16 opcode) } -static void +static void genmovemle (uae_u16 opcode) { comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); @@ -794,13 +794,13 @@ genmovemle (uae_u16 opcode) comprintf("\tfor (i=0;i<16;i++) {\n" "\t\tif ((mask>>i)&1) {\n"); switch(table68k[opcode].size) { - case sz_long: + case sz_long: comprintf("\t\t\tmov_l_rr(tmp,i);\n" "\t\t\tbswap_32(tmp);\n" "\t\t\tmov_l_Rr(native,tmp,offset);\n" "\t\t\toffset+=4;\n"); break; - case sz_word: + case sz_word: comprintf("\t\t\tmov_l_rr(tmp,i);\n" "\t\t\tbswap_16(tmp);\n" "\t\t\tmov_w_Rr(native,tmp,offset);\n" @@ -812,14 +812,14 @@ genmovemle (uae_u16 opcode) comprintf("\tfor (i=0;i<16;i++) {\n" "\t\tif ((mask>>i)&1) {\n"); switch(table68k[opcode].size) { - case sz_long: + case sz_long: comprintf("\t\t\toffset-=4;\n" "\t\t\tmov_l_rr(tmp,15-i);\n" "\t\t\tbswap_32(tmp);\n" "\t\t\tmov_l_Rr(native,tmp,offset);\n" ); break; - case sz_word: + case sz_word: comprintf("\t\t\toffset-=2;\n" "\t\t\tmov_l_rr(tmp,15-i);\n" "\t\t\tbswap_16(tmp);\n" @@ -842,11 +842,11 @@ genmovemle (uae_u16 opcode) comprintf("\tfor (i=0;i<16;i++) {\n" "\t\tif ((mask>>i)&1) {\n"); switch(table68k[opcode].size) { - case sz_long: + case sz_long: comprintf("\t\t\twritelong(tmp,i,scratchie);\n" "\t\t\tadd_l_ri(tmp,4);\n"); break; - case sz_word: + case sz_word: comprintf("\t\t\twriteword(tmp,i,scratchie);\n" "\t\t\tadd_l_ri(tmp,2);\n"); break; @@ -857,18 +857,18 @@ genmovemle (uae_u16 opcode) comprintf("\tfor (i=0;i<16;i++) {\n" "\t\tif ((mask>>i)&1) {\n"); switch(table68k[opcode].size) { - case sz_long: + case sz_long: comprintf("\t\t\tsub_l_ri(srca,4);\n" "\t\t\twritelong(srca,15-i,scratchie);\n"); break; - case sz_word: + case sz_word: comprintf("\t\t\tsub_l_ri(srca,2);\n" "\t\t\twriteword(srca,15-i,scratchie);\n"); break; default: abort(); } } - + comprintf("\t\t}\n" "\t}"); @@ -879,7 +879,7 @@ genmovemle (uae_u16 opcode) } -static void +static void duplicate_carry (void) { comprintf ("\tif (needed_flags&FLAG_X) duplicate_carry();\n"); @@ -887,14 +887,14 @@ duplicate_carry (void) typedef enum { - flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, + flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or, flag_eor, flag_mov } flagtypes; -static void +static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) { if (noflags) { @@ -1021,11 +1021,11 @@ genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) close_brace(); return; } - + case flag_addx: case flag_subx: - + comprintf("\tdont_care_flags();\n"); { char* op; @@ -1053,7 +1053,7 @@ genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) default: return; } } - + /* Need the flags, but possibly not all of them */ switch (type) { @@ -1194,10 +1194,10 @@ genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) duplicate_carry(); } comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); - + return; } - + case flag_addx: case flag_subx: uses_cmov; @@ -1251,7 +1251,7 @@ genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) } } -static void +static void force_range_for_rox (const char *var, wordsizes size) { /* Could do a modulo operation here... which one is faster? */ @@ -1288,7 +1288,7 @@ cmask (wordsizes size) } } -static int +static int source_is_imm1_8 (struct instr *i) { return i->stype == 3; @@ -1358,11 +1358,11 @@ gen_opcode (unsigned long int opcode) case i_ORSR: case i_EORSR: failure; - isjump; + isjump; break; case i_ANDSR: failure; - isjump; + isjump; break; case i_SUB: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); @@ -1472,7 +1472,7 @@ gen_opcode (unsigned long int opcode) case i_BCLR: case i_BSET: case i_BTST: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); start_brace(); comprintf("\tint s=scratchie++;\n" @@ -1482,7 +1482,7 @@ gen_opcode (unsigned long int opcode) else comprintf("\tand_l_ri(s,31);\n"); - { + { char* op; int need_write=1; @@ -1502,7 +1502,7 @@ gen_opcode (unsigned long int opcode) "\tlive_flags();\n" "\tend_needflags();\n"); } - if (need_write) + if (need_write) genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); } break; @@ -1530,15 +1530,15 @@ gen_opcode (unsigned long int opcode) case i_BSET: op="bts"; break; case i_BTST: op="bt"; need_write=0; break; } - comprintf("\t%s_l_rr(dst,s);\n" // Answer now in C - "\tsbb_l(s,s);\n" // s is 0 if bit was 0, -1 otherwise - "\tmake_flags_live();\n" // Get the flags back - "\tdont_care_flags();\n" + comprintf("\t%s_l_rr(dst,s);\n" // Answer now in C + "\tsbb_l(s,s);\n" // s is 0 if bit was 0, -1 otherwise + "\tmake_flags_live();\n" // Get the flags back + "\tdont_care_flags();\n" "\tstart_needflags();\n" "\tbsf_l_rr(s,s);\n" "\tlive_flags();\n" "\tend_needflags();\n",op); - if (need_write) + if (need_write) genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); } break; @@ -1566,11 +1566,11 @@ gen_opcode (unsigned long int opcode) /* The next two are coded a little unconventional, but they are doing * weird things... */ case i_MVPRM: - isjump; + isjump; failure; break; case i_MVPMR: - isjump; + isjump; failure; break; case i_MOVE: @@ -1605,11 +1605,11 @@ gen_opcode (unsigned long int opcode) break; case i_MVSR2: - isjump; + isjump; failure; break; case i_MV2SR: - isjump; + isjump; failure; break; case i_SWAP: @@ -1661,29 +1661,29 @@ gen_opcode (unsigned long int opcode) genmovemle (opcode); break; case i_TRAP: - isjump; + isjump; failure; break; case i_MVR2USP: - isjump; + isjump; failure; break; case i_MVUSP2R: - isjump; + isjump; failure; break; case i_RESET: - isjump; + isjump; failure; break; case i_NOP: break; case i_STOP: - isjump; + isjump; failure; break; case i_RTE: - isjump; + isjump; failure; break; case i_RTD: @@ -1700,7 +1700,7 @@ gen_opcode (unsigned long int opcode) "\tm68k_pc_offset=0;\n" "\tadd_l(15,offs);\n"); gen_update_next_handler(); - isjump; + isjump; break; case i_LINK: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); @@ -1730,18 +1730,18 @@ gen_opcode (unsigned long int opcode) "\tm68k_pc_offset=0;\n" "\tlea_l_brr(15,15,4);\n"); gen_update_next_handler(); - isjump; + isjump; break; case i_TRAPV: - isjump; + isjump; failure; break; case i_RTR: - isjump; + isjump; failure; break; case i_JSR: - isjump; + isjump; genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); start_brace(); comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); @@ -1797,7 +1797,7 @@ gen_opcode (unsigned long int opcode) comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); /* Leave the following as "add" --- it will allow it to be optimized away due to src being a constant ;-) */ - comprintf("\tadd_l_ri(src,(uae_u32)comp_pc_p);\n"); + comprintf("\tadd_l_ri(src,(uae_u32)comp_pc_p);\n"); comprintf("\tmov_l_ri(PC_P,(uae_u32)comp_pc_p);\n"); /* Now they are both constant. Might as well fold in m68k_pc_offset */ comprintf("\tadd_l_ri(src,m68k_pc_offset);\n"); @@ -1810,15 +1810,15 @@ gen_opcode (unsigned long int opcode) "\tregister_branch(v1,v2,%d);\n", cond_codes_x86[curi->cc]); comprintf("\tmake_flags_live();\n"); /* Load the flags */ - isjump; + isjump; } else { - is_const_jump; + is_const_jump; } switch(curi->cc) { case 0: /* Unconditional jump */ - comprintf("\tmov_l_rr(PC_P,src);\n"); + comprintf("\tmov_l_rr(PC_P,src);\n"); comprintf("\tcomp_pc_p=(void*)get_const(PC_P);\n"); break; case 1: break; /* This is silly! */ @@ -1836,7 +1836,7 @@ gen_opcode (unsigned long int opcode) case 12: case 13: case 14: - case 15: + case 15: break; default: abort(); } @@ -1847,12 +1847,12 @@ gen_opcode (unsigned long int opcode) genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); break; case i_PEA: - if (table68k[opcode].smode==Areg || - table68k[opcode].smode==Aind || - table68k[opcode].smode==Aipi || - table68k[opcode].smode==Apdi || - table68k[opcode].smode==Ad16 || - table68k[opcode].smode==Ad8r) + if (table68k[opcode].smode==Areg || + table68k[opcode].smode==Aind || + table68k[opcode].smode==Aipi || + table68k[opcode].smode==Apdi || + table68k[opcode].smode==Ad16 || + table68k[opcode].smode==Ad8r) comprintf("if (srcreg==7) dodgy=1;\n"); genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); @@ -1860,7 +1860,7 @@ gen_opcode (unsigned long int opcode) genastore ("srca", Apdi, "7", sz_long, "dst"); break; case i_DBcc: - isjump; + isjump; uses_cmov; genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); @@ -1870,9 +1870,9 @@ gen_opcode (unsigned long int opcode) case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break; default: abort(); /* Seems this only comes in word flavour */ } - comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); - comprintf("\tadd_l_ri(offs,(uae_u32)comp_pc_p);\n"); /* New PC, - once the + comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); + comprintf("\tadd_l_ri(offs,(uae_u32)comp_pc_p);\n"); /* New PC, + once the offset_68k is * also added */ /* Let's fold in the m68k_pc_offset at this point */ @@ -1887,14 +1887,14 @@ gen_opcode (unsigned long int opcode) comprintf("\tmake_flags_live();\n"); /* Load the flags */ } - if (curi->size!=sz_word) + if (curi->size!=sz_word) abort(); switch(curi->cc) { case 0: /* This is an elaborate nop? */ break; - case 1: + case 1: comprintf("\tstart_needflags();\n"); comprintf("\tsub_w_ri(src,1);\n"); comprintf("\t end_needflags();\n"); @@ -1927,14 +1927,14 @@ gen_opcode (unsigned long int opcode) cond_codes_x86[curi->cc]); comprintf("\tcmov_l_rr(src,nsrc,%d);\n", cond_codes_x86[curi->cc]); - /* OK, now for cc=true, we have src==nsrc and offs==PC_P, + /* OK, now for cc=true, we have src==nsrc and offs==PC_P, so whether we move them around doesn't matter. However, if cc=false, we have offs==jump_pc, and src==nsrc-1 */ comprintf("\t start_needflags();\n"); - comprintf("\ttest_w_rr(nsrc,nsrc);\n"); + comprintf("\ttest_w_rr(nsrc,nsrc);\n"); comprintf("\t end_needflags();\n"); - comprintf("\tcmov_l_rr(PC_P,offs,5);\n"); + comprintf("\tcmov_l_rr(PC_P,offs,5);\n"); break; default: abort(); } @@ -1950,11 +1950,11 @@ gen_opcode (unsigned long int opcode) /* We set val to 0 if we really should use 255, and to 1 for real 0 */ switch(curi->cc) { case 0: /* Unconditional set */ - comprintf("\tmov_l_ri(val,0);\n"); + comprintf("\tmov_l_ri(val,0);\n"); break; - case 1: + case 1: /* Unconditional not-set */ - comprintf("\tmov_l_ri(val,1);\n"); + comprintf("\tmov_l_ri(val,1);\n"); break; case 8: failure; break; /* Work out details! FIXME */ case 9: failure; break; /* Not critical, though! */ @@ -1981,18 +1981,18 @@ gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "src"); break; case i_DIVU: - isjump; + isjump; failure; break; case i_DIVS: - isjump; + isjump; failure; break; case i_MULU: comprintf("\tdont_care_flags();\n"); genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); - /* To do 16x16 unsigned multiplication, we actually use + /* To do 16x16 unsigned multiplication, we actually use 32x32 signed, and zero-extend the registers first. That solves the problem of MUL needing dedicated registers on the x86 */ @@ -2013,12 +2013,12 @@ gen_opcode (unsigned long int opcode) genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); break; case i_CHK: - isjump; + isjump; failure; break; case i_CHK2: - isjump; + isjump; failure; break; @@ -2053,15 +2053,15 @@ gen_opcode (unsigned long int opcode) switch(curi->size) { case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n" "\thighmask=0x38;\n" - "\twidth=8;\n"); + "\twidth=8;\n"); break; case sz_word: comprintf("\tshra_w_rr(data,cnt);\n" "\thighmask=0x30;\n" - "\twidth=16;\n"); + "\twidth=16;\n"); break; case sz_long: comprintf("\tshra_l_rr(data,cnt);\n" "\thighmask=0x20;\n" - "\twidth=32;\n"); + "\twidth=32;\n"); break; default: abort(); } @@ -2084,7 +2084,7 @@ gen_opcode (unsigned long int opcode) case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; default: abort(); } - + /* Result of shift is now in data. Now we need to determine the carry by shifting cdata one less */ comprintf("\tsub_l_ri(tmpcnt,1);\n"); @@ -2122,15 +2122,15 @@ gen_opcode (unsigned long int opcode) switch(curi->size) { case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n" "\thighmask=0x38;\n" - "\twidth=8;\n"); + "\twidth=8;\n"); break; case sz_word: comprintf("\tshra_w_rr(data,cnt);\n" "\thighmask=0x30;\n" - "\twidth=16;\n"); + "\twidth=16;\n"); break; case sz_long: comprintf("\tshra_l_rr(data,cnt);\n" "\thighmask=0x20;\n" - "\twidth=32;\n"); + "\twidth=32;\n"); break; default: abort(); } @@ -2207,7 +2207,7 @@ gen_opcode (unsigned long int opcode) " FAIL(1);\n" " return 0;\n" "} \n"); - + genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); if (curi->smode!=immi) { @@ -2225,13 +2225,13 @@ gen_opcode (unsigned long int opcode) 0 (for shift count==0) */ switch(curi->size) { case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); + "\thighmask=0x38;\n"); break; case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); + "\thighmask=0x30;\n"); break; case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); + "\thighmask=0x20;\n"); break; default: abort(); } @@ -2261,11 +2261,11 @@ gen_opcode (unsigned long int opcode) comprintf("\tif (needed_flags & FLAG_ZNV)\n"); switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); + case sz_byte: comprintf("\t test_b_rr(data,data);\n"); comprintf("\t bt_l_ri(cdata,7);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); + case sz_word: comprintf("\t test_w_rr(data,data);\n"); comprintf("\t bt_l_ri(cdata,15);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); + case sz_long: comprintf("\t test_l_rr(data,data);\n"); comprintf("\t bt_l_ri(cdata,31);\n"); break; } comprintf("\t live_flags();\n"); @@ -2280,13 +2280,13 @@ gen_opcode (unsigned long int opcode) comprintf("\tint highmask;\n"); switch(curi->size) { case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); + "\thighmask=0x38;\n"); break; case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); + "\thighmask=0x30;\n"); break; case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); + "\thighmask=0x20;\n"); break; default: abort(); } @@ -2334,7 +2334,7 @@ gen_opcode (unsigned long int opcode) genastore ("data", curi->dmode, "dstreg", curi->size, "data"); } break; - + case i_LSR: mayfail; if (curi->smode==Dreg) { @@ -2363,13 +2363,13 @@ gen_opcode (unsigned long int opcode) 0 (for shift count==0) */ switch(curi->size) { case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); + "\thighmask=0x38;\n"); break; case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); + "\thighmask=0x30;\n"); break; case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); + "\thighmask=0x20;\n"); break; default: abort(); } @@ -2415,13 +2415,13 @@ gen_opcode (unsigned long int opcode) comprintf("\tint highmask;\n"); switch(curi->size) { case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); + "\thighmask=0x38;\n"); break; case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); + "\thighmask=0x30;\n"); break; case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); + "\thighmask=0x20;\n"); break; default: abort(); } @@ -2490,13 +2490,13 @@ gen_opcode (unsigned long int opcode) 0 (for shift count==0) */ switch(curi->size) { case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); + "\thighmask=0x38;\n"); break; case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); + "\thighmask=0x30;\n"); break; case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); + "\thighmask=0x20;\n"); break; default: abort(); } @@ -2525,11 +2525,11 @@ gen_opcode (unsigned long int opcode) comprintf("\tstart_needflags();\n"); comprintf("\tif (needed_flags & FLAG_ZNV)\n"); switch(curi->size) { - case sz_byte: comprintf("\t test_b_rr(data,data);\n"); + case sz_byte: comprintf("\t test_b_rr(data,data);\n"); comprintf("\t bt_l_ri(cdata,7);\n"); break; - case sz_word: comprintf("\t test_w_rr(data,data);\n"); + case sz_word: comprintf("\t test_w_rr(data,data);\n"); comprintf("\t bt_l_ri(cdata,15);\n"); break; - case sz_long: comprintf("\t test_l_rr(data,data);\n"); + case sz_long: comprintf("\t test_l_rr(data,data);\n"); comprintf("\t bt_l_ri(cdata,31);\n"); break; } comprintf("\t live_flags();\n"); @@ -2544,13 +2544,13 @@ gen_opcode (unsigned long int opcode) comprintf("\tint highmask;\n"); switch(curi->size) { case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" - "\thighmask=0x38;\n"); + "\thighmask=0x38;\n"); break; case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" - "\thighmask=0x30;\n"); + "\thighmask=0x30;\n"); break; case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" - "\thighmask=0x20;\n"); + "\thighmask=0x20;\n"); break; default: abort(); } @@ -2618,7 +2618,7 @@ gen_opcode (unsigned long int opcode) case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break; case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break; } - + if (!noflags) { comprintf("\tstart_needflags();\n"); comprintf("\tif (needed_flags & FLAG_ZNV)\n"); @@ -2643,7 +2643,7 @@ gen_opcode (unsigned long int opcode) "} \n"); start_brace(); } - comprintf("\tdont_care_flags();\n"); + comprintf("\tdont_care_flags();\n"); genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); start_brace (); @@ -2653,7 +2653,7 @@ gen_opcode (unsigned long int opcode) case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break; case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break; } - + if (!noflags) { comprintf("\tstart_needflags();\n"); comprintf("\tif (needed_flags & FLAG_ZNV)\n"); @@ -2704,11 +2704,11 @@ gen_opcode (unsigned long int opcode) failure; break; case i_MOVEC2: - isjump; + isjump; failure; break; case i_MOVE2C: - isjump; + isjump; failure; break; case i_CAS: @@ -2718,27 +2718,27 @@ gen_opcode (unsigned long int opcode) failure; break; case i_MOVES: /* ignore DFC and SFC because we have no MMU */ - isjump; + isjump; failure; break; case i_BKPT: /* only needed for hardware emulators */ - isjump; + isjump; failure; break; case i_CALLM: /* not present in 68030 */ - isjump; + isjump; failure; break; case i_RTM: /* not present in 68030 */ - isjump; + isjump; failure; break; case i_TRAPcc: - isjump; + isjump; failure; break; case i_DIVL: - isjump; + isjump; failure; break; case i_MULL: @@ -2749,7 +2749,7 @@ gen_opcode (unsigned long int opcode) comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); comprintf("\tint r2=(extra>>12)&7;\n" "\tint tmp=scratchie++;\n"); - + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); /* The two operands are in dst and r2 */ comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */ @@ -2799,7 +2799,7 @@ gen_opcode (unsigned long int opcode) comprintf("\tcomp_fbcc_opp(opcode);\n"); break; case i_FDBcc: - isjump; + isjump; failure; break; case i_FScc: @@ -2809,7 +2809,7 @@ gen_opcode (unsigned long int opcode) comprintf("\tcomp_fscc_opp(opcode,extra);\n"); break; case i_FTRAPcc: - isjump; + isjump; failure; break; case i_FSAVE: @@ -2822,7 +2822,7 @@ gen_opcode (unsigned long int opcode) case i_CINVL: case i_CINVP: case i_CINVA: - isjump; /* Not really, but it's probably a good idea to stop + isjump; /* Not really, but it's probably a good idea to stop translating at this point */ failure; comprintf ("\tflush_icache();\n"); /* Differentiate a bit more? */ @@ -2830,7 +2830,7 @@ gen_opcode (unsigned long int opcode) case i_CPUSHL: case i_CPUSHP: case i_CPUSHA: - isjump; /* Not really, but it's probably a good idea to stop + isjump; /* Not really, but it's probably a good idea to stop translating at this point */ failure; break; @@ -2844,7 +2844,7 @@ gen_opcode (unsigned long int opcode) break; case i_MMUOP: - isjump; + isjump; failure; break; default: @@ -2859,10 +2859,11 @@ gen_opcode (unsigned long int opcode) return global_failure; } -static void +static void generate_includes (FILE * f) { fprintf (f, "#include \"sysconfig.h\"\n"); + fprintf (f, "#if defined(JIT)\n"); fprintf (f, "#include \"sysdeps.h\"\n"); fprintf (f, "#include \"config.h\"\n"); fprintf (f, "#include \"options.h\"\n"); @@ -2875,7 +2876,7 @@ generate_includes (FILE * f) static int postfix; -static void +static void generate_one_opcode (int rp, int noflags) { int i; @@ -2930,7 +2931,7 @@ generate_one_opcode (int rp, int noflags) { char source[100]; int pos = table68k[opcode].spos; - + if (pos) sprintf (source, "((opcode >> %d) & %d)", pos, smsk); else @@ -2961,7 +2962,7 @@ generate_one_opcode (int rp, int noflags) else { int pos = table68k[opcode].dpos; - + if (pos) comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", pos, dmsk); @@ -2971,18 +2972,18 @@ generate_one_opcode (int rp, int noflags) } if (have_srcreg && have_dstreg && - (table68k[opcode].dmode==Areg || - table68k[opcode].dmode==Aind || - table68k[opcode].dmode==Aipi || - table68k[opcode].dmode==Apdi || - table68k[opcode].dmode==Ad16 || + (table68k[opcode].dmode==Areg || + table68k[opcode].dmode==Aind || + table68k[opcode].dmode==Aipi || + table68k[opcode].dmode==Apdi || + table68k[opcode].dmode==Ad16 || table68k[opcode].dmode==Ad8r) && - (table68k[opcode].smode==Areg || - table68k[opcode].smode==Aind || - table68k[opcode].smode==Aipi || - table68k[opcode].smode==Apdi || - table68k[opcode].smode==Ad16 || - table68k[opcode].smode==Ad8r) + (table68k[opcode].smode==Areg || + table68k[opcode].smode==Aind || + table68k[opcode].smode==Aipi || + table68k[opcode].smode==Apdi || + table68k[opcode].smode==Ad16 || + table68k[opcode].smode==Ad8r) ) { comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n"); } @@ -3002,7 +3003,7 @@ generate_one_opcode (int rp, int noflags) if (global_iscjump) flags|=16; comprintf ("return 0;\n"); comprintf ("}\n"); - + if (aborted) { fprintf (stblfile, "{ NULL, %ld, 0x%08x }, /* %s */\n", opcode, flags, lookuptab[i].name); com_discard(); @@ -3023,7 +3024,7 @@ generate_one_opcode (int rp, int noflags) opcode_last_postfix[rp] = postfix; } -static void +static void generate_func (int noflags) { int i, j, rp; @@ -3073,7 +3074,7 @@ generate_func (int noflags) } -int +int main (int argc, char **argv) { read_table68k (); @@ -3110,6 +3111,9 @@ main (int argc, char **argv) noflags=1; generate_func (noflags); + printf ("#endif\n"); + fprintf (stblfile, "#endif\n"); + free (table68k); return 0; } diff --git a/gencpu.c b/gencpu.c index f052168e..7af4d960 100755 --- a/gencpu.c +++ b/gencpu.c @@ -292,16 +292,12 @@ static void fill_prefetch_2 (void) insn_n_cycles += 4; } -static void fill_prefetch_1 (int o, int needcycles) +static void fill_prefetch_1 (int o) { if (!using_prefetch) return; if (using_ce) { - if (needcycles) { - printf ("\tlostcycles = get_word_ce_prefetch_cycles (%d);\n", o); - } else { - printf ("\tget_word_ce_prefetch (%d);\n", o); - } + printf ("\tget_word_ce_prefetch (%d);\n", o); } else { printf ("\tget_word_prefetch (%d);\n", o); } @@ -311,9 +307,9 @@ static void fill_prefetch_1 (int o, int needcycles) static void fill_prefetch_full (void) { - fill_prefetch_1 (0, 0); + fill_prefetch_1 (0); irc2ir (); - fill_prefetch_1 (2, 0); + fill_prefetch_1 (2); } static void fill_prefetch_0 (void) @@ -328,22 +324,15 @@ static void fill_prefetch_0 (void) insn_n_cycles += 4; } -static void fill_prefetch_next_1 (needcycles) +static void fill_prefetch_next_1 (void) { - if (needcycles && using_ce) { - printf ("\tint lostcycles;\n"); - } irc2ir (); - fill_prefetch_1 (m68k_pc_offset + 2, needcycles); + fill_prefetch_1 (m68k_pc_offset + 2); } static void fill_prefetch_next (void) { - fill_prefetch_next_1 (0); -} -static void fill_prefetch_next_cycles (void) -{ - fill_prefetch_next_1 (1); + fill_prefetch_next_1 (); } static void fill_prefetch_next_delay (int extracycles) @@ -353,9 +342,9 @@ static void fill_prefetch_next_delay (int extracycles) if (using_ce) { if (extracycles > 0) { printf("\t{\n"); - fill_prefetch_next_cycles (); - printf("\tif ((%d + 4) * %d > lostcycles) do_cycles_ce ((%d + 4) * %d - lostcycles);\n", - extracycles, CYCLE_UNIT / 2, extracycles, CYCLE_UNIT / 2); + fill_prefetch_next (); + printf("\tif (%d > 0) do_cycles(%d * %d);\n", + extracycles, CYCLE_UNIT / 2, extracycles); printf("\t}\n"); } else { fill_prefetch_next (); @@ -369,7 +358,7 @@ static void fill_prefetch_finish (void) { if (did_prefetch || !using_prefetch) return; - fill_prefetch_1 (m68k_pc_offset, 0); + fill_prefetch_1 (m68k_pc_offset); } static void sync_m68k_pc (void) @@ -1131,7 +1120,7 @@ static void shift_ce (amodes dmode, int size) { if (using_ce && isreg (dmode)) { printf ("\t{\n"); - printf ("\t\tint cycles = %d * %d - lostcycles;\n", size == sz_long ? 8 : 6, CYCLE_UNIT / 2); + printf ("\t\tint cycles = %d * %d;\n", size == sz_long ? 8 : 6, CYCLE_UNIT / 2); printf ("\t\tcycles += 2 * %d * ccnt;\n", CYCLE_UNIT / 2); addcycles3 ("\t\t"); printf ("\t}\n"); @@ -1717,7 +1706,7 @@ static void gen_opcode (unsigned long int opcode) } printf ("\tm68k_setpc (srca);\n"); m68k_pc_offset = 0; - fill_prefetch_1 (0, 0); + fill_prefetch_1 (0); printf("\tm68k_areg (regs, 7) -= 4;\n"); if (using_ce) { printf("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n"); @@ -1839,7 +1828,7 @@ static void gen_opcode (unsigned long int opcode) addcycles (2); printf ("\tif (!cctrue(%d)) {\n", curi->cc); printf ("\t\tm68k_incpc((uae_s32)offs + 2);\n"); - printf ("\t"); fill_prefetch_1 (0, 0); + printf ("\t"); fill_prefetch_1 (0); printf ("\t"); genastore ("(src-1)", curi->smode, "srcreg", curi->size, "src"); printf ("\t\tif (src) {\n"); @@ -1851,7 +1840,7 @@ static void gen_opcode (unsigned long int opcode) need_endlabel = 1; } irc2ir (); - fill_prefetch_1 (2, 0); + fill_prefetch_1 (2); returncycles ("\t\t\t", 12); if (using_ce) printf ("\t\t\treturn;\n"); @@ -1868,11 +1857,11 @@ static void gen_opcode (unsigned long int opcode) case i_Scc: genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0); start_brace (); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); printf ("\tint val = cctrue(%d) ? 0xff : 0;\n", curi->cc); if (using_ce) { - printf ("\tint cycles = -lostcycles;\n"); + printf ("\tint cycles = 0;\n"); if (isreg (curi->smode)) printf ("\tif (val) cycles += 2 * %d;\n", CYCLE_UNIT / 2); addcycles3 ("\t"); @@ -1883,8 +1872,6 @@ static void gen_opcode (unsigned long int opcode) printf ("\tuaecptr oldpc = m68k_getpc();\n"); genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); - fill_prefetch_next_cycles (); - sync_m68k_pc (); printf ("\tCLEAR_CZNV;\n"); printf ("\tif (src == 0) {\n"); if (cpu_level > 0) { @@ -1900,7 +1887,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n"); printf ("\t\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n"); if (using_ce) { - printf ("\t\tint cycles = 138 * %d - lostcycles;\n", CYCLE_UNIT / 2); + printf ("\t\tint cycles = getDivu68kCycles((uae_u32)dst, (uae_u16)src) * %d;\n", CYCLE_UNIT / 2); addcycles3 ("\t\t"); } /* The N flag appears to be set each time there is an overflow. @@ -1918,16 +1905,16 @@ static void gen_opcode (unsigned long int opcode) printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); printf ("\t\t}\n"); + fill_prefetch_next (); + sync_m68k_pc (); printf ("\t}\n"); - insn_n_cycles += 136; + insn_n_cycles += 136 - (136 - 76) / 2; /* average */ need_endlabel = 1; break; case i_DIVS: printf ("\tuaecptr oldpc = m68k_getpc();\n"); genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); - fill_prefetch_next_cycles (); - sync_m68k_pc (); printf ("\tCLEAR_CZNV;\n"); printf ("\tif (src == 0) {\n"); if (cpu_level > 0) { @@ -1943,7 +1930,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n"); printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n"); if (using_ce) { - printf ("\t\tint cycles = 156 * %d - lostcycles;\n", CYCLE_UNIT / 2); + printf ("\t\tint cycles = getDivs68kCycles((uae_s32)dst, (uae_s16)src) * %d;\n", CYCLE_UNIT / 2); addcycles3 ("\t\t"); } printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n"); @@ -1960,18 +1947,20 @@ static void gen_opcode (unsigned long int opcode) printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); printf ("\t\t}\n"); + fill_prefetch_next (); + sync_m68k_pc (); printf ("\t}\n"); - insn_n_cycles += 154; + insn_n_cycles += 156 - (156 - 120) / 2; /* average */ need_endlabel = 1; break; case i_MULU: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n"); if (using_ce) - printf ("\tint cycles = 36 * %d - lostcycles, bits;\n", CYCLE_UNIT / 2); + printf ("\tint cycles = 36 * %d, bits;\n", CYCLE_UNIT / 2); genflags (flag_logical, sz_long, "newv", "", ""); if (using_ce) { printf ("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n"); @@ -1985,11 +1974,11 @@ static void gen_opcode (unsigned long int opcode) case i_MULS: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n"); if (using_ce) - printf ("\tint cycles = 36 * %d - lostcycles, bits;\n", CYCLE_UNIT / 2); + printf ("\tint cycles = 36 * %d, bits;\n", CYCLE_UNIT / 2); genflags (flag_logical, sz_long, "newv", "", ""); if (using_ce) { printf ("\tsrc <<= 1;\n"); @@ -2047,7 +2036,7 @@ static void gen_opcode (unsigned long int opcode) case i_ASR: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; @@ -2083,7 +2072,7 @@ static void gen_opcode (unsigned long int opcode) case i_ASL: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; @@ -2122,7 +2111,7 @@ static void gen_opcode (unsigned long int opcode) case i_LSR: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; @@ -2154,7 +2143,7 @@ static void gen_opcode (unsigned long int opcode) case i_LSL: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; @@ -2187,7 +2176,7 @@ static void gen_opcode (unsigned long int opcode) case i_ROL: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; @@ -2217,7 +2206,7 @@ static void gen_opcode (unsigned long int opcode) case i_ROR: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; @@ -2247,7 +2236,7 @@ static void gen_opcode (unsigned long int opcode) case i_ROXL: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; @@ -2280,7 +2269,7 @@ static void gen_opcode (unsigned long int opcode) case i_ROXR: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); - fill_prefetch_next_cycles (); + fill_prefetch_next(); start_brace (); switch (curi->size) { case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; diff --git a/gengenblitter.c b/gengenblitter.c index a5659bf3..8b964bd9 100755 --- a/gengenblitter.c +++ b/gengenblitter.c @@ -105,7 +105,7 @@ static int tree_cst (tree t, unsigned int *src, unsigned int *notsrc) case op_xor: case op_or: return 4 + tree_cst (t->left, src, notsrc) + tree_cst (t->right, src, notsrc); - + default: abort (); } @@ -173,7 +173,7 @@ static void do_sprint_tree (char *s, tree t) case op_or: case op_xor: { - + char *c = op == op_and ? " & " : op == op_or ? " | " : " ^ "; strcat (s, "("); do_sprint_tree (s, t->left); @@ -300,7 +300,7 @@ static void find_best_trees (void) for (size = 2; ! do_stop && size < 20; size++) { int split, last_split; tree_vec *sv = size_trees + size - 1; - + if (n_unknown == 0) do_stop = 1; last_split = (size >> 1) + 1; diff --git a/genp2c.c b/genp2c.c index b6d09df6..3be5c28b 100755 --- a/genp2c.c +++ b/genp2c.c @@ -360,7 +360,7 @@ static void gen_x86_set_hires_h (int pl, int mode) } break; } - + if (i < pl) { orl (esi, ecx); orl (ebp, ebx); @@ -388,7 +388,7 @@ static void gen_x86_set_hires_h (int pl, int mode) printf ("\n\n"); } -/* Squeeze: every second bit does not generate a pixel +/* Squeeze: every second bit does not generate a pixel Not optimized, this mode isn't useful. */ static void gen_x86_set_hires_l (int pl, int mode) { @@ -405,7 +405,7 @@ static void gen_x86_set_hires_l (int pl, int mode) pushl (esi); pushl (edi); pushl (ebx); - + movl (ind (esp, 20), ebp); movl (ind (esp, 24), esi); movl (imm (0), edi); @@ -464,7 +464,7 @@ static void gen_x86_set_lores_h (int pl, int mode) pushl (esi); pushl (edi); pushl (ebx); - + movl (ind (esp, 20), ebp); movl (ind (esp, 24), esi); movl (imm (0), edi); @@ -483,7 +483,7 @@ static void gen_x86_set_lores_h (int pl, int mode) char *data1 = (i == 0 && mode != 2 ? ecx : edx); char *data2 = (i == 0 && mode != 2 ? ebx : eax); char *indb0; - + indb0 = gen_indx (esi, realpl*MAX_WORDS_PER_LINE*2, edi, 1); movzbl (indb0, data2); free (indb0); @@ -542,10 +542,10 @@ static void gen_c_set_hires_h (int pl, int mode, int header) for (i = 0; i <= pl; i++) { int realpl = i * plmul + ploff; char *asgn = (i == 0 && mode != 2 ? "=" : "|="); - + printf ("\t\t{\n"); printf ("\t\t\tunsigned int data = *(ptr + i + %d);\n", MAX_WORDS_PER_LINE*2*realpl); - + printf ("\t\t\tv1 %s hirestab_h[data][0] << %d;\n", asgn, realpl); printf ("\t\t\tv2 %s hirestab_h[data][1] << %d;\n", asgn, realpl); printf ("\t\t}\n"); @@ -556,7 +556,7 @@ static void gen_c_set_hires_h (int pl, int mode, int header) printf ("}\n\n"); } -/* Squeeze: every second bit does not generate a pixel +/* Squeeze: every second bit does not generate a pixel Not optimized, this mode isn't useful. */ static void gen_c_set_hires_l (int pl, int mode, int header) { @@ -581,7 +581,7 @@ static void gen_c_set_hires_l (int pl, int mode, int header) for (i = 0; i <= pl; i++) { int realpl = i * plmul + ploff; char *asgn = (i == 0 && mode != 2 ? "=" : "|="); - + printf ("\t\t{\n"); printf ("\t\t\tunsigned int data = *(ptr + i + %d);\n", MAX_WORDS_PER_LINE*2*realpl); diff --git a/identify.c b/identify.c index 792e075a..cc81713f 100755 --- a/identify.c +++ b/identify.c @@ -1,7 +1,7 @@ /* * UAE - The Un*x Amiga Emulator * - * Routines for labelling amiga internals. + * Routines for labelling amiga internals. * */ @@ -111,7 +111,7 @@ struct mem_labels mem_labels[] = { NULL, 0 } }; -/* This table was generated from the list of AGA chip names in +/* This table was generated from the list of AGA chip names in * AGA.guide available on aminet. It could well have errors in it. */ struct customData custd[] = diff --git a/include/bsdsocket.h b/include/bsdsocket.h index cacdcb03..33ca35b4 100755 --- a/include/bsdsocket.h +++ b/include/bsdsocket.h @@ -27,6 +27,12 @@ extern void deinit_socket_layer (void); #define MAXADDRLEN 256 +#ifdef _WIN32 +#define SOCKET_TYPE SOCKET +#else +#define SOCKET_TYPE int +#endif + /* allocated and maintained on a per-task basis */ struct socketbase { struct socketbase *next; @@ -39,7 +45,7 @@ struct socketbase { uae_u32 errnoptr, herrnoptr; /* pointers */ uae_u32 errnosize, herrnosize; /* pinter sizes */ int dtablesize; /* current descriptor/flag etc. table size */ - int *dtable; /* socket descriptor table */ + SOCKET_TYPE *dtable; /* socket descriptor table */ int *ftable; /* socket flags */ int resultval; uae_u32 hostent; /* pointer to the current hostent structure (Amiga mem) */ @@ -56,8 +62,8 @@ struct socketbase { /* host-specific fields below */ #ifdef _WIN32 - unsigned int sockAbort; /* for aborting WinSock2 select() (damn Microsoft) */ - unsigned int sockAsync; /* for aborting WSBAsyncSelect() in window message handler */ + SOCKET_TYPE sockAbort; /* for aborting WinSock2 select() (damn Microsoft) */ + SOCKET_TYPE sockAsync; /* for aborting WSBAsyncSelect() in window message handler */ int needAbort; /* abort flag */ void *hAsyncTask; /* async task handle */ void *hEvent; /* thread event handle */ @@ -112,7 +118,7 @@ extern uae_u32 strncpyha (uae_u32, char *, int); extern void seterrno (SB, int); extern void setherrno (SB, int); -extern void sockmsg (unsigned int, unsigned long, unsigned long); +extern void sockmsg (unsigned int, WPARAM, LPARAM); extern void sockabort (SB); extern void addtosigqueue (SB, int); @@ -122,9 +128,9 @@ extern void locksigqueue (void); extern void unlocksigqueue (void); extern BOOL checksd(SB, int sd); -extern void setsd(SB, int ,int ); -extern int getsd (SB, int); -extern int getsock (SB, int); +extern void setsd(SB, int , SOCKET_TYPE); +extern int getsd (SB, SOCKET_TYPE); +extern SOCKET_TYPE getsock (SB, int); extern void releasesock (SB, int); extern void waitsig (SB); @@ -133,7 +139,7 @@ extern void cancelsig (SB); extern int host_sbinit (SB); extern void host_sbcleanup (SB); extern void host_sbreset (void); -extern void host_closesocketquick (int); +extern void host_closesocketquick (SOCKET_TYPE); extern int host_dup2socket (SB, int, int); extern int host_socket (SB, int, int, int); diff --git a/include/catweasel.h b/include/catweasel.h index 8ff11704..5fb6b281 100755 --- a/include/catweasel.h +++ b/include/catweasel.h @@ -10,6 +10,9 @@ extern uae_u32 catweasel_do_bget (uaecptr addr); extern void catweasel_do_bput (uaecptr addr, uae_u32 b); extern int catweasel_read_joystick (uae_u8 *dir, uae_u8 *buttons); extern void catweasel_hsync (void); +extern int catweasel_isjoystick(void); +extern int catweasel_ismouse(void); +extern int catweasel_read_mouse(int port, int *dx, int *dy, int *buttons); typedef struct catweasel_drive { struct catweasel_contr *contr; /* The controller this drive belongs to */ @@ -40,6 +43,8 @@ typedef struct catweasel_contr { unsigned char srm_dskready; int io_sr; /* IO port of control / status register */ int io_mem; /* IO port of memory register */ + int sid[2]; + int can_sid, can_mouse, can_joy, can_kb; } catweasel_contr; #define CATWEASEL_TYPE_NONE -1 @@ -84,4 +89,5 @@ int catweasel_fillmfm (catweasel_drive *d, uae_u16 *mfm, int side, int clock, in int catweasel_diskready(catweasel_drive *d); int catweasel_track0(catweasel_drive *d); + #endif \ No newline at end of file diff --git a/include/commpipe.h b/include/commpipe.h index 7c27d319..128009c3 100755 --- a/include/commpipe.h +++ b/include/commpipe.h @@ -71,7 +71,7 @@ static __inline__ void write_comm_pipe_pt (smp_comm_pipe *p, uae_pt data, int no maybe_wake_reader (p, no_buffer); return; } - + uae_sem_wait (&p->lock); if (nxwrp == p->rdp) { /* Pipe full! */ diff --git a/include/compemu_old.h b/include/compemu_old.h deleted file mode 100755 index a8b2a756..00000000 --- a/include/compemu_old.h +++ /dev/null @@ -1,527 +0,0 @@ -#define USE_OPTIMIZER 0 -#define USE_LOW_OPTIMIZER 0 -#define USE_ALIAS 1 -#define USE_F_ALIAS 1 -#define USE_SOFT_FLUSH 1 -#define USE_OFFSET 1 -#define COMP_DEBUG 1 - -#if COMP_DEBUG -#define Dif(x) if (x) -#else -#define Dif(x) if (0) -#endif - -#define SCALE 2 -#define MAXCYCLES (1000 * CYCLE_UNIT) -#define MAXREGOPT 65536 - -#define BYTES_PER_INST 10240 /* paranoid ;-) */ -#define LONGEST_68K_INST 16 /* The number of bytes the longest possible - 68k instruction takes */ -#define MAX_CHECKSUM_LEN 2048 /* The maximum size we calculate checksums - for. Anything larger will be flushed - unconditionally even with SOFT_FLUSH */ -#define MAX_HOLD_BI 3 /* One for the current block, and up to two - for jump targets */ - -#define INDIVIDUAL_INST 0 -#define FLAG_C 0x0010 -#define FLAG_V 0x0008 -#define FLAG_Z 0x0004 -#define FLAG_N 0x0002 -#define FLAG_X 0x0001 -#define FLAG_CZNV (FLAG_C | FLAG_Z | FLAG_N | FLAG_V) -#define FLAG_ZNV (FLAG_Z | FLAG_N | FLAG_V) - -#define KILLTHERAT 1 /* Set to 1 to avoid some partial_rat_stalls */ - -/* Whether to preserve registers across calls to JIT compiled routines */ -#if defined X86_ASSEMBLY -#define USE_PUSH_POP 0 -#else -#define USE_PUSH_POP 1 -#endif - -#define N_REGS 8 /* really only 7, but they are numbered 0,1,2,3,5,6,7 */ -#define N_FREGS 6 /* That leaves us two positions on the stack to play with */ - -/* Functions exposed to newcpu, or to what was moved from newcpu.c to - * compemu_support.c */ -extern void init_comp(void); -extern void flush(int save_regs); -extern void small_flush(int save_regs); -extern void set_target(uae_u8* t); -extern uae_u8* get_target(void); -extern void freescratch(void); -extern void build_comp(void); -extern void set_cache_state(int enabled); -extern int get_cache_state(void); -extern uae_u32 get_jitted_size(void); -#ifdef JIT -extern void flush_icache(int n); -#endif -extern void alloc_cache(void); -extern void compile_block(cpu_history* pc_hist, int blocklen, int totcyles); -extern void lopt_emit_all(void); -extern int check_for_cache_miss(void); - - -#define scaled_cycles(x) (currprefs.m68k_speed==-1?(((x)/SCALE)?(((x)/SCALE= REGALLOC */ -#define DECLARE(func) extern void func; extern void do_##func -#else -#define REGALLOC_O 2000000 -#define PEEPHOLE_O 2000000 -#define DECLARE(func) extern void func -#endif - - -/* What we expose to the outside */ -DECLARE(bt_l_ri(R4 r, IMM i)); -DECLARE(bt_l_rr(R4 r, R4 b)); -DECLARE(btc_l_ri(RW4 r, IMM i)); -DECLARE(btc_l_rr(RW4 r, R4 b)); -DECLARE(bts_l_ri(RW4 r, IMM i)); -DECLARE(bts_l_rr(RW4 r, R4 b)); -DECLARE(btr_l_ri(RW4 r, IMM i)); -DECLARE(btr_l_rr(RW4 r, R4 b)); -DECLARE(mov_l_rm(W4 d, IMM s)); -DECLARE(call_r(R4 r)); -DECLARE(sub_l_mi(IMM d, IMM s)); -DECLARE(mov_l_mi(IMM d, IMM s)); -DECLARE(mov_w_mi(IMM d, IMM s)); -DECLARE(mov_b_mi(IMM d, IMM s)); -DECLARE(rol_b_ri(RW1 r, IMM i)); -DECLARE(rol_w_ri(RW2 r, IMM i)); -DECLARE(rol_l_ri(RW4 r, IMM i)); -DECLARE(rol_l_rr(RW4 d, R1 r)); -DECLARE(rol_w_rr(RW2 d, R1 r)); -DECLARE(rol_b_rr(RW1 d, R1 r)); -DECLARE(shll_l_rr(RW4 d, R1 r)); -DECLARE(shll_w_rr(RW2 d, R1 r)); -DECLARE(shll_b_rr(RW1 d, R1 r)); -DECLARE(ror_b_ri(R1 r, IMM i)); -DECLARE(ror_w_ri(R2 r, IMM i)); -DECLARE(ror_l_ri(R4 r, IMM i)); -DECLARE(ror_l_rr(R4 d, R1 r)); -DECLARE(ror_w_rr(R2 d, R1 r)); -DECLARE(ror_b_rr(R1 d, R1 r)); -DECLARE(shrl_l_rr(RW4 d, R1 r)); -DECLARE(shrl_w_rr(RW2 d, R1 r)); -DECLARE(shrl_b_rr(RW1 d, R1 r)); -DECLARE(shra_l_rr(RW4 d, R1 r)); -DECLARE(shra_w_rr(RW2 d, R1 r)); -DECLARE(shra_b_rr(RW1 d, R1 r)); -DECLARE(shll_l_ri(RW4 r, IMM i)); -DECLARE(shll_w_ri(RW2 r, IMM i)); -DECLARE(shll_b_ri(RW1 r, IMM i)); -DECLARE(shrl_l_ri(RW4 r, IMM i)); -DECLARE(shrl_w_ri(RW2 r, IMM i)); -DECLARE(shrl_b_ri(RW1 r, IMM i)); -DECLARE(shra_l_ri(RW4 r, IMM i)); -DECLARE(shra_w_ri(RW2 r, IMM i)); -DECLARE(shra_b_ri(RW1 r, IMM i)); -DECLARE(setcc(W1 d, IMM cc)); -DECLARE(setcc_m(IMM d, IMM cc)); -DECLARE(cmov_l_rr(RW4 d, R4 s, IMM cc)); -DECLARE(cmov_l_rm(RW4 d, IMM s, IMM cc)); -DECLARE(bsf_l_rr(W4 d, R4 s)); -DECLARE(pop_m(IMM d)); -DECLARE(push_m(IMM d)); -DECLARE(pop_l(W4 d)); -DECLARE(push_l_i(IMM i)); -DECLARE(push_l(R4 s)); -DECLARE(clear_16(RW4 r)); -DECLARE(clear_8(RW4 r)); -DECLARE(sign_extend_16_rr(W4 d, R2 s)); -DECLARE(sign_extend_8_rr(W4 d, R1 s)); -DECLARE(zero_extend_16_rr(W4 d, R2 s)); -DECLARE(zero_extend_8_rr(W4 d, R1 s)); -DECLARE(imul_64_32(RW4 d, RW4 s)); -DECLARE(mul_64_32(RW4 d, RW4 s)); -DECLARE(imul_32_32(RW4 d, R4 s)); -DECLARE(mul_32_32(RW4 d, R4 s)); -DECLARE(mov_b_rr(W1 d, R1 s)); -DECLARE(mov_w_rr(W2 d, R2 s)); -DECLARE(mov_l_rrm_indexed(W4 d,R4 baser, R4 index, IMM factor)); -DECLARE(mov_w_rrm_indexed(W2 d, R4 baser, R4 index, IMM factor)); -DECLARE(mov_b_rrm_indexed(W1 d, R4 baser, R4 index, IMM factor)); -DECLARE(mov_l_mrr_indexed(R4 baser, R4 index, IMM factor, R4 s)); -DECLARE(mov_w_mrr_indexed(R4 baser, R4 index, IMM factor, R2 s)); -DECLARE(mov_b_mrr_indexed(R4 baser, R4 index, IMM factor, R1 s)); -DECLARE(mov_l_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R4 s)); -DECLARE(mov_w_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R2 s)); -DECLARE(mov_b_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R1 s)); -DECLARE(mov_l_brrm_indexed(W4 d, IMM base, R4 baser, R4 index, IMM factor)); -DECLARE(mov_w_brrm_indexed(W2 d, IMM base, R4 baser, R4 index, IMM factor)); -DECLARE(mov_b_brrm_indexed(W1 d, IMM base, R4 baser, R4 index, IMM factor)); -DECLARE(mov_l_rm_indexed(W4 d, IMM base, R4 index, IMM factor)); -DECLARE(mov_l_rR(W4 d, R4 s, IMM offset)); -DECLARE(mov_w_rR(W2 d, R4 s, IMM offset)); -DECLARE(mov_b_rR(W1 d, R4 s, IMM offset)); -DECLARE(mov_l_brR(W4 d, R4 s, IMM offset)); -DECLARE(mov_w_brR(W2 d, R4 s, IMM offset)); -DECLARE(mov_b_brR(W1 d, R4 s, IMM offset)); -DECLARE(mov_l_Ri(R4 d, IMM i, IMM offset)); -DECLARE(mov_w_Ri(R4 d, IMM i, IMM offset)); -DECLARE(mov_b_Ri(R4 d, IMM i, IMM offset)); -DECLARE(mov_l_Rr(R4 d, R4 s, IMM offset)); -DECLARE(mov_w_Rr(R4 d, R2 s, IMM offset)); -DECLARE(mov_b_Rr(R4 d, R1 s, IMM offset)); -DECLARE(lea_l_brr(W4 d, R4 s, IMM offset)); -DECLARE(lea_l_brr_indexed(W4 d, R4 s, R4 index, IMM factor, IMM offset)); -DECLARE(lea_l_rr_indexed(W4 d, R4 s, R4 index, IMM factor)); -DECLARE(mov_l_bRr(R4 d, R4 s, IMM offset)); -DECLARE(mov_w_bRr(R4 d, R2 s, IMM offset)); -DECLARE(mov_b_bRr(R4 d, R1 s, IMM offset)); -DECLARE(bswap_32(RW4 r)); -DECLARE(bswap_16(RW2 r)); -DECLARE(mov_l_rr(W4 d, R4 s)); -DECLARE(mov_l_mr(IMM d, R4 s)); -DECLARE(mov_w_mr(IMM d, R2 s)); -DECLARE(mov_w_rm(W2 d, IMM s)); -DECLARE(mov_b_mr(IMM d, R1 s)); -DECLARE(mov_b_rm(W1 d, IMM s)); -DECLARE(mov_l_ri(W4 d, IMM s)); -DECLARE(mov_w_ri(W2 d, IMM s)); -DECLARE(mov_b_ri(W1 d, IMM s)); -DECLARE(add_l_mi(IMM d, IMM s) ); -DECLARE(add_w_mi(IMM d, IMM s) ); -DECLARE(add_b_mi(IMM d, IMM s) ); -DECLARE(test_l_ri(R4 d, IMM i)); -DECLARE(test_l_rr(R4 d, R4 s)); -DECLARE(test_w_rr(R2 d, R2 s)); -DECLARE(test_b_rr(R1 d, R1 s)); -DECLARE(and_l_ri(RW4 d, IMM i)); -DECLARE(and_l(RW4 d, R4 s)); -DECLARE(and_w(RW2 d, R2 s)); -DECLARE(and_b(RW1 d, R1 s)); -DECLARE(or_l_ri(RW4 d, IMM i)); -DECLARE(or_l(RW4 d, R4 s)); -DECLARE(or_w(RW2 d, R2 s)); -DECLARE(or_b(RW1 d, R1 s)); -DECLARE(adc_l(RW4 d, R4 s)); -DECLARE(adc_w(RW2 d, R2 s)); -DECLARE(adc_b(RW1 d, R1 s)); -DECLARE(add_l(RW4 d, R4 s)); -DECLARE(add_w(RW2 d, R2 s)); -DECLARE(add_b(RW1 d, R1 s)); -DECLARE(sub_l_ri(RW4 d, IMM i)); -DECLARE(sub_w_ri(RW2 d, IMM i)); -DECLARE(sub_b_ri(RW1 d, IMM i)); -DECLARE(add_l_ri(RW4 d, IMM i)); -DECLARE(add_w_ri(RW2 d, IMM i)); -DECLARE(add_b_ri(RW1 d, IMM i)); -DECLARE(sbb_l(RW4 d, R4 s)); -DECLARE(sbb_w(RW2 d, R2 s)); -DECLARE(sbb_b(RW1 d, R1 s)); -DECLARE(sub_l(RW4 d, R4 s)); -DECLARE(sub_w(RW2 d, R2 s)); -DECLARE(sub_b(RW1 d, R1 s)); -DECLARE(cmp_l(R4 d, R4 s)); -DECLARE(cmp_l_ri(R4 r, IMM i)); -DECLARE(cmp_w(R2 d, R2 s)); -DECLARE(cmp_b(R1 d, R1 s)); -DECLARE(xor_l(RW4 d, R4 s)); -DECLARE(xor_w(RW2 d, R2 s)); -DECLARE(xor_b(RW1 d, R1 s)); -DECLARE(live_flags(void)); -DECLARE(dont_care_flags(void)); -DECLARE(duplicate_carry(void)); -DECLARE(restore_carry(void)); -DECLARE(start_needflags(void)); -DECLARE(end_needflags(void)); -DECLARE(make_flags_live(void)); -DECLARE(call_r_11(R4 r, W4 out1, R4 in1, IMM osize, IMM isize)); -DECLARE(call_r_02(R4 r, R4 in1, R4 in2, IMM isize1, IMM isize2)); -DECLARE(readmem_new(R4 address, W4 dest, IMM offset, IMM size, W4 tmp)); -DECLARE(writemem_new(R4 address, R4 source, IMM offset, IMM size, W4 tmp)); -DECLARE(forget_about(W4 r)); -DECLARE(nop(void)); - -DECLARE(f_forget_about(FW r)); -DECLARE(fmov_pi(FW r)); -DECLARE(fmov_log10_2(FW r)); -DECLARE(fmov_log2_e(FW r)); -DECLARE(fmov_loge_2(FW r)); -DECLARE(fmov_1(FW r)); -DECLARE(fmov_0(FW r)); -DECLARE(fmov_rm(FW r, MEMR m)); -DECLARE(fmovi_rm(FW r, MEMR m)); -DECLARE(fmovi_mr(MEMW m, FR r)); -DECLARE(fmovs_rm(FW r, MEMR m)); -DECLARE(fmovs_mr(MEMW m, FR r)); -DECLARE(fmov_mr(MEMW m, FR r)); -DECLARE(fmov_ext_mr(MEMW m, FR r)); -DECLARE(fmov_ext_rm(FW r, MEMR m)); -DECLARE(fmov_rr(FW d, FR s)); -DECLARE(fldcw_m_indexed(R4 index, IMM base)); -DECLARE(ftst_r(FR r)); -DECLARE(dont_care_fflags(void)); -DECLARE(fsqrt_rr(FW d, FR s)); -DECLARE(fabs_rr(FW d, FR s)); -DECLARE(frndint_rr(FW d, FR s)); -DECLARE(fsin_rr(FW d, FR s)); -DECLARE(fcos_rr(FW d, FR s)); -DECLARE(ftwotox_rr(FW d, FR s)); -DECLARE(fetox_rr(FW d, FR s)); -DECLARE(flog2_rr(FW d, FR s)); -DECLARE(fneg_rr(FW d, FR s)); -DECLARE(fadd_rr(FRW d, FR s)); -DECLARE(fsub_rr(FRW d, FR s)); -DECLARE(fmul_rr(FRW d, FR s)); -DECLARE(frem_rr(FRW d, FR s)); -DECLARE(frem1_rr(FRW d, FR s)); -DECLARE(fdiv_rr(FRW d, FR s)); -DECLARE(fcmp_rr(FR d, FR s)); -DECLARE(fflags_into_flags(W2 tmp)); - -extern int failure; -#define FAIL(x) do { failure|=x; } while (0) - -/* Convenience functions exposed to gencomp */ -extern uae_u32 m68k_pc_offset; -extern void readbyte(int address, int dest, int tmp); -extern void readword(int address, int dest, int tmp); -extern void readlong(int address, int dest, int tmp); -extern void writebyte(int address, int source, int tmp); -extern void writeword(int address, int source, int tmp); -extern void writelong(int address, int source, int tmp); -extern void writeword_clobber(int address, int source, int tmp); -extern void writelong_clobber(int address, int source, int tmp); -extern void get_n_addr(int address, int dest, int tmp); -extern void get_n_addr_jmp(int address, int dest, int tmp); -extern void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp); -extern int kill_rodent(int r); -extern void sync_m68k_pc(void); -extern uae_u32 get_const(int r); -extern int is_const(int r); -extern void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond); -extern void empty_optimizer(void); - -#define comp_get_ibyte(o) do_get_mem_byte((uae_u8 *)(comp_pc_p + (o) + 1)) -#define comp_get_iword(o) do_get_mem_word((uae_u16 *)(comp_pc_p + (o))) -#define comp_get_ilong(o) do_get_mem_long((uae_u32 *)(comp_pc_p + (o))) - -/* Preferences handling */ -void check_prefs_changed_comp (void); - -struct blockinfo_t; - -typedef struct dep_t { - uae_u32* jmp_off; - struct blockinfo_t* target; - struct dep_t** prev_p; - struct dep_t* next; -} dependency; - -typedef struct blockinfo_t { - uae_s32 count; - cpuop_func* direct_handler_to_use; - cpuop_func* handler_to_use; - /* The direct handler does not check for the correct address */ - - cpuop_func* handler; - cpuop_func* direct_handler; - - cpuop_func* direct_pen; - cpuop_func* direct_pcc; - - uae_u8* nexthandler; - uae_u8* pc_p; - - uae_u32 c1; - uae_u32 c2; - uae_u32 len; - - struct blockinfo_t* next_same_cl; - struct blockinfo_t** prev_same_cl_p; - struct blockinfo_t* next; - struct blockinfo_t** prev_p; - - uae_u32 min_pcp; - uae_u8 optlevel; - uae_u8 needed_flags; - uae_u8 status; - uae_u8 havestate; - - dependency dep[2]; /* Holds things we depend on */ - dependency* deplist; /* List of things that depend on this */ - smallstate env; -} blockinfo; - -#define BI_NEW 0 -#define BI_COUNTING 1 -#define BI_TARGETTED 2 - -typedef struct { - uae_u8 type; - uae_u8 reg; - uae_u32 next; -} regacc; - -void execute_normal(void); -void exec_nostats(void); -void do_nothing(void); - diff --git a/include/drawing.h b/include/drawing.h index 9b7d3f6b..27b234c3 100755 --- a/include/drawing.h +++ b/include/drawing.h @@ -1,6 +1,6 @@ /* * Data used for communication between custom.c and drawing.c. - * + * * Copyright 1996-1998 Bernd Schmidt */ @@ -57,7 +57,7 @@ extern int framecnt; /* color values in two formats: 12 (OCS/ECS) or 24 (AGA) bit Amiga RGB (color_regs), - * and the native color value; both for each Amiga hardware color register. + * and the native color value; both for each Amiga hardware color register. * * !!! See color_reg_xxx functions below before touching !!! */ @@ -116,7 +116,7 @@ STATIC_INLINE int color_reg_cmp (struct color_entry *ce1, struct color_entry *ce return memcmp (ce1->color_regs_aga, ce2->color_regs_aga, sizeof (uae_u32) * 256); else #endif - return memcmp (ce1->color_regs_ecs, ce2->color_regs_ecs, sizeof (uae_u16) * 32); + return memcmp (ce1->color_regs_ecs, ce2->color_regs_ecs, sizeof (uae_u16) * 32); } /* ugly copy hack, is there better solution? */ STATIC_INLINE void color_reg_cpy (struct color_entry *dst, struct color_entry *src) diff --git a/include/events_jit.h b/include/events_jit.h index 8b1995dc..8686178d 100755 --- a/include/events_jit.h +++ b/include/events_jit.h @@ -66,16 +66,16 @@ STATIC_INLINE void do_cycles_slow (unsigned long cycles_to_add) } } while ((nextevent - currcycle) <= cycles_to_add) { - int i; - cycles_to_add -= (nextevent - currcycle); - currcycle = nextevent; + int i; + cycles_to_add -= (nextevent - currcycle); + currcycle = nextevent; - for (i = 0; i < ev_max; i++) { + for (i = 0; i < ev_max; i++) { if (eventtab[i].active && eventtab[i].evtime == currcycle) { (*eventtab[i].handler)(); } } - events_schedule(); + events_schedule(); } currcycle += cycles_to_add; } @@ -127,7 +127,7 @@ STATIC_INLINE void events_schedule (void) for (i = 0; i < ev_max; i++) { if (eventtab[i].active) { unsigned long int eventtime = eventtab[i].evtime - curcycles; - if (eventtime < mintime) + if (eventtime < mintime) mintime = eventtime; } } @@ -154,7 +154,7 @@ STATIC_INLINE void do_cycles_slow (long cycles_to_add) if (is_lastline && /*cycles_to_next_event <= cycles_to_hsync_event*/ - eventtab[ev_hsync].evtime == nextevent) + eventtab[ev_hsync].evtime == nextevent) { frame_time_t now=read_processor_time(); if (diff32(now, vsyncmintime)<0) diff --git a/include/events_normal.h b/include/events_normal.h index 88f78b3a..b72a1b53 100755 --- a/include/events_normal.h +++ b/include/events_normal.h @@ -28,16 +28,16 @@ STATIC_INLINE void do_cycles_slow (unsigned long cycles_to_add) return; while ((nextevent - currcycle) <= cycles_to_add) { - int i; - cycles_to_add -= (nextevent - currcycle); - currcycle = nextevent; + int i; + cycles_to_add -= (nextevent - currcycle); + currcycle = nextevent; - for (i = 0; i < ev_max; i++) { + for (i = 0; i < ev_max; i++) { if (eventtab[i].active && eventtab[i].evtime == currcycle) { (*eventtab[i].handler)(); } } - events_schedule(); + events_schedule(); } currcycle += cycles_to_add; } diff --git a/include/filesys.h b/include/filesys.h index 92026273..da85147e 100755 --- a/include/filesys.h +++ b/include/filesys.h @@ -15,6 +15,7 @@ struct hardfiledata { int reservedblocks; int blocksize; void *handle; + int handle_valid; int readonly; int flags; uae_u8 *cache; diff --git a/include/fpp-ieee-be.h b/include/fpp-ieee-be.h index 81e67b7b..061c7ab2 100755 --- a/include/fpp-ieee-be.h +++ b/include/fpp-ieee-be.h @@ -12,8 +12,8 @@ STATIC_INLINE double to_single (uae_u32 value) { union { - float f; - uae_u32 u; + float f; + uae_u32 u; } val; val.u = value; @@ -23,8 +23,8 @@ STATIC_INLINE double to_single (uae_u32 value) STATIC_INLINE uae_u32 from_single (double src) { union { - float f; - uae_u32 u; + float f; + uae_u32 u; } val; val.f = src; @@ -34,8 +34,8 @@ STATIC_INLINE uae_u32 from_single (double src) STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2) { union { - double d; - uae_u32 u[2]; + double d; + uae_u32 u[2]; } val; val.u[0] = wrd1; @@ -46,8 +46,8 @@ STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2) STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2) { union { - double d; - uae_u32 u[2]; + double d; + uae_u32 u[2]; } val; val.d = src; diff --git a/include/fpp-unknown.h b/include/fpp-unknown.h index 26d5e1ff..aa991640 100755 --- a/include/fpp-unknown.h +++ b/include/fpp-unknown.h @@ -14,10 +14,10 @@ STATIC_INLINE double to_single (uae_u32 value) double frac; if ((value & 0x7fffffff) == 0) - return (0.0); + return (0.0); frac = (double) ((value & 0x7fffff) | 0x800000) / 8388608.0; if (value & 0x80000000) - frac = -frac; + frac = -frac; return (ldexp (frac, ((value >> 23) & 0xff) - 127)); } #endif @@ -30,21 +30,21 @@ STATIC_INLINE uae_u32 from_single (double src) double frac; if (src == 0.0) - return 0; + return 0; if (src < 0) { - tmp = 0x80000000; - src = -src; + tmp = 0x80000000; + src = -src; } else { - tmp = 0; + tmp = 0; } frac = frexp (src, &expon); frac += 0.5 / 16777216.0; if (frac >= 1.0) { - frac /= 2.0; - expon++; + frac /= 2.0; + expon++; } return (tmp | (((expon + 127 - 1) & 0xff) << 23) | - (((int) (frac * 16777216.0)) & 0x7fffff)); + (((int) (frac * 16777216.0)) & 0x7fffff)); } #endif @@ -54,11 +54,11 @@ STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) double frac; if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) - return 0.0; + return 0.0; frac = (double) wrd2 / 2147483648.0 + - (double) wrd3 / 9223372036854775808.0; + (double) wrd3 / 9223372036854775808.0; if (wrd1 & 0x80000000) - frac = -frac; + frac = -frac; return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383); } #endif @@ -70,22 +70,22 @@ STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u3 double frac; if (src == 0.0) { - *wrd1 = 0; - *wrd2 = 0; - *wrd3 = 0; - return; + *wrd1 = 0; + *wrd2 = 0; + *wrd3 = 0; + return; } if (src < 0) { - *wrd1 = 0x80000000; - src = -src; + *wrd1 = 0x80000000; + src = -src; } else { - *wrd1 = 0; + *wrd1 = 0; } frac = frexp (src, &expon); frac += 0.5 / 18446744073709551616.0; if (frac >= 1.0) { - frac /= 2.0; - expon++; + frac /= 2.0; + expon++; } *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16); *wrd2 = (uae_u32) (frac * 4294967296.0); @@ -99,11 +99,11 @@ STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2) double frac; if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) - return 0.0; + return 0.0; frac = (double) ((wrd1 & 0xfffff) | 0x100000) / 1048576.0 + - (double) wrd2 / 4503599627370496.0; + (double) wrd2 / 4503599627370496.0; if (wrd1 & 0x80000000) - frac = -frac; + frac = -frac; return ldexp (frac, ((wrd1 >> 20) & 0x7ff) - 1023); } #endif @@ -116,21 +116,21 @@ STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2) double frac; if (src == 0.0) { - *wrd1 = 0; - *wrd2 = 0; - return; + *wrd1 = 0; + *wrd2 = 0; + return; } if (src < 0) { - *wrd1 = 0x80000000; - src = -src; + *wrd1 = 0x80000000; + src = -src; } else { - *wrd1 = 0; + *wrd1 = 0; } frac = frexp (src, &expon); frac += 0.5 / 9007199254740992.0; if (frac >= 1.0) { - frac /= 2.0; - expon++; + frac /= 2.0; + expon++; } tmp = (uae_u32) (frac * 2097152.0); *wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff); diff --git a/include/gfxfilter.h b/include/gfxfilter.h index cd941cd9..c3a1bb8d 100755 --- a/include/gfxfilter.h +++ b/include/gfxfilter.h @@ -21,9 +21,9 @@ extern void Super2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint extern void SuperEagle(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); extern void _2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height); extern void AdMame2x(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ - u8 *dstPtr, u32 dstPitch, int width, int height); + u8 *dstPtr, u32 dstPitch, int width, int height); extern void AdMame2x32(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ - u8 *dstPtr, u32 dstPitch, int width, int height); + u8 *dstPtr, u32 dstPitch, int width, int height); extern void hq_init(int rb, int gb, int bb, int rs, int gs, int bs); extern void hq2x_32(unsigned char*, unsigned char*, int, int, int, int, int); diff --git a/include/identify.h b/include/identify.h index 01941c52..e5f39f12 100755 --- a/include/identify.h +++ b/include/identify.h @@ -1,10 +1,10 @@ /* * UAE - The Un*x Amiga Emulator * - * Tables for labelling amiga internals. + * Tables for labelling amiga internals. * */ - + struct mem_labels { const char *name; diff --git a/include/inputdevice.h b/include/inputdevice.h index 8e4ab38c..6d0e2b54 100755 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -102,7 +102,7 @@ extern void inputdevice_updateconfig (struct uae_prefs *prefs); extern int inputdevice_translatekeycode (int keyboard, int scancode, int state); extern void inputdevice_setkeytranslation (struct uae_input_device_kbr_default *trans); -extern void handle_input_event (int nr, int state, int max, int autofire); +extern int handle_input_event (int nr, int state, int max, int autofire); extern void inputdevice_do_keyboard (int code, int state); extern uae_u16 potgo_value; diff --git a/include/memory.h b/include/memory.h index e4bb3b82..e763e03f 100755 --- a/include/memory.h +++ b/include/memory.h @@ -13,9 +13,10 @@ extern void a1000_reset (void); extern int special_mem; #define S_READ 1 #define S_WRITE 2 +#endif + extern void *cache_alloc (int); extern void cache_free (void*); -#endif #ifdef ADDRESS_SPACE_24BIT #define MEMORY_BANKS 256 @@ -115,9 +116,9 @@ extern uae_u8 *baseaddr[MEMORY_BANKS]; #define put_mem_bank(addr, b, realstart) do { \ (mem_banks[bankindex(addr)] = (b)); \ if ((b)->baseaddr) \ - baseaddr[bankindex(addr)] = (b)->baseaddr - (realstart); \ + baseaddr[bankindex(addr)] = (b)->baseaddr - (realstart); \ else \ - baseaddr[bankindex(addr)] = (uae_u8*)(((long)b)+1); \ + baseaddr[bankindex(addr)] = (uae_u8*)(((long)b)+1); \ } while (0) extern void memory_init (void); @@ -243,6 +244,7 @@ extern void clearexec (void); extern void mapkick (void); extern int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom); extern void decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size, uae_u8 *key, int keysize); +extern void init_shm(void); #define ROMTYPE_KICK 1 #define ROMTYPE_KICKCD32 2 diff --git a/include/newcpu.h b/include/newcpu.h index bef11ae3..88154c3d 100755 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -162,12 +162,12 @@ STATIC_INLINE void m68k_setpc (uaecptr newpc) STATIC_INLINE uaecptr m68k_getpc (void) { - return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); + return regs.pc + (uaecptr)(((char *)regs.pc_p - (char *)regs.pc_oldp)); } STATIC_INLINE uaecptr m68k_getpc_p (uae_u8 *p) { - return regs.pc + ((char *)p - (char *)regs.pc_oldp); + return regs.pc + (uaecptr)(((char *)p - (char *)regs.pc_oldp)); } #define get_ibyte(o) do_get_mem_byte((uae_u8 *)(regs.pc_p + (o) + 1)) @@ -253,6 +253,8 @@ extern void m68k_dumpstate (void *, uaecptr *); extern void m68k_disasm (void *, uaecptr, uaecptr *, int); extern void sm68k_disasm(char *, char *, uaecptr addr, uaecptr *nextpc); extern void m68k_reset (void); +extern int getDivu68kCycles(uae_u32 dividend, uae_u16 divisor); +extern int getDivs68kCycles(uae_s32 dividend, uae_s16 divisor); extern void mmu_op (uae_u32, uae_u16); @@ -290,7 +292,7 @@ extern struct cputbl op_smalltbl_6_ff[]; extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl"); - + /* Flags for Bernie during development/debugging. Should go away eventually */ #define DISTRUST_CONSISTENT_MEM 0 #define TAGMASK 0x000fffff diff --git a/include/options.h b/include/options.h index 00d01557..a82dd0d1 100755 --- a/include/options.h +++ b/include/options.h @@ -8,7 +8,7 @@ */ #define UAEMAJOR 1 -#define UAEMINOR 0 +#define UAEMINOR 1 #define UAESUBREV 0 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang; @@ -24,7 +24,7 @@ struct strlist { }; /* maximum number native input devices supported (single type) */ -#define MAX_INPUT_DEVICES 6 +#define MAX_INPUT_DEVICES 8 /* maximum number of native input device's buttons and axles supported */ #define MAX_INPUT_DEVICE_EVENTS 256 /* 4 different customization settings */ @@ -53,8 +53,8 @@ struct uae_prefs { char description[256]; char info[256]; int config_version; - char config_hardware_path[256]; - char config_host_path[256]; + char config_hardware_path[MAX_DPATH]; + char config_host_path[MAX_DPATH]; int illegal_mem; int no_xhair; @@ -156,12 +156,12 @@ struct uae_prefs { int tod_hack; uae_u32 maprom; - char df[4][256]; - char dfxlist[MAX_SPARE_DRIVES][256]; - char romfile[256]; - char romextfile[256]; - char flashfile[256]; - char cartfile[256]; + char df[4][MAX_DPATH]; + char dfxlist[MAX_SPARE_DRIVES][MAX_DPATH]; + char romfile[MAX_DPATH]; + char romextfile[MAX_DPATH]; + char flashfile[MAX_DPATH]; + char cartfile[MAX_DPATH]; char pci_devices[256]; char prtname[256]; char sername[256]; @@ -185,6 +185,7 @@ struct uae_prefs { int kickshifter; int filesys_no_uaefsdb; int filesys_custom_uaefsdb; + int mmkeyboard; struct uaedev_mount_info *mountinfo; diff --git a/include/sysdeps.h b/include/sysdeps.h index 6a78b428..846e8c7e 100755 --- a/include/sysdeps.h +++ b/include/sysdeps.h @@ -116,7 +116,7 @@ struct utimbuf /* sam: some definitions so that SAS/C can compile UAE */ #if defined(__SASC) && defined(AMIGA) -#define REGPARAM2 +#define REGPARAM2 #define REGPARAM #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE @@ -295,7 +295,7 @@ extern void gettimeofday( struct timeval *tv, void *blah ); #define FILEFLAG_SCRIPT 0x20 #define FILEFLAG_PURE 0x40 -#define REGPARAM +#define REGPARAM #include #define O_BINARY _O_BINARY @@ -352,7 +352,7 @@ extern void posixemu_closedir (DIR *); #endif -#endif /* _WIN32 */ +#endif /* _WIN32 */ #ifdef DONT_HAVE_POSIX @@ -454,6 +454,7 @@ extern void f_out (void *, const char *, ...); extern void gui_message (const char *,...); extern int gui_message_multibutton (int flags, const char *format,...); #define write_log_err write_log +extern void logging_init(void); #ifndef O_BINARY #define O_BINARY 0 diff --git a/include/uae.h b/include/uae.h index b29a3de6..59448fe1 100755 --- a/include/uae.h +++ b/include/uae.h @@ -14,6 +14,7 @@ extern void real_main (int, char **); extern void usage (void); extern void parse_cmdline (int argc, char **argv); extern void sleep_millis (int ms); +extern void sleep_millis_busy (int ms); extern int sleep_resolution; extern void uae_reset (int); diff --git a/include/unzip.h b/include/unzip.h index 3c76300e..4b290eca 100755 --- a/include/unzip.h +++ b/include/unzip.h @@ -1,4 +1,4 @@ -/* unzip.h -- IO for uncompress .zip files using zlib +/* unzip.h -- IO for uncompress .zip files using zlib Version 0.15 beta, Mar 19th, 1998, Copyright (C) 1998 Gilles Vollant @@ -33,7 +33,7 @@ */ -/* for more info about .ZIP format, see +/* for more info about .ZIP format, see ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip PkWare has also a specification at : ftp://ftp.pkware.com/probdesc.zip */ @@ -67,7 +67,7 @@ extern CRC32 pcrc32; #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) /* like the STRICT of WIN32, we define a pointer that cannot be converted from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; +typedef struct TagunzFile__ { int unused; } unzFile__; typedef unzFile__ *unzFile; #else typedef voidp unzFile; @@ -84,7 +84,7 @@ typedef voidp unzFile; #define UNZ_CRCERROR (-105) /* tm_unz contain date/time info */ -typedef struct tm_unz_s +typedef struct tm_unz_s { uInt tm_sec; /* seconds after the minute - [0,59] */ uInt tm_min; /* minutes after the hour - [0,59] */ @@ -113,8 +113,8 @@ typedef struct unz_file_info_s uLong compression_method; /* compression method 2 bytes */ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ uLong size_filename; /* filename length 2 bytes */ uLong size_file_extra; /* extra field length 2 bytes */ uLong size_file_comment; /* file comment length 2 bytes */ @@ -191,7 +191,7 @@ extern int ZEXPORT unzGoToNextFile OF((unzFile file)); return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ -extern int ZEXPORT unzLocateFile OF((unzFile file, +extern int ZEXPORT unzLocateFile OF((unzFile file, const char *szFileName, int iCaseSensitivity)); /* @@ -242,8 +242,8 @@ extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); Return UNZ_CRCERROR if all the file was read but the CRC is not good */ - -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, voidp buf, unsigned len)); /* @@ -264,7 +264,7 @@ extern z_off_t ZEXPORT unztell OF((unzFile file)); extern int ZEXPORT unzeof OF((unzFile file)); /* - return 1 if the end of file was reached, 0 elsewhere + return 1 if the end of file was reached, 0 elsewhere */ extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, @@ -279,7 +279,7 @@ extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, if buf!=NULL, len is the size of the buffer, the extra header is copied in buf. - the return value is the number of bytes copied in buf, or (if <0) + the return value is the number of bytes copied in buf, or (if <0) the error code */ diff --git a/include/xwin.h b/include/xwin.h index 7723b1a8..74e51dbe 100755 --- a/include/xwin.h +++ b/include/xwin.h @@ -51,7 +51,7 @@ struct vidbuf_description * - set bufmem to point at it * - set linemem to 0 * - if memcpy within bufmem would be very slow, i.e. because bufmem is - * in graphics card memory, also set emergmem to point to a buffer + * in graphics card memory, also set emergmem to point to a buffer * that is large enough to hold a single line. * - implement flush_line to be a no-op. * If you use a single line buffer: diff --git a/inputdevice.c b/inputdevice.c index a5541526..b29bad77 100755 --- a/inputdevice.c +++ b/inputdevice.c @@ -1333,13 +1333,13 @@ void inputdevice_handle_inputcode (void) } } -void handle_input_event (int nr, int state, int max, int autofire) +int handle_input_event (int nr, int state, int max, int autofire) { struct inputevent *ie; int joy; if (nr <= 0) - return; + return 0; ie = &events[nr]; //write_log("'%s' %d %d\n", ie->name, state, max); if (autofire) { @@ -1446,6 +1446,7 @@ void handle_input_event (int nr, int state, int max, int autofire) inputdevice_do_keyboard (ie->data, state); break; } + return 1; } void inputdevice_vsync (void) @@ -1869,9 +1870,10 @@ int inputdevice_translatekeycode (int keyboard, int scancode, int state) { struct uae_input_device *na = &keyboards[keyboard]; int j, k; + int handled = 0; if (!keyboards || scancode < 0) - return 0; + return handled; j = 0; while (na->extra[j][0] >= 0) { if (na->extra[j][0] == scancode) { @@ -1879,14 +1881,14 @@ int inputdevice_translatekeycode (int keyboard, int scancode, int state) int autofire = (na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] & ID_FLAG_AUTOFIRE) ? 1 : 0; int event = na->eventid[j][sublevdir[state == 0 ? 1 : 0][k]]; char *custom = na->custom[j][sublevdir[state == 0 ? 1 : 0][k]]; - handle_input_event (event, state, 1, autofire); + handled |= handle_input_event (event, state, 1, autofire); //write_log ("'%s' %d ('%s') %d\n", na->name, event, events[event].name, state); } - return 1; + return handled; } j++; } - return 0; + return handled; } static struct inputdevice_functions idev[3]; diff --git a/inputevents.def b/inputevents.def index f9ecab5d..dc176bfd 100755 --- a/inputevents.def +++ b/inputevents.def @@ -240,6 +240,14 @@ DEFEVENT(KEY_CDTV_PLAYPAUSE,"CDTV Play/Pause",AM_K,0,0,0x73) DEFEVENT(KEY_CDTV_FF,"CDTV Fast Forward",AM_K,0,0,0x74) DEFEVENT(KEY_CDTV_REW,"CDTV Rewind",AM_K,0,0,0x75) +DEFEVENT(KEY_47,"Keycode 0x47",AM_K,0,0,0x47) +DEFEVENT(KEY_48,"Keycode 0x48",AM_K,0,0,0x48) +DEFEVENT(KEY_49,"Keycode 0x49",AM_K,0,0,0x49) +DEFEVENT(KEY_4B,"Keycode 0x4B",AM_K,0,0,0x4B) + +DEFEVENT(KEY_6E,"Keycode 0x6E",AM_K,0,0,0x6e) +DEFEVENT(KEY_6F,"Keycode 0x6F",AM_K,0,0,0x6f) + DEFEVENT(KEY_70,"Keycode 0x70",AM_K,0,0,0x70) DEFEVENT(KEY_71,"Keycode 0x71",AM_K,0,0,0x71) DEFEVENT(KEY_76,"Keycode 0x76",AM_K,0,0,0x76) diff --git a/main.c b/main.c index 488f2a09..3d52c2d3 100755 --- a/main.c +++ b/main.c @@ -177,7 +177,7 @@ void fixup_prefs (struct uae_prefs *p) err = 1; } #endif - + if (p->produce_sound < 0 || p->produce_sound > 3) { write_log ("Bad value for -S parameter: enable value must be within 0..3\n"); p->produce_sound = 0; @@ -241,7 +241,7 @@ void fixup_prefs (struct uae_prefs *p) p->gfxmem_size = 0; err = 1; } -#ifndef BSDSOCKET +#if !defined(BSDSOCKET) if (p->socket_emu) { write_log ("Compile-time option of BSDSOCKET_SUPPORTED was not enabled. You can't use bsd-socket emulation.\n"); p->socket_emu = 0; @@ -327,7 +327,7 @@ void uae_reset (int hardreset) if (hardreset) quit_program = -3; } - + } void uae_quit (void) @@ -375,8 +375,8 @@ static void parse_diskswapper (char *s) p1 = tmp; for(;;) { - p2 = strtok (p1, delim); - if (!p2) + p2 = strtok (p1, delim); + if (!p2) break; p1 = NULL; if (num >= MAX_SPARE_DRIVES) @@ -406,7 +406,7 @@ static void parse_cmdline (int argc, char **argv) write_log ("Missing argument for '-f' option.\n"); } else { #ifdef FILESYS - free_mountinfo (currprefs.mountinfo); + free_mountinfo (currprefs.mountinfo); #endif target_cfgfile_load (&currprefs, argv[++i], -1, 1); } @@ -470,7 +470,7 @@ void reset_all_systems (void) init_eventtab (); memory_reset (); -#ifdef BSDSOCKET +#if defined(BSDSOCKET) bsdlib_reset (); #endif #ifdef FILESYS @@ -546,7 +546,7 @@ void leave_program (void) static void real_main2 (int argc, char **argv) { -#if defined (NATMEM_OFFSET) && defined( _WIN32 ) && !defined( NO_WIN32_EXCEPTION_HANDLER ) +#if defined (JIT) && (defined( _WIN32 ) || defined(_WIN64)) && !defined( NO_WIN32_EXCEPTION_HANDLER ) extern int EvalException ( LPEXCEPTION_POINTERS blah, int n_except ); __try #endif @@ -568,7 +568,7 @@ static void real_main2 (int argc, char **argv) exit (1); } -#ifdef JIT +#ifdef NATMEM_OFFSET init_shm(); #endif @@ -578,7 +578,7 @@ static void real_main2 (int argc, char **argv) #endif if (restart_config[0]) - parse_cmdline_and_init_file (argc, argv); + parse_cmdline_and_init_file (argc, argv); else currprefs = changed_prefs; @@ -588,7 +588,7 @@ static void real_main2 (int argc, char **argv) write_log ("Sound driver unavailable: Sound output disabled\n"); currprefs.produce_sound = 0; } - inputdevice_init (); + inputdevice_init(); changed_prefs = currprefs; no_gui = ! currprefs.start_gui; @@ -639,7 +639,9 @@ static void real_main2 (int argc, char **argv) #endif #ifdef AUTOCONFIG gfxlib_install (); +#if defined(BSDSOCKET) bsdlib_install (); +#endif emulib_install (); uaeexe_install (); native2amiga_install (); @@ -675,7 +677,7 @@ static void real_main2 (int argc, char **argv) } } -#if defined (NATMEM_OFFSET) && defined( _WIN32 ) && !defined( NO_WIN32_EXCEPTION_HANDLER ) +#if defined (JIT) && (defined( _WIN32 ) || defined(_WIN64)) && !defined( NO_WIN32_EXCEPTION_HANDLER ) __except( EvalException( GetExceptionInformation(), GetExceptionCode() ) ) { // EvalException does the good stuff... @@ -693,7 +695,7 @@ void real_main (int argc, char **argv) while (restart_program) { changed_prefs = currprefs; real_main2 (argc, argv); - leave_program (); + leave_program (); quit_program = 0; } zfile_exit (); diff --git a/memory.c b/memory.c index 0c12a794..a6fa821e 100755 --- a/memory.c +++ b/memory.c @@ -28,9 +28,8 @@ #include "arcadia.h" #include "enforcer.h" -#ifdef JIT int canbang; - +#ifdef JIT /* Set by each memory handler that does not simply access real memory. */ int special_mem; #endif @@ -44,7 +43,11 @@ uae_u32 allocated_gfxmem; uae_u32 allocated_z3fastmem; uae_u32 allocated_a3000mem; +#if defined(CPU_64_BIT) +uae_u32 max_z3fastmem = 2048UL * 1024 * 1024; +#else uae_u32 max_z3fastmem = 512 * 1024 * 1024; +#endif static long chip_filepos; static long bogo_filepos; @@ -186,15 +189,7 @@ uae_u8 *load_keyfile (struct uae_prefs *p, char *path, int *size) strcpy (tmp, path); strcat (tmp, "rom.key"); f = zfile_fopen (tmp, "rb"); - if (!f) { - strcpy (tmp, p->romfile); - d = strrchr(tmp, '/'); - if (!d) - d = strrchr(tmp, '\\'); - if (d) { - strcpy (d + 1, "rom.key"); - f = zfile_fopen(tmp, "rb"); - } + { if (!f) { struct romdata *rd = getromdatabyid (0); char *s = romlist_get (rd); @@ -213,6 +208,20 @@ uae_u8 *load_keyfile (struct uae_prefs *p, char *path, int *size) if (!f) { sprintf (tmp, "%s../shared/rom/rom.key", start_path_data); f = zfile_fopen(tmp, "rb"); + if (!f) { + if (!f) { + strcpy (tmp, p->romfile); + d = strrchr(tmp, '/'); + if (!d) + d = strrchr(tmp, '\\'); + if (d) { + strcpy (d + 1, "rom.key"); + f = zfile_fopen(tmp, "rb"); + } + } + + } + } } } @@ -526,7 +535,9 @@ static int mbres_val = 0; uae_u32 REGPARAM2 mbres_lget (uaecptr addr) { +#ifdef JIT special_mem |= S_READ; +#endif if (currprefs.illegal_mem) write_log ("Illegal lget at %08lx\n", addr); @@ -535,7 +546,9 @@ uae_u32 REGPARAM2 mbres_lget (uaecptr addr) uae_u32 REGPARAM2 mbres_wget (uaecptr addr) { +#ifdef JIT special_mem |= S_READ; +#endif if (currprefs.illegal_mem) write_log ("Illegal wget at %08lx\n", addr); @@ -544,7 +557,9 @@ uae_u32 REGPARAM2 mbres_wget (uaecptr addr) uae_u32 REGPARAM2 mbres_bget (uaecptr addr) { +#ifdef JIT special_mem |= S_READ; +#endif if (currprefs.illegal_mem) write_log ("Illegal bget at %08lx\n", addr); @@ -553,19 +568,25 @@ uae_u32 REGPARAM2 mbres_bget (uaecptr addr) void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l) { +#ifdef JIT special_mem |= S_WRITE; +#endif if (currprefs.illegal_mem) write_log ("Illegal lput at %08lx\n", addr); } void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w) { +#ifdef JIT special_mem |= S_WRITE; +#endif if (currprefs.illegal_mem) write_log ("Illegal wput at %08lx\n", addr); } void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b) { +#ifdef JIT special_mem |= S_WRITE; +#endif if (currprefs.illegal_mem) write_log ("Illegal bput at %08lx\n", addr); @@ -603,7 +624,9 @@ uae_u32 REGPARAM2 chipmem_lget_ce2 (uaecptr addr) { uae_u32 *m; +#ifdef JIT special_mem |= S_READ; +#endif addr -= chipmem_start & chipmem_mask; addr &= chipmem_mask; m = (uae_u32 *)(chipmemory + addr); @@ -615,7 +638,9 @@ uae_u32 REGPARAM2 chipmem_wget_ce2 (uaecptr addr) { uae_u16 *m; +#ifdef JIT special_mem |= S_READ; +#endif addr -= chipmem_start & chipmem_mask; addr &= chipmem_mask; m = (uae_u16 *)(chipmemory + addr); @@ -625,7 +650,9 @@ uae_u32 REGPARAM2 chipmem_wget_ce2 (uaecptr addr) uae_u32 REGPARAM2 chipmem_bget_ce2 (uaecptr addr) { +#ifdef JIT special_mem |= S_READ; +#endif addr -= chipmem_start & chipmem_mask; addr &= chipmem_mask; ce2_timeout (); @@ -636,7 +663,9 @@ void REGPARAM2 chipmem_lput_ce2 (uaecptr addr, uae_u32 l) { uae_u32 *m; +#ifdef JIT special_mem |= S_WRITE; +#endif addr -= chipmem_start & chipmem_mask; addr &= chipmem_mask; m = (uae_u32 *)(chipmemory + addr); @@ -648,7 +677,9 @@ void REGPARAM2 chipmem_wput_ce2 (uaecptr addr, uae_u32 w) { uae_u16 *m; +#ifdef JIT special_mem |= S_WRITE; +#endif addr -= chipmem_start & chipmem_mask; addr &= chipmem_mask; m = (uae_u16 *)(chipmemory + addr); @@ -658,7 +689,9 @@ void REGPARAM2 chipmem_wput_ce2 (uaecptr addr, uae_u32 w) void REGPARAM2 chipmem_bput_ce2 (uaecptr addr, uae_u32 b) { +#ifdef JIT special_mem |= S_WRITE; +#endif addr -= chipmem_start & chipmem_mask; addr &= chipmem_mask; ce2_timeout (); @@ -1236,7 +1269,9 @@ uae_u8 REGPARAM2 *default_xlate (uaecptr a) if (quit_program == 0) { /* do this only in 68010+ mode, there are some tricky A500 programs.. */ if (currprefs.cpu_level > 0 || !currprefs.cpu_compatible) { +#if defined(ENFORCER) enforcer_disable (); +#endif if (be_cnt < 3) { int i, j; uaecptr a2 = a - 32; diff --git a/newcpu.c b/newcpu.c index 700f8554..273044fa 100755 --- a/newcpu.c +++ b/newcpu.c @@ -1722,17 +1722,19 @@ static int do_specialties (int cycles) unset_special (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE); return 1; } -#ifdef JIT + if (currprefs.cpu_idle && currprefs.m68k_speed != 0 && ((regs.spcflags & SPCFLAG_STOP)) == SPCFLAG_STOP) { /* sleep 1ms if STOP-instruction is executed */ if (1) { static int sleepcnt, lvpos, zerocnt; if (vpos != lvpos) { sleepcnt--; +#ifdef JIT if (pissoff == 0 && compiled_code && --zerocnt < 0) { sleepcnt = -1; zerocnt = IDLETIME / 4; } +#endif lvpos = vpos; if (sleepcnt < 0) { sleepcnt = IDLETIME / 2; @@ -1741,8 +1743,8 @@ static int do_specialties (int cycles) } } } -#endif } + if (regs.spcflags & SPCFLAG_TRACE) do_trace (); @@ -2613,3 +2615,146 @@ void cpureset (void) } +/* + + The routines below take dividend and divisor as parameters. + They return 0 if division by zero, or exact number of cycles otherwise. + + The number of cycles returned assumes a register operand. + Effective address time must be added if memory operand. + + For 68000 only (not 68010, 68012, 68020, etc). + Probably valid for 68008 after adding the extra prefetch cycle. + + + Best and worst cases are for register operand: + (Note the difference with the documented range.) + + + DIVU: + + Overflow (always): 10 cycles. + Worst case: 136 cycles. + Best case: 76 cycles. + + + DIVS: + + Absolute overflow: 16-18 cycles. + Signed overflow is not detected prematurely. + + Worst case: 156 cycles. + Best case without signed overflow: 122 cycles. + Best case with signed overflow: 120 cycles + + + */ + + +// +// DIVU +// Unsigned division +// + +STATIC_INLINE int getDivu68kCycles_2(uae_u32 dividend, uae_u16 divisor) +{ + int mcycles; + uae_u32 hdivisor; + int i; + + if(divisor == 0) + return 0; + + // Overflow + if((dividend >> 16) >= divisor) + return (mcycles = 5) * 2; + + mcycles = 38; + hdivisor = divisor << 16; + + for( i = 0; i < 15; i++) + { + uae_u32 temp; + temp = dividend; + + dividend <<= 1; + + // If carry from shift + if((uae_s32)temp < 0) + { + dividend -= hdivisor; + } + else + { + mcycles += 2; + if(dividend >= hdivisor) + { + dividend -= hdivisor; + mcycles--; + } + } + } + return mcycles * 2; +} +int getDivu68kCycles(uae_u32 dividend, uae_u16 divisor) +{ + int v = getDivu68kCycles_2(dividend, divisor) - 4; +// write_log("U%d ", v); + return v; +} + +// +// DIVS +// Signed division +// + +STATIC_INLINE int getDivs68kCycles_2(uae_s32 dividend, uae_s16 divisor) +{ + int mcycles; + uae_u32 aquot; + int i; + + if(divisor == 0) + return 0; + + mcycles = 6; + + if( dividend < 0) + mcycles++; + + // Check for absolute overflow + if(((uae_u32)abs(dividend) >> 16) >= (uae_u16)abs(divisor)) + { + return (mcycles + 2) * 2; + } + + // Absolute quotient + aquot = (uae_u32) abs(dividend) / (uae_u16)abs(divisor); + + mcycles += 55; + + if(divisor >= 0) + { + if(dividend >= 0) + mcycles--; + else + mcycles++; + } + + // Count 15 msbits in absolute of quotient + + for( i = 0; i < 15; i++) + { + if((uae_s16)aquot >= 0) + mcycles++; + aquot <<= 1; + } + + return mcycles * 2; +} +int getDivs68kCycles(uae_s32 dividend, uae_s16 divisor) +{ + int v = getDivs68kCycles_2(dividend, divisor) - 4; +// write_log("S%d ", v); + return v; +} diff --git a/nogui.c b/nogui.c index 5e8830d5..52d1404e 100755 --- a/nogui.c +++ b/nogui.c @@ -76,7 +76,7 @@ void gui_unlock (void) } void gui_message (const char *format,...) -{ +{ char msg[2048]; va_list parms; diff --git a/od-generic/joystick.c b/od-generic/joystick.c index 5ec3561a..2c390c4c 100755 --- a/od-generic/joystick.c +++ b/od-generic/joystick.c @@ -1,8 +1,8 @@ - /* + /* * UAE - The Un*x Amiga Emulator - * + * * Joystick emulation stubs - * + * * Copyright 1997 Bernd Schmidt * Copyright 2003 Richard Drummond */ diff --git a/od-generic/sound.c b/od-generic/sound.c index 4c63521c..022bf021 100755 --- a/od-generic/sound.c +++ b/od-generic/sound.c @@ -1,8 +1,8 @@ - /* + /* * UAE - The Un*x Amiga Emulator - * + * * Support for the Mute sound system - * + * * Copyright 1997 Bernd Schmidt * Copyright 2003 Richard Drummond */ diff --git a/od-generic/sound.h b/od-generic/sound.h index 1817268e..68b211a0 100755 --- a/od-generic/sound.h +++ b/od-generic/sound.h @@ -1,8 +1,8 @@ - /* + /* * UAE - The Un*x Amiga Emulator - * + * * Support for the Mute sound system. - * + * * Copyright 1997 Bernd Schmidt */ diff --git a/od-win32/ahidsound.c b/od-win32/ahidsound.c index 4ef74f96..77b47572 100755 --- a/od-win32/ahidsound.c +++ b/od-win32/ahidsound.c @@ -8,12 +8,13 @@ * Copyright 2000-2002 Bernd Roesch */ - #define NATIVBUFFNUM 4 #define RECORDBUFFER 50 //survive 9 sec of blocking at 44100 #include "sysconfig.h" +#if defined(AHI) + #ifdef __GNUC__ #define INITGUID #endif @@ -45,9 +46,9 @@ #include "sounddep/sound.h" #include "od-win32/ahidsound.h" #include "vfw.h" +#include "dxwrap.h" #include "win32.h" #include "win32gfx.h" -#include "dxwrap.h" #include "inputdevice.h" #include "avioutput.h" #include "parser.h" @@ -77,9 +78,6 @@ static int amigablksize; static DWORD sound_flushes2 = 0; extern HWND hAmigaWnd; -#ifdef __GNUC__ -DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); -#endif static LPDIRECTSOUND lpDS2 = NULL; static LPDIRECTSOUNDBUFFER lpDSBprimary2 = NULL; @@ -98,9 +96,10 @@ struct winuae //this struct is put in a6 if you call unsigned int changenum; //number to detect screen close/open unsigned int z3offset; //the offset to add to acsess Z3 mem from Dll side }; +static struct winuae uaevar; +static struct winuae *a6; -struct winuae uaevar; -struct winuae *a6; +#if defined(X86_MSVC_ASSEMBLY) #define CREATE_NATIVE_FUNC_PTR2 uae_u32 (* native_func)( uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, \ uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32,uae_u32,uae_u32) @@ -157,6 +156,8 @@ static uae_u32 emulib_ExecuteNativeCode2 (void) return 0; } +#endif + void ahi_close_sound (void) { HRESULT hr = DS_OK; @@ -674,6 +675,8 @@ uae_u32 ahi_demux (void) flushprinter (); return 0; +#if defined(X86_MSVC_ASSEMBLY) + case 100: // open dll { char *dllname; @@ -697,7 +700,7 @@ uae_u32 ahi_demux (void) case 102: //execute native code return emulib_ExecuteNativeCode2 (); - + case 103: //close dll { HMODULE libaddr; @@ -705,6 +708,7 @@ uae_u32 ahi_demux (void) FreeLibrary(libaddr); return 0; } +#endif case 104: //screenlost { @@ -715,6 +719,7 @@ uae_u32 ahi_demux (void) return 1; } +#if defined(X86_MSVC_ASSEMBLY) case 105: //returns memory offset return (uae_u32) get_real_address(0); case 106: //byteswap 16bit vars @@ -838,6 +843,7 @@ uae_u32 ahi_demux (void) free(bswap_buffer); bswap_buffer = NULL; return 0; +#endif case 200: ahitweak = m68k_dreg (regs, 1); @@ -852,3 +858,5 @@ uae_u32 ahi_demux (void) return 0x12345678; // Code for not supportet function } } + +#endif diff --git a/od-win32/bsdsock.c b/od-win32/bsdsock.c index de483484..6e4663d9 100755 --- a/od-win32/bsdsock.c +++ b/od-win32/bsdsock.c @@ -12,6 +12,8 @@ #include "sysconfig.h" #include "sysdeps.h" +#if defined(BSDSOCKET) + #include #include #include @@ -34,20 +36,18 @@ #include "mmsystem.h" #include "win32.h" - - static HWND hSockWnd; -static long FAR PASCAL SocketWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ); +static LRESULT CALLBACK SocketWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); extern HWND hAmigaWnd; -int hWndSelector = 0; /* Set this to zero to get hSockWnd */ -CRITICAL_SECTION csSigQueueLock; +static int hWndSelector = 0; /* Set this to zero to get hSockWnd */ +static CRITICAL_SECTION csSigQueueLock; -DWORD threadid; +static DWORD threadid; #ifdef __GNUC__ #define THREAD(func,arg) CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)func,(LPVOID)arg,0,&threadid) #else -#define THREAD(func,arg) _beginthreadex( NULL, 0, func, (void *)arg, 0, (unsigned *)&threadid ) +#define THREAD(func,arg) (HANDLE)_beginthreadex(NULL, 0, func, arg, 0, &threadid) #endif #define SETERRNO seterrno(sb,WSAGetLastError()-WSABASEERR) @@ -65,24 +65,43 @@ DWORD threadid; static WSADATA wsbData; -int PASCAL WSAEventSelect(SOCKET,HANDLE,long); +static int PASCAL WSAEventSelect(SOCKET,HANDLE,long); #define MAX_SELECT_THREADS 64 static HANDLE hThreads[MAX_SELECT_THREADS]; -uae_u32 *threadargs[MAX_SELECT_THREADS]; +static struct threadargsw *threadargsw[MAX_SELECT_THREADS]; static HANDLE hEvents[MAX_SELECT_THREADS]; #define MAX_GET_THREADS 64 static HANDLE hGetThreads[MAX_GET_THREADS]; -uae_u32 *threadGetargs[MAX_GET_THREADS]; -static HANDLE hGetEvents[MAX_GET_THREADS]; +struct threadargs { + struct socketbase *sb; + uae_u32 args1; + uae_u32 args2; + int args3; + long args4; + char *args5; +}; + +struct threadargsw { + struct socketbase *sb; + uae_u32 nfds; + uae_u32 readfds; + uae_u32 writefds; + uae_u32 exceptfds; + uae_u32 timeout; +}; + +static struct threadargs *threadGetargs[MAX_GET_THREADS]; +static int threadGetargs_inuse[MAX_GET_THREADS]; +static HANDLE hGetEvents[MAX_GET_THREADS]; static HANDLE hSockThread; static HANDLE hSockReq, hSockReqHandled; static unsigned int __stdcall sock_thread(void *); -CRITICAL_SECTION SockThreadCS; +static CRITICAL_SECTION SockThreadCS; #define PREPARE_THREAD EnterCriticalSection( &SockThreadCS ) #define TRIGGER_THREAD { SetEvent( hSockReq ); WaitForSingleObject( hSockReqHandled, INFINITE ); LeaveCriticalSection( &SockThreadCS ); } @@ -120,38 +139,39 @@ static int mySockStartup( void ) if( lasterror == WSAVERNOTSUPPORTED ) { - char szMessage[ MAX_DPATH ]; - WIN32GUI_LoadUIString( IDS_WSOCK2NEEDED, szMessage, MAX_DPATH ); - gui_message( szMessage ); + char szMessage[ MAX_DPATH ]; + WIN32GUI_LoadUIString( IDS_WSOCK2NEEDED, szMessage, MAX_DPATH ); + gui_message( szMessage ); } else - write_log( "BSDSOCK: ERROR - Unable to initialize Windows socket layer! Error code: %d\n", lasterror ); + write_log( "BSDSOCK: ERROR - Unable to initialize Windows socket layer! Error code: %d\n", lasterror ); return 0; } if (LOBYTE (wsbData.wVersion) != SOCKVER_MAJOR || HIBYTE (wsbData.wVersion) != SOCKVER_MINOR ) { - char szMessage[ MAX_DPATH ]; - WIN32GUI_LoadUIString( IDS_WSOCK2NEEDED, szMessage, MAX_DPATH ); - gui_message( szMessage ); + char szMessage[ MAX_DPATH ]; + WIN32GUI_LoadUIString( IDS_WSOCK2NEEDED, szMessage, MAX_DPATH ); + gui_message( szMessage ); - return 0; + return 0; } else { write_log( "BSDSOCK: using %s\n", wsbData.szDescription ); - // make sure WSP/NSPStartup gets called from within the regular stack - // (Windows 95/98 need this) - if( ( dummy = socket( AF_INET,SOCK_STREAM,IPPROTO_TCP ) ) != INVALID_SOCKET ) - { - closesocket( dummy ); - result = 1; - } - else - { - write_log( "BSDSOCK: ERROR - WSPStartup/NSPStartup failed! Error code: %d\n",WSAGetLastError() ); - result = 0; - } + // make sure WSP/NSPStartup gets called from within the regular stack + // (Windows 95/98 need this) + if((dummy = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) != INVALID_SOCKET) + { + closesocket(dummy); + result = 1; + } + else + { + write_log( "BSDSOCK: ERROR - WSPStartup/NSPStartup failed! Error code: %d\n", + WSAGetLastError() ); + result = 0; + } } return result; @@ -166,44 +186,43 @@ int init_socket_layer(void) #ifndef CAN_DO_STACK_MAGIC currprefs.socket_emu = 0; #endif - if( currprefs.socket_emu ) + if(currprefs.socket_emu) { - if( ( result = mySockStartup() ) ) - { - InitializeCriticalSection(&csSigQueueLock); + if((result = mySockStartup())) + { + InitializeCriticalSection(&csSigQueueLock); - if( hSockThread == NULL ) - { - WNDCLASS wc; // Set up an invisible window and dummy wndproc - - InitializeCriticalSection( &SockThreadCS ); - hSockReq = CreateEvent( NULL, FALSE, FALSE, NULL ); - hSockReqHandled = CreateEvent( NULL, FALSE, FALSE, NULL ); - - wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW; - wc.lpfnWndProc = SocketWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = 0; - wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON)); - wc.hCursor = LoadCursor (NULL, IDC_ARROW); - wc.hbrBackground = GetStockObject (BLACK_BRUSH); - wc.lpszMenuName = 0; - wc.lpszClassName = "SocketFun"; - if( RegisterClass (&wc) ) + if(hSockThread == NULL) { - hSockWnd = CreateWindowEx ( 0, - "SocketFun", "WinUAE Socket Window", - WS_POPUP, - 0, 0, - 1, 1, - NULL, NULL, 0, NULL); - hSockThread = (void *)THREAD(sock_thread,NULL); + WNDCLASS wc; // Set up an invisible window and dummy wndproc + + InitializeCriticalSection( &SockThreadCS ); + hSockReq = CreateEvent( NULL, FALSE, FALSE, NULL ); + hSockReqHandled = CreateEvent( NULL, FALSE, FALSE, NULL ); + + wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW; + wc.lpfnWndProc = SocketWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = 0; + wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON)); + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hbrBackground = GetStockObject (BLACK_BRUSH); + wc.lpszMenuName = 0; + wc.lpszClassName = "SocketFun"; + if(RegisterClass(&wc)) + { + hSockWnd = CreateWindowEx ( 0, + "SocketFun", "WinUAE Socket Window", + WS_POPUP, + 0, 0, + 1, 1, + NULL, NULL, 0, NULL); + hSockThread = THREAD(sock_thread, NULL); + } } - } - } + } } - socket_layer_initialized = result; return result; @@ -212,29 +231,30 @@ int init_socket_layer(void) void deinit_socket_layer(void) { int i; - if( currprefs.socket_emu ) + if(currprefs.socket_emu) { - WSACleanup(); - if( socket_layer_initialized ) - { - DeleteCriticalSection( &csSigQueueLock ); - if( hSockThread ) - { - DeleteCriticalSection( &SockThreadCS ); - CloseHandle( hSockReq ); - hSockReq = NULL; - CloseHandle( hSockReqHandled ); - WaitForSingleObject( hSockThread, INFINITE ); - CloseHandle( hSockThread ); - } - for (i = 0; i < MAX_SELECT_THREADS; i++) - { - if (hThreads[i]) + WSACleanup(); + if(socket_layer_initialized) { - CloseHandle( hThreads[i] ); + DeleteCriticalSection(&csSigQueueLock); + if(hSockThread) + { + DeleteCriticalSection(&SockThreadCS); + CloseHandle(hSockReq); + hSockReq = NULL; + CloseHandle(hSockReqHandled); + WaitForSingleObject(hSockThread, INFINITE); + CloseHandle(hSockThread); + } + for (i = 0; i < MAX_SELECT_THREADS; i++) + { + if (hThreads[i]) + { + CloseHandle(hThreads[i]); + hThreads[i] = NULL; + } + } } - } - } } } @@ -265,32 +285,34 @@ void unlocksigqueue(void) // Blocking sockets with asynchronous event notification are currently not safe to use. -struct socketbase *asyncsb[MAXPENDINGASYNC]; -SOCKET asyncsock[MAXPENDINGASYNC]; -uae_u32 asyncsd[MAXPENDINGASYNC]; -int asyncindex; +static struct socketbase *asyncsb[MAXPENDINGASYNC]; +static SOCKET asyncsock[MAXPENDINGASYNC]; +static uae_u32 asyncsd[MAXPENDINGASYNC]; +static int asyncindex; int host_sbinit(SB) { sb->sockAbort = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - if (sb->sockAbort == INVALID_SOCKET) return 0; - if ((sb->hEvent = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL) return 0; + if (sb->sockAbort == INVALID_SOCKET) + return 0; + if ((sb->hEvent = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL) + return 0; sb->mtable = calloc(sb->dtablesize,sizeof(*sb->mtable)); return 1; } -void host_closesocketquick(int s) +void host_closesocketquick(SOCKET s) { BOOL true = 1; if( s ) { - setsockopt((SOCKET)s,SOL_SOCKET,SO_DONTLINGER,(char *)&true,sizeof(true)); + setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(char *)&true,sizeof(true)); shutdown(s,1); - closesocket((SOCKET)s); + closesocket(s); } } @@ -304,12 +326,12 @@ void host_sbcleanup(SB) for (i = sb->dtablesize; i--; ) { - if (sb->dtable[i] != (int)INVALID_SOCKET) host_closesocketquick(sb->dtable[i]); + if (sb->dtable[i] != INVALID_SOCKET) host_closesocketquick(sb->dtable[i]); if (sb->mtable[i]) asyncsb[(sb->mtable[i]-0xb000)/2] = NULL; } - shutdown(sb->sockAbort,1); + shutdown(sb->sockAbort,1); closesocket(sb->sockAbort); free(sb->mtable); @@ -320,10 +342,10 @@ void host_sbreset(void) memset(asyncsb,0,sizeof asyncsb); memset(asyncsock,0,sizeof asyncsock); memset(asyncsd,0,sizeof asyncsd); - memset(threadargs,0,sizeof threadargs); + memset(threadargsw,0,sizeof threadargsw); } -void sockmsg(unsigned int msg, unsigned long wParam, unsigned long lParam) +void sockmsg(unsigned int msg, WPARAM wParam, LPARAM lParam) { SB; unsigned int index; @@ -452,9 +474,9 @@ void sockabort(SB) } void setWSAAsyncSelect(SB, uae_u32 sd, SOCKET s, long lEvent ) - { +{ if (sb->mtable[sd-1]) - { + { long wsbevents = 0; long eventflags; int i; @@ -477,9 +499,8 @@ void setWSAAsyncSelect(SB, uae_u32 sd, SOCKET s, long lEvent ) WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : hSockWnd,sb->mtable[sd-1],wsbevents); unlocksigqueue(); - } } - +} // address cleaning static void prephostaddr(SOCKADDR_IN *addr) @@ -498,7 +519,7 @@ static void prepamigaaddr(struct sockaddr *realpt, int len) int host_dup2socket(SB, int fd1, int fd2) - { +{ SOCKET s1,s2; TRACE(("dup2socket(%d,%d) -> ",fd1,fd2)); @@ -506,36 +527,36 @@ int host_dup2socket(SB, int fd1, int fd2) s1 = getsock(sb, fd1); if (s1 != INVALID_SOCKET) - { + { if (fd2 != -1) - { + { if ((unsigned int) (fd2) >= (unsigned int) sb->dtablesize) - { + { TRACE (("Bad file descriptor (%d)\n", fd2)); seterrno (sb, 9); /* EBADF */ - } + } fd2++; s2 = getsock(sb,fd2); if (s2 != INVALID_SOCKET) - { + { shutdown(s2,1); closesocket(s2); - } + } setsd(sb,fd2,s1); TRACE(("0\n")); return 0; - } + } else - { + { fd2 = getsd(sb, 1); setsd(sb,fd2,s1); TRACE(("%d\n",fd2)); return (fd2 - 1); - } } - TRACE(("-1\n")); - return -1; } + TRACE(("-1\n")); + return -1; +} int host_socket(SB, int af, int type, int protocol) { @@ -547,9 +568,9 @@ int host_socket(SB, int af, int type, int protocol) if ((s = socket(af,type,protocol)) == INVALID_SOCKET) { - SETERRNO; - TRACE(("failed (%d)\n",sb->sb_errno)); - return -1; + SETERRNO; + TRACE(("failed (%d)\n",sb->sb_errno)); + return -1; } else sd = getsd(sb,(int)s); @@ -559,24 +580,24 @@ int host_socket(SB, int af, int type, int protocol) TRACE(("%d\n",sd)); if (type == SOCK_RAW) - { + { if (protocol==IPPROTO_UDP) - { + { sb->ftable[sd-1] |= SF_RAW_UDP; - } + } if (protocol==IPPROTO_ICMP) - { + { struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; bind(s,(struct sockaddr *)&sin,sizeof(sin)) ; - } + } if (protocol==IPPROTO_RAW) - { - sb->ftable[sd-1] |= SF_RAW_RAW; - } + { + sb->ftable[sd-1] |= SF_RAW_RAW; } + } return sd-1; } @@ -592,23 +613,23 @@ uae_u32 host_bind(SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) if (s != INVALID_SOCKET) { - if (namelen <= sizeof buf) - { - memcpy(buf,get_real_address(name),namelen); - - // some Amiga programs set this field to bogus values - prephostaddr((SOCKADDR_IN *)buf); + if (namelen <= sizeof buf) + { + memcpy(buf,get_real_address(name),namelen); + + // some Amiga programs set this field to bogus values + prephostaddr((SOCKADDR_IN *)buf); - if ((success = bind(s,(struct sockaddr *)buf,namelen)) != 0) - { - SETERRNO; - TRACE(("failed (%d)\n",sb->sb_errno)); - } - else - TRACE(("OK\n")); - } - else - write_log("BSDSOCK: ERROR - Excessive namelen (%d) in bind()!\n",namelen); + if ((success = bind(s,(struct sockaddr *)buf,namelen)) != 0) + { + SETERRNO; + TRACE(("failed (%d)\n",sb->sb_errno)); + } + else + TRACE(("OK\n")); + } + else + write_log("BSDSOCK: ERROR - Excessive namelen (%d) in bind()!\n",namelen); } return success; @@ -625,13 +646,13 @@ uae_u32 host_listen(SB, uae_u32 sd, uae_u32 backlog) if (s != INVALID_SOCKET) { - if ((success = listen(s,backlog)) != 0) - { - SETERRNO; - TRACE(("failed (%d)\n",sb->sb_errno)); - } - else - TRACE(("OK\n")); + if ((success = listen(s,backlog)) != 0) + { + SETERRNO; + TRACE(("failed (%d)\n",sb->sb_errno)); + } + else + TRACE(("OK\n")); } return success; @@ -648,115 +669,116 @@ void host_accept(SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) sd++; if (name != 0 ) - { + { rp_nameuae = rp_name = (struct sockaddr *)get_real_address(name); hlenuae = hlen = get_long(namelen); if (hlenuae < sizeof(sockaddr)) - { // Fix for CNET BBS Windows must have 16 Bytes (sizeof(sockaddr)) otherwise Error WSAEFAULT + { // Fix for CNET BBS Windows must have 16 Bytes (sizeof(sockaddr)) otherwise Error WSAEFAULT rp_name = &sockaddr; hlen = sizeof(sockaddr); - } } + } else - { + { rp_name = &sockaddr; hlen = sizeof(sockaddr); - } + } TRACE(("accept(%d,%d,%d) -> ",sd,name,hlenuae)); s = (SOCKET)getsock(sb,(int)sd); if (s != INVALID_SOCKET) { - BEGINBLOCKING; - - s2 = accept(s,rp_name,&hlen); - - if (s2 == INVALID_SOCKET) - { - SETERRNO; + BEGINBLOCKING; + + s2 = accept(s,rp_name,&hlen); - if (sb->ftable[sd-1] & SF_BLOCKING && sb->sb_errno == WSAEWOULDBLOCK-WSABASEERR) - { - if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) + if (s2 == INVALID_SOCKET) { - if (sb->mtable[sd-1] == 0) - { - WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : hSockWnd,wMsg,FD_ACCEPT); - } - else + SETERRNO; + + if (sb->ftable[sd-1] & SF_BLOCKING && sb->sb_errno == WSAEWOULDBLOCK-WSABASEERR) + { + if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) { - setWSAAsyncSelect(sb,sd,s,FD_ACCEPT); - } + if (sb->mtable[sd-1] == 0) + { + WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : hSockWnd,wMsg,FD_ACCEPT); + } + else + { + setWSAAsyncSelect(sb,sd,s,FD_ACCEPT); + } - WAITSIGNAL; + WAITSIGNAL; - if (sb->mtable[sd-1] == 0) - { - cancelasyncmsg(wMsg); - } - else - { - setWSAAsyncSelect(sb,sd,s,0); - } - - if (sb->eintr) - { - TRACE(("[interrupted]\n")); - ENDBLOCKING; - return; - } + if (sb->mtable[sd-1] == 0) + { + cancelasyncmsg(wMsg); + } + else + { + setWSAAsyncSelect(sb,sd,s,0); + } + + if (sb->eintr) + { + TRACE(("[interrupted]\n")); + ENDBLOCKING; + return; + } - s2 = accept(s,rp_name,&hlen); + s2 = accept(s,rp_name,&hlen); - if (s2 == INVALID_SOCKET) - { - SETERRNO; + if (s2 == INVALID_SOCKET) + { + SETERRNO; - if (sb->sb_errno == WSAEWOULDBLOCK-WSABASEERR) write_log("BSDSOCK: ERRRO - accept() would block despite FD_ACCEPT message\n"); - } + if (sb->sb_errno == WSAEWOULDBLOCK-WSABASEERR) + write_log("BSDSOCK: ERRRO - accept() would block despite FD_ACCEPT message\n"); + } + } + } } - } - } - - if (s2 == INVALID_SOCKET) - { - sb->resultval = -1; - TRACE(("failed (%d)\n",sb->sb_errno)); - } - else - { - sb->resultval = getsd(sb, s2); - sb->ftable[sb->resultval-1] = sb->ftable[sd-1]; // new socket inherits the old socket's properties - sb->resultval--; - if (rp_name != 0) + + if (s2 == INVALID_SOCKET) + { + sb->resultval = -1; + TRACE(("failed (%d)\n",sb->sb_errno)); + } + else + { + sb->resultval = getsd(sb, s2); + sb->ftable[sb->resultval-1] = sb->ftable[sd-1]; // new socket inherits the old socket's properties + sb->resultval--; + if (rp_name != 0) { // 1.11.2002 XXX - if (hlen <= hlenuae) + if (hlen <= hlenuae) { // Fix for CNET BBS Part 2 - prepamigaaddr(rp_name,hlen); - if (namelen != 0) + prepamigaaddr(rp_name,hlen); + if (namelen != 0) { - put_long(namelen,hlen); + put_long(namelen,hlen); } } - else + else { // Copy only the number of bytes requested - if (hlenuae != 0) + if (hlenuae != 0) { - prepamigaaddr(rp_name,hlenuae); - memcpy(rp_nameuae,rp_name,hlenuae); - put_long(namelen,hlenuae); + prepamigaaddr(rp_name,hlenuae); + memcpy(rp_nameuae,rp_name,hlenuae); + put_long(namelen,hlenuae); } } } - TRACE(("%d/%d\n",sb->resultval,hlen)); - } - - ENDBLOCKING; - } + TRACE(("%d/%d\n",sb->resultval,hlen)); + } + ENDBLOCKING; } +} + typedef enum { connect_req, @@ -814,62 +836,61 @@ BOOL HandleStuff( void ) { // 100ms sleepiness might need some tuning... //if(WaitForSingleObject( hSockReq, 100 ) == WAIT_OBJECT_0 ) - { - 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); - 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); - } - break; - case recvfrom_req: - if( sockreq.params.recvfrom_s.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 ); + { + 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); + 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); + } + break; + case recvfrom_req: + if( sockreq.params.recvfrom_s.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 - { - sockreq.sb->resultval = recv( sockreq.s, sockreq.params.recvfrom_s.realpt, sockreq.params.recvfrom_s.len, - sockreq.params.recvfrom_s.flags ); - } - break; - case abort_req: - *(sockreq.params.abort_s.newsock) = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - if (*(sockreq.params.abort_s.newsock) != sb->sockAbort) + } + else { - shutdown( sb->sockAbort, 1 ); - closesocket(sb->sockAbort); + sockreq.sb->resultval = recv( sockreq.s, sockreq.params.recvfrom_s.realpt, sockreq.params.recvfrom_s.len, + sockreq.params.recvfrom_s.flags ); } - handled = FALSE; /* Don't bother the SETERRNO section after the switch() */ - break; - case last_req: - default: - write_log( "BSDSOCK: Invalid sock-thread request!\n" ); - handled = FALSE; - break; - } - if( handled ) - { - if( sockreq.sb->resultval == SOCKET_ERROR ) - { - sb = sockreq.sb; - - SETERRNO; + break; + case abort_req: + *(sockreq.params.abort_s.newsock) = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + if (*(sockreq.params.abort_s.newsock) != sb->sockAbort) + { + shutdown( sb->sockAbort, 1 ); + closesocket(sb->sockAbort); + } + handled = FALSE; /* Don't bother the SETERRNO section after the switch() */ + break; + case last_req: + default: + write_log( "BSDSOCK: Invalid sock-thread request!\n" ); + handled = FALSE; + break; + } + if( handled ) + { + if( sockreq.sb->resultval == SOCKET_ERROR ) + { + sb = sockreq.sb; + SETERRNO; + } + } + SetEvent( hSockReqHandled ); } - } - SetEvent( hSockReqHandled ); - } } else { @@ -878,7 +899,7 @@ BOOL HandleStuff( void ) return quit; } -static long FAR PASCAL SocketWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) +static LRESULT CALLBACK SocketWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { if( message >= 0xB000 && message < 0xB000+MAXPENDINGASYNC*2 ) { @@ -904,33 +925,33 @@ static unsigned int __stdcall sock_thread(void *blah) // Make sure we're outrunning the wolves int pri = THREAD_PRIORITY_ABOVE_NORMAL; if (!os_winnt) { - pri = priorities[currprefs.win32_active_priority].value; - if (pri == THREAD_PRIORITY_HIGHEST) + pri = priorities[currprefs.win32_active_priority].value; + if (pri == THREAD_PRIORITY_HIGHEST) pri = THREAD_PRIORITY_TIME_CRITICAL; - else - pri++; + else + pri++; } SetThreadPriority( GetCurrentThread(), pri ); while( TRUE ) { - if( hSockReq ) + if( hSockReq ) { - DWORD wait; - WaitHandle = hSockReq; - wait = MsgWaitForMultipleObjects (1, &WaitHandle, FALSE,INFINITE, QS_POSTMESSAGE); - if (wait == WAIT_OBJECT_0) + DWORD wait; + WaitHandle = hSockReq; + wait = MsgWaitForMultipleObjects (1, &WaitHandle, FALSE,INFINITE, QS_POSTMESSAGE); + if (wait == WAIT_OBJECT_0) { - if( HandleStuff() ) // See if its time to quit... - break; + if( HandleStuff() ) // See if its time to quit... + break; } - if (wait == WAIT_OBJECT_0 +1) + if (wait == WAIT_OBJECT_0 +1) { - Sleep(10); - while( PeekMessage( &msg, NULL, WM_USER, 0xB000+MAXPENDINGASYNC*2, PM_REMOVE ) > 0 ) + Sleep(10); + while( PeekMessage( &msg, NULL, WM_USER, 0xB000+MAXPENDINGASYNC*2, PM_REMOVE ) > 0 ) { - TranslateMessage( &msg ); - DispatchMessage( &msg ); + TranslateMessage( &msg ); + DispatchMessage( &msg ); } } } @@ -959,79 +980,73 @@ void host_connect(SB, uae_u32 sd, uae_u32 name, uae_u32 namelen) if (s != INVALID_SOCKET) { - if (namelen <= MAXADDRLEN) - { - if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) - { - if (sb->mtable[sd-1] == 0) - { - WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : hSockWnd,wMsg,FD_CONNECT); - } - else + if (namelen <= MAXADDRLEN) + { + if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) { - setWSAAsyncSelect(sb,sd,s,FD_CONNECT); - } - - - BEGINBLOCKING; - PREPARE_THREAD; + if (sb->mtable[sd-1] == 0) + { + WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : hSockWnd,wMsg,FD_CONNECT); + } + else + { + setWSAAsyncSelect(sb,sd,s,FD_CONNECT); + } - memcpy(buf,get_real_address(name),namelen); - prephostaddr((SOCKADDR_IN *)buf); - - sockreq.packet_type = connect_req; - sockreq.s = s; - sockreq.sb = sb; - sockreq.params.connect_s.buf = buf; - sockreq.params.connect_s.namelen = namelen; + BEGINBLOCKING; + PREPARE_THREAD; - TRIGGER_THREAD; + memcpy(buf,get_real_address(name),namelen); + prephostaddr((SOCKADDR_IN *)buf); + + sockreq.packet_type = connect_req; + sockreq.s = s; + sockreq.sb = sb; + sockreq.params.connect_s.buf = buf; + sockreq.params.connect_s.namelen = namelen; + TRIGGER_THREAD; - if (sb->resultval) - { - if (sb->sb_errno == WSAEWOULDBLOCK-WSABASEERR) - { - if (sb->ftable[sd-1] & SF_BLOCKING) - { - seterrno(sb,0); - - - WAITSIGNAL; + if (sb->resultval) + { + if (sb->sb_errno == WSAEWOULDBLOCK-WSABASEERR) + { + if (sb->ftable[sd-1] & SF_BLOCKING) + { + seterrno(sb,0); + + WAITSIGNAL; - if (sb->eintr) - { - // Destroy socket to cancel abort, replace it with fake socket to enable proper closing. - // This is in accordance with BSD behaviour. - shutdown(s,1); - closesocket(s); - sb->dtable[sd-1] = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - } - } - else + if (sb->eintr) + { + // Destroy socket to cancel abort, replace it with fake socket to enable proper closing. + // This is in accordance with BSD behaviour. + shutdown(s,1); + closesocket(s); + sb->dtable[sd-1] = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + } + } + else + { + seterrno(sb,36); // EINPROGRESS + } + } + else { - seterrno(sb,36); // EINPROGRESS - + CANCELSIGNAL; // Cancel pending signal } - } - else - { - CANCELSIGNAL; // Cancel pending signal - - } - } + } - ENDBLOCKING; - if (sb->mtable[sd-1] == 0) + ENDBLOCKING; + if (sb->mtable[sd-1] == 0) { - cancelasyncmsg(wMsg); + cancelasyncmsg(wMsg); } - else + else { - setWSAAsyncSelect(sb,sd,s,0); + setWSAAsyncSelect(sb,sd,s,0); } } - } else write_log("BSDSOCK: WARNING - Excessive namelen (%d) in connect()!\n",namelen); @@ -1060,81 +1075,81 @@ void host_sendto(SB, uae_u32 sd, uae_u32 msg, uae_u32 len, uae_u32 flags, uae_u3 { realpt = get_real_address(msg); - if (to) - { - if (tolen > sizeof buf) write_log("BSDSOCK: WARNING - Target address in sendto() too large (%d)!\n",tolen); - else - { - memcpy(buf,get_real_address(to),tolen); - // some Amiga software sets this field to bogus values - prephostaddr((SOCKADDR_IN *)buf); - } - } - if (sb->ftable[sd-1]&SF_RAW_RAW) + if (to) + { + if (tolen > sizeof buf) write_log("BSDSOCK: WARNING - Target address in sendto() too large (%d)!\n",tolen); + else + { + memcpy(buf,get_real_address(to),tolen); + // some Amiga software sets this field to bogus values + prephostaddr((SOCKADDR_IN *)buf); + } + } + if (sb->ftable[sd-1]&SF_RAW_RAW) { - if (*(realpt+9) == 0x1) + if (*(realpt+9) == 0x1) { // ICMP - struct sockaddr_in sin; - shutdown(s,1); - closesocket(s); - s = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); + struct sockaddr_in sin; + shutdown(s,1); + closesocket(s); + s = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = (unsigned short) (*(realpt+21)&0xff)*256 + (unsigned short) (*(realpt+20)&0xff); - bind(s,(struct sockaddr *)&sin,sizeof(sin)) ; + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = (unsigned short) (*(realpt+21)&0xff)*256 + (unsigned short) (*(realpt+20)&0xff); + bind(s,(struct sockaddr *)&sin,sizeof(sin)) ; - sb->dtable[sd-1] = s; - sb->ftable[sd-1]&= ~SF_RAW_RAW; - sb->ftable[sd-1]|= SF_RAW_RICMP; + sb->dtable[sd-1] = s; + sb->ftable[sd-1]&= ~SF_RAW_RAW; + sb->ftable[sd-1]|= SF_RAW_RICMP; } - if (*(realpt+9) == 0x11) + if (*(realpt+9) == 0x11) { // UDP - struct sockaddr_in sin; - shutdown(s,1); - closesocket(s); - s = socket(AF_INET,SOCK_RAW,IPPROTO_UDP); + struct sockaddr_in sin; + shutdown(s,1); + closesocket(s); + s = socket(AF_INET,SOCK_RAW,IPPROTO_UDP); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = (unsigned short) (*(realpt+21)&0xff)*256 + (unsigned short) (*(realpt+20)&0xff); - bind(s,(struct sockaddr *)&sin,sizeof(sin)) ; + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = (unsigned short) (*(realpt+21)&0xff)*256 + (unsigned short) (*(realpt+20)&0xff); + bind(s,(struct sockaddr *)&sin,sizeof(sin)) ; - sb->dtable[sd-1] = s; - sb->ftable[sd-1]&= ~SF_RAW_RAW; - sb->ftable[sd-1]|= SF_RAW_RUDP; + sb->dtable[sd-1] = s; + sb->ftable[sd-1]&= ~SF_RAW_RAW; + sb->ftable[sd-1]|= SF_RAW_RUDP; } } - - BEGINBLOCKING; - - for (;;) - { - PREPARE_THREAD; + + BEGINBLOCKING; - sockreq.packet_type = sendto_req; - sockreq.s = s; - sockreq.sb = sb; - sockreq.params.sendto_s.realpt = realpt; - sockreq.params.sendto_s.buf = buf; - sockreq.params.sendto_s.sd = sd; - sockreq.params.sendto_s.msg = msg; - sockreq.params.sendto_s.len = len; - sockreq.params.sendto_s.flags = flags; - sockreq.params.sendto_s.to = to; - sockreq.params.sendto_s.tolen = tolen; + for (;;) + { + PREPARE_THREAD; + + sockreq.packet_type = sendto_req; + sockreq.s = s; + sockreq.sb = sb; + sockreq.params.sendto_s.realpt = realpt; + sockreq.params.sendto_s.buf = buf; + sockreq.params.sendto_s.sd = sd; + sockreq.params.sendto_s.msg = msg; + sockreq.params.sendto_s.len = len; + sockreq.params.sendto_s.flags = flags; + sockreq.params.sendto_s.to = to; + sockreq.params.sendto_s.tolen = tolen; if (sb->ftable[sd-1]&SF_RAW_UDP) - { + { *(buf+2) = *(realpt+2); *(buf+3) = *(realpt+3); // Copy DST-Port iCut = 8; sockreq.params.sendto_s.realpt += iCut; sockreq.params.sendto_s.len -= iCut; - } + } if (sb->ftable[sd-1]&SF_RAW_RUDP) - { + { int iTTL; iTTL = (int) *(realpt+8)&0xff; setsockopt(s,IPPROTO_IP,4,(char*) &iTTL,sizeof(iTTL)); @@ -1144,69 +1159,70 @@ void host_sendto(SB, uae_u32 sd, uae_u32 msg, uae_u32 len, uae_u32 flags, uae_u3 iCut = 28; sockreq.params.sendto_s.realpt += iCut; sockreq.params.sendto_s.len -= iCut; - } + } if (sb->ftable[sd-1]&SF_RAW_RICMP) - { + { int iTTL; iTTL = (int) *(realpt+8)&0xff; setsockopt(s,IPPROTO_IP,4,(char*) &iTTL,sizeof(iTTL)); iCut = 20; sockreq.params.sendto_s.realpt += iCut; sockreq.params.sendto_s.len -= iCut; - } - - - - TRIGGER_THREAD; - if (sb->ftable[sd-1]&SF_RAW_UDP||sb->ftable[sd-1]&SF_RAW_RUDP||sb->ftable[sd-1]&SF_RAW_RICMP) - { - sb->resultval += iCut; } - if (sb->resultval == -1) - { - if (sb->sb_errno != WSAEWOULDBLOCK-WSABASEERR || !(sb->ftable[sd-1] & SF_BLOCKING)) break; - } - else - { - realpt += sb->resultval; - len -= sb->resultval; - - if (len <= 0) break; - else continue; - } - if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) - { - if (sb->mtable[sd-1] == 0) + TRIGGER_THREAD; + if (sb->ftable[sd-1]&SF_RAW_UDP||sb->ftable[sd-1]&SF_RAW_RUDP||sb->ftable[sd-1]&SF_RAW_RICMP) { - WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : hSockWnd,wMsg,FD_WRITE); + sb->resultval += iCut; } - else + if (sb->resultval == -1) { - setWSAAsyncSelect(sb,sd,s,FD_WRITE); + if (sb->sb_errno != WSAEWOULDBLOCK-WSABASEERR || !(sb->ftable[sd-1] & SF_BLOCKING)) + break; } - - WAITSIGNAL; - - if (sb->mtable[sd-1] == 0) + else { - cancelasyncmsg(wMsg); + realpt += sb->resultval; + len -= sb->resultval; + + if (len <= 0) + break; + else + continue; } - else + + if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(sb,sd,s)) != 0) { - setWSAAsyncSelect(sb,sd,s,0); + if (sb->mtable[sd-1] == 0) + { + WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : hSockWnd,wMsg,FD_WRITE); + } + else + { + setWSAAsyncSelect(sb,sd,s,FD_WRITE); + } + + WAITSIGNAL; + + if (sb->mtable[sd-1] == 0) + { + cancelasyncmsg(wMsg); + } + else + { + setWSAAsyncSelect(sb,sd,s,0); + } + + if (sb->eintr) + { + TRACE(("[interrupted]\n")); + return; + } } - - if (sb->eintr) - { - TRACE(("[interrupted]\n")); - return; + else break; } - } - else break; - } - ENDBLOCKING; + ENDBLOCKING; } else sb->resultval = -1; @@ -1755,16 +1771,16 @@ static void fd_zero(uae_u32 fdset, uae_u32 nfds) } // This seems to be the only way of implementing a cancelable WinSock2 select() call... sigh. -static unsigned int __stdcall thread_WaitSelect(void *index2) +static unsigned int __stdcall thread_WaitSelect(void *indexp) { - uae_u32 index = (uae_u32)index2; + uae_u32 index = *((uae_u32*)indexp); unsigned int result = 0; long nfds; uae_u32 readfds, writefds, exceptfds; uae_u32 timeout; struct fd_set readsocks, writesocks, exceptsocks; struct timeval tv; - uae_u32 *args; + struct threadargsw *args; SB; @@ -1772,14 +1788,14 @@ static unsigned int __stdcall thread_WaitSelect(void *index2) { WaitForSingleObject(hEvents[index],INFINITE); - if ((args = threadargs[index]) != NULL) + if ((args = threadargsw[index]) != NULL) { - sb = (struct socketbase *)*args; - nfds = args[1]; - readfds = args[2]; - writefds = args[3]; - exceptfds = args[4]; - timeout = args[5]; + sb = args->sb; + nfds = args->nfds; + readfds = args->readfds; + writefds = args->writefds; + exceptfds = args->exceptfds; + timeout = args->timeout; // construct descriptor tables makesocktable(sb,readfds,&readsocks,nfds,sb->sockAbort); @@ -1844,7 +1860,7 @@ static unsigned int __stdcall thread_WaitSelect(void *index2) SETSIGNAL; - threadargs[index] = NULL; + threadargsw[index] = NULL; SetEvent(sb->hEvent); } } @@ -1858,6 +1874,7 @@ void host_WaitSelect(SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u3 { uae_u32 sigs, wssigs; int i; + struct threadargsw taw; wssigs = sigmp ? get_long(sigmp) : 0; @@ -1889,7 +1906,7 @@ void host_WaitSelect(SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u3 } } if (nfds == 0) - { // No sockets to check, only wait for signals + { // No sockets to check, only wait for signals m68k_dreg(regs,0) = wssigs; sigs = CallLib(get_long(4),-0x13e); // Wait() @@ -1900,33 +1917,39 @@ void host_WaitSelect(SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u3 if (exceptfds) fd_zero(exceptfds,nfds); sb->resultval = 0; return; - } + } ResetEvent(sb->hEvent); sb->needAbort = 1; - for (i = 0; i < MAX_SELECT_THREADS; i++) if (hThreads[i] && !threadargs[i]) break; + for (i = 0; i < MAX_SELECT_THREADS; i++) { + if (hThreads[i] && !threadargsw[i]) + break; + } if (i >= MAX_SELECT_THREADS) { for (i = 0; i < MAX_SELECT_THREADS; i++) { - if (!hThreads[i]) - { - if ((hEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL || (hThreads[i] = (void *)THREAD(thread_WaitSelect,i)) == NULL) - { - hThreads[i] = 0; - write_log("BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n",GetLastError()); - seterrno(sb,12); // ENOMEM - sb->resultval = -1; - return; - } - - // this should improve responsiveness - SetThreadPriority(hThreads[i],THREAD_PRIORITY_TIME_CRITICAL); - break; - } + if (!hThreads[i]) + { + hEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL); + hThreads[i] = THREAD(thread_WaitSelect,&i); + if (hEvents[i] == NULL || hThreads[i] == NULL) + { + hThreads[i] = 0; + write_log("BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n", + GetLastError()); + seterrno(sb,12); // ENOMEM + sb->resultval = -1; + return; + } + + // this should improve responsiveness + SetThreadPriority(hThreads[i],THREAD_PRIORITY_TIME_CRITICAL); + break; + } } } @@ -1935,7 +1958,14 @@ void host_WaitSelect(SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u3 { SOCKET newsock = INVALID_SOCKET; - threadargs[i] = (uae_u32 *)&sb; + taw.sb = sb; + taw.nfds = nfds; + taw.readfds = readfds; + taw.writefds = writefds; + taw.exceptfds = exceptfds; + taw.timeout = timeout; + + threadargsw[i] = &taw; SetEvent(hEvents[i]); @@ -1951,12 +1981,12 @@ void host_WaitSelect(SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u3 { if ((newsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET) write_log("BSDSOCK: ERROR - Cannot create socket: %d\n",WSAGetLastError()); - shutdown(sb->sockAbort,1); + shutdown(sb->sockAbort,1); if (newsock != sb->sockAbort) - { + { shutdown(sb->sockAbort,1); closesocket(sb->sockAbort); - } + } } WaitForSingleObject(sb->hEvent,INFINITE); @@ -1984,15 +2014,14 @@ void host_WaitSelect(SB, uae_u32 nfds, uae_u32 readfds, uae_u32 writefds, uae_u3 seterrno(sb,0); sb->resultval = 0; } - if (sb->resultval >= 0) + if (sb->resultval >= 0) { - TRACE(("%d\n",sb->resultval)); + TRACE(("%d\n",sb->resultval)); } - else + else { - TRACE(("%d errno %d\n",sb->resultval,sb->sb_errno)); + TRACE(("%d errno %d\n",sb->resultval,sb->sb_errno)); } - } else TRACE(("%d\n",sb->resultval)); } @@ -2038,160 +2067,157 @@ uae_u32 host_inet_addr(uae_u32 cp) int isfullscreen (void); BOOL CheckOnline(SB) - { +{ DWORD dwFlags; BOOL bReturn = TRUE; if (InternetGetConnectedState(&dwFlags,0) == FALSE) - { // Internet is offline + { // Internet is offline if (InternetAttemptConnect(0) != ERROR_SUCCESS) - { // Show Dialer window + { // Show Dialer window sb->sb_errno = 10001; sb->sb_herrno = 1; bReturn = FALSE; // No success or aborted - } + } if (isfullscreen()) - { + { ShowWindow (hAmigaWnd, SW_RESTORE); SetActiveWindow(hAmigaWnd); - } } - return(bReturn); } + return(bReturn); +} -static unsigned int __stdcall thread_get(void *index2) +static unsigned int __stdcall thread_get(void *indexp) { - uae_u32 index = (uae_u32)index2; + uae_u32 index = *((uae_u32*)indexp); unsigned int result = 0; - uae_u32 *args; - uae_u32 name; - uae_u32 namelen; - long addrtype; - char *name_rp; - char *buf; - - - SB; + struct threadargs *args; + uae_u32 name; + uae_u32 namelen; + long addrtype; + char *name_rp; + char *buf; + SB; for (;;) { WaitForSingleObject(hGetEvents[index],INFINITE); - if (threadGetargs[index] == -1) - { + if (threadGetargs_inuse[index] == -1) + { + threadGetargs_inuse[index] = 0; threadGetargs[index] = NULL; - } + } if ((args = threadGetargs[index]) != NULL ) { - sb = (struct socketbase *)*args; - if (args[1] == 0) - { // gethostbyname or gethostbyaddr + sb = args->sb; + if (args->args1 == 0) + { // gethostbyname or gethostbyaddr struct hostent *host; - name = args[2]; - namelen = args[3]; - addrtype = args[4]; - buf = (char*) args[5]; + name = args->args2; + namelen = args->args3; + addrtype = args->args4; + buf = args->args5; name_rp = get_real_address(name); if (strchr(name_rp,'.') == 0 || CheckOnline(sb) == TRUE) - { // Local Address or Internet Online ? + { // Local Address or Internet Online ? if (addrtype == -1) - { + { host = gethostbyname(name_rp); - } + } else - { + { host = gethostbyaddr(name_rp,namelen,addrtype); - } - if (threadGetargs[index] != -1) - { // No CTRL-C Signal + } + if (threadGetargs_inuse[index] != -1) + { // No CTRL-C Signal if (host == 0) - { + { // Error occured SETERRNO; TRACE(("failed (%d) - ",sb->sb_errno)); - } + } else - { + { seterrno(sb,0); memcpy(buf,host,sizeof(HOSTENT)); - } } } } - if (args[1] == 1) - { // getprotobyname + } + if (args->args1 == 1) + { // getprotobyname struct protoent *proto; - name = args[2]; - buf = (char*) args[5]; + name = args->args2; + buf = args->args5; name_rp = get_real_address(name); proto = getprotobyname (name_rp); - if (threadGetargs[index] != -1) - { // No CTRL-C Signal + if (threadGetargs_inuse[index] != -1) + { // No CTRL-C Signal if (proto == 0) - { + { // Error occured SETERRNO; TRACE(("failed (%d) - ",sb->sb_errno)); - } + } else - { + { seterrno(sb,0); memcpy(buf,proto,sizeof(struct protoent)); - } } } - if (args[1] == 2) - { // getservbyport and getservbyname + } + if (args->args1 == 2) + { // getservbyport and getservbyname uae_u32 nameport; uae_u32 proto; uae_u32 type; char *proto_rp = 0; struct servent *serv; - nameport = args[2]; - proto = args[3]; - type = args[4]; - buf = (char*) args[5]; + nameport = args->args2; + proto = args->args3; + type = args->args4; + buf = args->args5; if (proto) proto_rp = get_real_address(proto); if (type) - { + { serv = getservbyport(nameport,proto_rp); - } + } else - { + { name_rp = get_real_address(nameport); serv = getservbyname(name_rp,proto_rp); - } - if (threadGetargs[index] != -1) - { // No CTRL-C Signal + } + if (threadGetargs_inuse[index] != -1) + { // No CTRL-C Signal if (serv == 0) - { + { // Error occured SETERRNO; TRACE(("failed (%d) - ",sb->sb_errno)); - } + } else - { + { seterrno(sb,0); memcpy(buf,serv,sizeof(struct servent)); - } } } - - - + } TRACE(("-> ")); - if (threadGetargs[index] != -1) + if (threadGetargs_inuse[index] != -1) SETSIGNAL; - threadGetargs[index] = NULL; + threadGetargs_inuse[index] = 0; + threadGetargs[index] = NULL; - } + } } #ifndef __GNUC__ _endthreadex( result ); @@ -2208,7 +2234,7 @@ void host_gethostbynameaddr(SB, uae_u32 name, uae_u32 namelen, long addrtype) char *name_rp; int i; - uae_u32 args[6]; + struct threadargs args; uae_u32 addr; uae_u32 *addr_list[2]; @@ -2216,9 +2242,6 @@ void host_gethostbynameaddr(SB, uae_u32 name, uae_u32 namelen, long addrtype) char buf[MAXGETHOSTSTRUCT]; unsigned int wMsg = 0; - - - // char on = 1; // InternetSetOption(0,INTERNET_OPTION_SETTINGS_CHANGED,&on,strlen(&on)); // Do not use: Causes locks with some machines @@ -2250,38 +2273,42 @@ void host_gethostbynameaddr(SB, uae_u32 name, uae_u32 namelen, long addrtype) TRACE(("gethostbyaddr(0x%lx,0x%lx,%ld) -> ",name,namelen,addrtype)); } - args[0] = (uae_u32) sb; - args[1] = 0; - args[2] = name; - args[3] = namelen; - args[4] = addrtype; - args[5] = (uae_u32) &buf[0]; + args.sb = sb; + args.args1 = 0; + args.args2 = name; + args.args3 = namelen; + args.args4 = addrtype; + args.args5 = buf; for (i = 0; i < MAX_GET_THREADS; i++) + { + if (threadGetargs_inuse[i] == -1) { - if (threadGetargs[i] == -1) - { - threadGetargs[i] = 0; - } - if (hGetThreads[i] && !threadGetargs[i]) break; + threadGetargs_inuse[i] = 0; + threadGetargs[i] = NULL; } + if (hGetThreads[i] && !threadGetargs_inuse[i]) break; + } if (i >= MAX_GET_THREADS) { for (i = 0; i < MAX_GET_THREADS; i++) { - if (!hGetThreads[i]) - { - if ((hGetEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL || (hGetThreads[i] = (void *)THREAD(thread_get,i)) == NULL) - { - hGetThreads[i] = 0; - write_log("BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n",GetLastError()); - seterrno(sb,12); // ENOMEM - sb->resultval = -1; - return; - } - break; - } + if (hGetThreads[i] == NULL) + { + hGetEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL); + hGetThreads[i] = THREAD(thread_get, &i); + if (hGetEvents[i] == NULL || hGetThreads[i] == NULL) + { + hGetThreads[i] = NULL; + write_log("BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n", + GetLastError()); + seterrno(sb,12); // ENOMEM + sb->resultval = -1; + return; + } + break; + } } } @@ -2289,17 +2316,18 @@ void host_gethostbynameaddr(SB, uae_u32 name, uae_u32 namelen, long addrtype) else { bsdsetpriority (hGetThreads[i]); - threadGetargs[i] = (uae_u32 *)&args[0]; + threadGetargs[i] = &args; + threadGetargs_inuse[i] = 1; SetEvent(hGetEvents[i]); } sb->eintr = 0; - while ( threadGetargs[i] != 0 && sb->eintr == 0) - { + while ( threadGetargs_inuse[i] != 0 && sb->eintr == 0) + { WAITSIGNAL; if (sb->eintr == 1) - threadGetargs[i] = -1; - } + threadGetargs_inuse[i] = -1; + } CANCELSIGNAL; @@ -2310,10 +2338,12 @@ kludge: // compute total size of hostent size = 28; - if (h->h_name != NULL) size += strlen(h->h_name)+1; + if (h->h_name != NULL) + size += strlen(h->h_name)+1; if (h->h_aliases != NULL) - while (h->h_aliases[numaliases]) size += strlen(h->h_aliases[numaliases++])+5; + while (h->h_aliases[numaliases]) + size += strlen(h->h_aliases[numaliases++])+5; if (h->h_addr_list != NULL) { @@ -2330,7 +2360,9 @@ kludge: if (!sb->hostent) { - write_log("BSDSOCK: WARNING - gethostby%s() ran out of Amiga memory (couldn't allocate %ld bytes) while returning result of lookup for '%s'\n",addrtype == -1 ? "name" : "addr",size,(char *)name); + write_log("BSDSOCK: WARNING - gethostby%s() ran out of Amiga memory " + "(couldn't allocate %ld bytes) while returning result of lookup for '%s'\n", + addrtype == -1 ? "name" : "addr", size, name_rp); seterrno(sb,12); // ENOMEM return; } @@ -2370,7 +2402,7 @@ void host_getprotobyname(SB, uae_u32 name) char *name_rp; int i; - uae_u32 args[6]; + struct threadargs args; char buf[MAXGETHOSTSTRUCT]; @@ -2379,35 +2411,38 @@ void host_getprotobyname(SB, uae_u32 name) TRACE(("getprotobyname(%s) -> ",name_rp)); - args[0] = (uae_u32) sb; - args[1] = 1; - args[2] = name; - args[5] = (uae_u32) &buf[0]; + args.sb = sb; + args.args1 = 1; + args.args2 = name; + args.args5 = buf; for (i = 0; i < MAX_GET_THREADS; i++) + { + if (threadGetargs_inuse[i] == -1) { - if (threadGetargs[i] == -1) - { - threadGetargs[i] = 0; - } - if (hGetThreads[i] && !threadGetargs[i]) break; + threadGetargs_inuse[i] = 0; + threadGetargs[i] = NULL; } + if (hGetThreads[i] && !threadGetargs_inuse[i]) break; + } if (i >= MAX_GET_THREADS) { for (i = 0; i < MAX_GET_THREADS; i++) { - if (!hGetThreads[i]) - { - if ((hGetEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL || (hGetThreads[i] = (void *)THREAD(thread_get,i)) == NULL) - { - hGetThreads[i] = 0; - write_log("BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n",GetLastError()); - seterrno(sb,12); // ENOMEM - sb->resultval = -1; - return; - } - break; - } + if (!hGetThreads[i]) + { + hEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL); + hGetThreads[i] = THREAD(thread_get,&i); + if (hGetEvents[i] == NULL || hGetThreads[i] == NULL) + { + hGetThreads[i] = 0; + write_log("BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n",GetLastError()); + seterrno(sb,12); // ENOMEM + sb->resultval = -1; + return; + } + break; + } } } @@ -2416,17 +2451,18 @@ void host_getprotobyname(SB, uae_u32 name) { bsdsetpriority (hGetThreads[i]); - threadGetargs[i] = (uae_u32 *)&args[0]; + threadGetargs[i] = &args; + threadGetargs_inuse[i] = 1; SetEvent(hGetEvents[i]); } sb->eintr = 0; - while ( threadGetargs[i] != 0 && sb->eintr == 0) + while ( threadGetargs_inuse[i] != 0 && sb->eintr == 0) { WAITSIGNAL; if (sb->eintr == 1) - threadGetargs[i] = -1; + threadGetargs_inuse[i] = -1; } CANCELSIGNAL; @@ -2452,7 +2488,9 @@ void host_getprotobyname(SB, uae_u32 name) if (!sb->protoent) { - write_log("BSDSOCK: WARNING - getprotobyname() ran out of Amiga memory (couldn't allocate %ld bytes) while returning result of lookup for '%s'\n",size,(char *)name); + write_log("BSDSOCK: WARNING - getprotobyname() ran out of Amiga memory " + "(couldn't allocate %ld bytes) while returning result of lookup for '%s'\n", + size, name_rp); seterrno(sb,12); // ENOMEM return; } @@ -2489,7 +2527,7 @@ void host_getservbynameport(SB, uae_u32 nameport, uae_u32 proto, uae_u32 type) int i; char buf[MAXGETHOSTSTRUCT]; - uae_u32 args[6]; + struct threadargs args; if (proto) proto_rp = get_real_address(proto); @@ -2503,38 +2541,41 @@ void host_getservbynameport(SB, uae_u32 nameport, uae_u32 proto, uae_u32 type) TRACE(("getservbyname(%s,%s) -> ",name_rp,proto_rp ? proto_rp : "NULL")); } - args[0] = (uae_u32) sb; - args[1] = 2; - args[2] = nameport; - args[3] = proto; - args[4] = type; - args[5] = (uae_u32) &buf[0]; + args.sb = sb; + args.args1 = 2; + args.args2 = nameport; + args.args3 = proto; + args.args4 = type; + args.args5 = buf; for (i = 0; i < MAX_GET_THREADS; i++) + { + if (threadGetargs_inuse[i] == -1) { - if (threadGetargs[i] == -1) - { - threadGetargs[i] = 0; - } - if (hGetThreads[i] && !threadGetargs[i]) break; + threadGetargs_inuse[i] = 0; + threadGetargs[i] = NULL; } + if (hGetThreads[i] && !threadGetargs_inuse[i]) break; + } if (i >= MAX_GET_THREADS) { for (i = 0; i < MAX_GET_THREADS; i++) { - if (!hGetThreads[i]) - { - if ((hGetEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL || (hGetThreads[i] = (void *)THREAD(thread_get,i)) == NULL) - { - hGetThreads[i] = 0; - write_log("BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n",GetLastError()); - seterrno(sb,12); // ENOMEM - sb->resultval = -1; - return; - } - - break; - } + if (!hGetThreads[i]) + { + hGetEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL); + hGetThreads[i] = THREAD(thread_get,&i); + if (hGetEvents[i] == NULL || hGetThreads[i] == NULL) + { + hGetThreads[i] = 0; + write_log("BSDSOCK: ERROR - Thread/Event creation failed - error code: %d\n",GetLastError()); + seterrno(sb,12); // ENOMEM + sb->resultval = -1; + return; + } + + break; + } } } @@ -2543,18 +2584,19 @@ void host_getservbynameport(SB, uae_u32 nameport, uae_u32 proto, uae_u32 type) { bsdsetpriority (hGetThreads[i]); - threadGetargs[i] = (uae_u32 *)&args[0]; + threadGetargs[i] = &args; + threadGetargs_inuse[i] = 1; SetEvent(hGetEvents[i]); } sb->eintr = 0; - while ( threadGetargs[i] != 0 && sb->eintr == 0) - { + while ( threadGetargs_inuse[i] != 0 && sb->eintr == 0) + { WAITSIGNAL; if (sb->eintr == 1) - threadGetargs[i] = -1; - } + threadGetargs_inuse[i] = -1; + } CANCELSIGNAL; @@ -2592,7 +2634,8 @@ void host_getservbynameport(SB, uae_u32 nameport, uae_u32 proto, uae_u32 type) put_long(sb->servent+4,sb->servent+16); put_long(sb->servent+8,(unsigned short)htons(s->s_port)); - for (i = 0; i < numaliases; i++) put_long(sb->servent+16+i*4,addstr(&aptr,s->s_aliases[i])); + for (i = 0; i < numaliases; i++) + put_long(sb->servent+16+i*4,addstr(&aptr,s->s_aliases[i])); put_long(sb->servent+16+numaliases*4,0); put_long(sb->servent,aptr); addstr(&aptr,s->s_name); @@ -2617,3 +2660,5 @@ uae_u32 host_gethostname(uae_u32 name, uae_u32 namelen) } #endif + +#endif diff --git a/od-win32/dinput.c b/od-win32/dinput.c index 95ab02a9..ad93d63a 100755 --- a/od-win32/dinput.c +++ b/od-win32/dinput.c @@ -45,6 +45,11 @@ #define DID_JOYSTICK 2 #define DID_KEYBOARD 3 +#define DIDC_DX 1 +#define DIDC_RAW 2 +#define DIDC_WIN 3 +#define DIDC_CAT 4 + struct didata { int type; int disabled; @@ -55,9 +60,11 @@ struct didata { char *name; char *sortname; + int connection; LPDIRECTINPUTDEVICE8 lpdi; HANDLE rawinput; int wininput; + int catweasel; int axles; int buttons; @@ -150,6 +157,79 @@ static int register_rawinput (void) return 1; } +static void cleardid(struct didata *did) +{ + int i; + memset (did, 0, sizeof (*did)); + for (i = 0; i < MAX_MAPPINGS; i++) { + did->axismappings[i] = -1; + did->buttonmappings[i] = -1; + } +} + +static int initialize_catweasel(void) +{ + int j, i; + char tmp[MAX_DPATH]; + struct didata *did; + + if (catweasel_ismouse()) { + for (i = 0; i < 2 && num_mouse < MAX_INPUT_DEVICES; i++) { + did = di_mouse; + did += num_mouse; + cleardid(did); + did->connection = DIDC_CAT; + did->catweasel = i; + did->name = my_strdup ("Catweasel mouse"); + did->sortname = my_strdup (tmp); + did->buttons = 3; + did->axles = 2; + did->axistype[0] = 1; + did->axissort[0] = 0; + did->axisname[0] = my_strdup ("X-Axis"); + did->axistype[1] = 1; + did->axissort[1] = 1; + did->axisname[1] = my_strdup ("Y-Axis"); + for (j = 0; j < did->buttons; j++) { + did->buttonsort[j] = j; + sprintf (tmp, "Button %d", j + 1); + did->buttonname[j] = my_strdup (tmp); + } + did->priority = -1; + num_mouse++; + } + } + if (catweasel_isjoystick()) { + for (i = 0; i < 2 && num_joystick < MAX_INPUT_DEVICES; i++) { + did = di_joystick; + did += num_joystick; + cleardid(did); + did->connection = DIDC_CAT; + did->catweasel = i; + sprintf (tmp, "Catweasel joystick"); + did->name = my_strdup (tmp); + did->sortname = my_strdup (tmp); + did->buttons = (catweasel_isjoystick() & 0x80) ? 3 : 1; + did->axles = 2; + did->axistype[0] = 1; + did->axissort[0] = 0; + did->axisname[0] = my_strdup ("X-Axis"); + did->axistype[1] = 1; + did->axissort[1] = 1; + did->axisname[1] = my_strdup ("Y-Axis"); + for (j = 0; j < did->buttons; j++) { + did->buttonsort[j] = j; + sprintf (tmp, "Button %d", j + 1); + did->buttonname[j] = my_strdup (tmp); + } + did->priority = -1; + num_joystick++; + } + } + return 1; +} + + #define RDP_MOUSE "\\??\\Root#RDP_MOU#" static int initialize_rawinput (void) @@ -241,14 +321,11 @@ static int initialize_rawinput (void) } rnum_raw++; - memset (did, 0, sizeof (*did)); - for (j = 0; j < MAX_MAPPINGS; j++) { - did->axismappings[j] = -1; - did->buttonmappings[j] = -1; - } + cleardid(did); sprintf (tmp, "%s", type == RIM_TYPEMOUSE ? "RAW Mouse" : "RAW Keyboard"); did->name = my_strdup (tmp); did->rawinput = h; + did->connection = DIDC_RAW; write_log ("%p %s: ", h, type == RIM_TYPEMOUSE ? "mouse" : "keyboard"); did->sortname = my_strdup (buf); @@ -313,6 +390,7 @@ static void initialize_windowsmouse (void) return; num_mouse++; name = (i == 0) ? "Windows mouse" : "Mousehack mouse"; + did->connection = DIDC_WIN; did->name = my_strdup (i ? "Mousehack mouse" : "Windows mouse"); did->sortname = my_strdup (i ? "Windowsmouse2" : "Windowsmouse1"); did->buttons = GetSystemMetrics (SM_CMOUSEBUTTONS); @@ -686,6 +764,7 @@ static BOOL CALLBACK di_enumcallback (LPCDIDEVICEINSTANCE lpddi, LPVOID *dd) did->buttonmappings[i] = -1; } len = strlen (lpddi->tszInstanceName) + 3 + 1; + did->connection = DIDC_DX; did->name = malloc (len); strcpy (did->name, lpddi->tszInstanceName); did->guid = lpddi->guidInstance; @@ -719,8 +798,9 @@ static int di_do_init (void) } IDirectInput8_EnumDevices (g_lpdi, DI8DEVCLASS_ALL, di_enumcallback, 0, DIEDFL_ATTACHEDONLY); - initialize_rawinput (); - initialize_windowsmouse (); + initialize_rawinput(); + initialize_windowsmouse(); + initialize_catweasel(); sortdd (di_joystick, num_joystick, DID_JOYSTICK); sortdd (di_mouse, num_mouse, DID_MOUSE); @@ -818,7 +898,7 @@ static int init_mouse (void) mouse_inited = 1; for (i = 0; i < num_mouse; i++) { did = &di_mouse[i]; - if (!did->disabled && !did->rawinput && !did->wininput) { + if (!did->disabled && did->connection == DIDC_DX) { hr = IDirectInput8_CreateDevice (g_lpdi, &did->guid, &lpdi, NULL); if (hr == DI_OK) { hr = IDirectInputDevice8_SetDataFormat(lpdi, &c_dfDIMouse); @@ -858,7 +938,7 @@ static int acquire_mouse (int num, int flags) HRESULT hr; unacquire (lpdi, "mouse"); - if (lpdi) { + if (did->connection == DIDC_DX && lpdi) { setcoop (lpdi, flags ? (DISCL_FOREGROUND | DISCL_EXCLUSIVE) : (DISCL_BACKGROUND | DISCL_NONEXCLUSIVE), "mouse"); dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); @@ -916,7 +996,21 @@ static void read_mouse (void) for (i = 0; i < MAX_INPUT_DEVICES; i++) { struct didata *did = &di_mouse[i]; LPDIRECTINPUTDEVICE8 lpdi = did->lpdi; - if (!lpdi) + if (!did->acquired) + continue; + if (did->connection == DIDC_CAT) { + int cx, cy, cbuttons; + catweasel_read_mouse(did->catweasel, &cx, &cy, &cbuttons); + if (cx) + setmousestate(i, 0, cx, 0); + if (cy) + setmousestate(i, 1, cy, 0); + setmousebuttonstate(i, 0, cbuttons & 8); + setmousebuttonstate(i, 1, cbuttons & 4); + setmousebuttonstate(i, 2, cbuttons & 2); + continue; + } + if (!lpdi || did->connection != DIDC_DX) continue; elements = DI_BUFFER; hr = IDirectInputDevice8_GetDeviceData (lpdi, sizeof (DIDEVICEOBJECTDATA), didod, &elements, 0); @@ -1130,7 +1224,7 @@ static int init_kb (void) keyboard_inited = 1; for (i = 0; i < num_keyboard; i++) { struct didata *did = &di_keyboard[i]; - if (!did->disabled && !did->rawinput && !did->wininput) { + if (!did->disabled && did->connection == DIDC_DX) { hr = IDirectInput8_CreateDevice (g_lpdi, &did->guid, &lpdi, NULL); if (hr == DI_OK) { hr = IDirectInputDevice8_SetDataFormat(lpdi, &c_dfDIKeyboard); @@ -1326,6 +1420,8 @@ static void read_kb (void) update_leds (); for (i = 0; i < MAX_INPUT_DEVICES; i++) { struct didata *did = &di_keyboard[i]; + if (!did->acquired) + continue; lpdi = did->lpdi; if (!lpdi) continue; @@ -1545,13 +1641,27 @@ static void read_joystick (void) for (i = 0; i < MAX_INPUT_DEVICES; i++) { struct didata *did = &di_joystick[i]; - lpdi = did->lpdi; - if (!lpdi) - continue; if (currprefs.input_selected_setting == 0) { if (jsem_isjoy (0, &currprefs) != i && jsem_isjoy (1, &currprefs) != i) continue; } + if (!did->acquired) + continue; + if (did->connection == DIDC_CAT) { + uae_u8 cdir, cbuttons; + catweasel_read_joystick(&cdir, &cbuttons); + cdir >>= did->catweasel * 4; + cbuttons >>= did->catweasel * 4; + setjoystickstate(i, 0, !(cdir & 1) ? 1 : !(cdir & 2) ? -1 : 0, 0); + setjoystickstate(i, 1, !(cdir & 4) ? 1 : !(cdir & 8) ? -1 : 0, 0); + setjoybuttonstate(i, 0, cbuttons & 8); + setjoybuttonstate(i, 1, cbuttons & 4); + setjoybuttonstate(i, 2, cbuttons & 2); + continue; + } + lpdi = did->lpdi; + if (!lpdi || did->connection != DIDC_DX) + continue; elements = DI_BUFFER; hr = IDirectInputDevice8_GetDeviceData (lpdi, sizeof (DIDEVICEOBJECTDATA), didod, &elements, 0); if (hr == DI_OK) { @@ -1598,7 +1708,7 @@ static void read_joystick (void) } IDirectInputDevice8_Poll (lpdi); } -#ifdef CATWEASEL +#if 0 { static uae_u8 odir, obut; uae_u8 dir, dir2, but; @@ -1638,7 +1748,7 @@ static int init_joystick (void) joystick_inited = 1; for (i = 0; i < num_joystick; i++) { did = &di_joystick[i]; - if (!did->disabled) { + if (!did->disabled && did->connection == DIDC_DX) { hr = IDirectInput8_CreateDevice (g_lpdi, &did->guid, &lpdi, NULL); if (hr == DI_OK) { hr = IDirectInputDevice8_SetDataFormat(lpdi, &c_dfDIJoystick); @@ -1648,8 +1758,9 @@ static int init_joystick (void) sortobjects (did, did->axismappings, did->axissort, did->axisname, did->axistype, did->axles); sortobjects (did, did->buttonmappings, did->buttonsort, did->buttonname, 0, did->buttons); } - } else + } else { write_log ("joystick createdevice failed, %s\n", DXError (hr)); + } } } return 1; @@ -1677,17 +1788,21 @@ static int acquire_joystick (int num, int flags) HRESULT hr; unacquire (lpdi, "joystick"); - setcoop (lpdi, flags ? (DISCL_FOREGROUND | DISCL_EXCLUSIVE) : (DISCL_BACKGROUND | DISCL_NONEXCLUSIVE), "joystick"); - memset (&dipdw, 0, sizeof (dipdw)); - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = DI_BUFFER; - hr = IDirectInputDevice8_SetProperty (lpdi, DIPROP_BUFFERSIZE, &dipdw.diph); - if (hr != DI_OK) + if (di_joystick[num].connection == DIDC_DX && lpdi) { + setcoop (lpdi, flags ? (DISCL_FOREGROUND | DISCL_EXCLUSIVE) : (DISCL_BACKGROUND | DISCL_NONEXCLUSIVE), "joystick"); + memset (&dipdw, 0, sizeof (dipdw)); + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DI_BUFFER; + hr = IDirectInputDevice8_SetProperty (lpdi, DIPROP_BUFFERSIZE, &dipdw.diph); + if (hr != DI_OK) write_log ("joystick setproperty failed, %s\n", DXError (hr)); - di_joystick[num].acquired = acquire (lpdi, "joystick") ? 1 : -1; + di_joystick[num].acquired = acquire (lpdi, "joystick") ? 1 : -1; + } else { + di_joystick[num].acquired = 1; + } return di_joystick[num].acquired > 0 ? 1 : 0; } diff --git a/od-win32/dxwrap.c b/od-win32/dxwrap.c index 10128f9b..844c6481 100755 --- a/od-win32/dxwrap.c +++ b/od-win32/dxwrap.c @@ -47,18 +47,20 @@ static int flipinterval_supported; #define dxwrite_log -static int restoresurface (LPDIRECTDRAWSURFACE7 surface) +static HRESULT restoresurface (LPDIRECTDRAWSURFACE7 surface) { - HRESULT hr = IDirectDrawSurface7_Restore (surface); + HRESULT hr2, hr; + DDSURFACEDESC2 surfacedesc; + + hr = IDirectDrawSurface7_Restore (surface); if (SUCCEEDED(hr)) { - HRESULT hr2; DDBLTFX bltfx; memset (&bltfx, 0, sizeof (bltfx)); bltfx.dwSize = sizeof (bltfx); hr2 = IDirectDrawSurface7_Blt (surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx); if (FAILED(hr2)) { static int crap = 0; - if (hr2 == 0x887601C2) { + if (hr2 == DDERR_SURFACELOST) { if (crap) return hr; crap = 1; @@ -67,6 +69,12 @@ static int restoresurface (LPDIRECTDRAWSURFACE7 surface) } write_log("Surface clear failed: %s\n", DXError (hr2)); } + surfacedesc.dwSize = sizeof surfacedesc; + hr2 = IDirectDrawSurface7_Lock(surface, NULL, &surfacedesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (SUCCEEDED(hr2)) { + write_log("Surface Pointer: %p\n", surfacedesc.lpSurface); + IDirectDrawSurface7_Unlock(surface, NULL); + } } return hr; } @@ -286,7 +294,7 @@ static int LockStub( surface_type_e type ) if(SUCCEEDED(ddrval)) result = 1; - if( result ) + if(result) lockcnt++; return result; @@ -367,7 +375,7 @@ char *DirectDraw_GetSurfacePointer( void ) char *pixels = NULL; /* Make sure that somebody has done a lock before returning the lpSurface member */ - if( lockcnt ) + if(lockcnt) { pixels = DirectDrawState.lockable.lpdesc->lpSurface; } @@ -1639,7 +1647,7 @@ DWORD DirectDraw_CurrentRefreshRate( void ) * 1999.08.02 Brian King Creation * */ -static int DirectDraw_BltFastStub4( LPDIRECTDRAWSURFACE7 dstsurf, DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 srcsurf, LPRECT srcrect ) +static int DirectDraw_BltFastStub4(LPDIRECTDRAWSURFACE7 dstsurf, DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 srcsurf, LPRECT srcrect ) { int result = 0; HRESULT ddrval; @@ -1650,9 +1658,7 @@ static int DirectDraw_BltFastStub4( LPDIRECTDRAWSURFACE7 dstsurf, DWORD x, DWORD { ddrval = restoresurface ( dstsurf ); if (FAILED(ddrval)) - { break; - } } else if (ddrval != DDERR_SURFACEBUSY) { @@ -1661,9 +1667,7 @@ static int DirectDraw_BltFastStub4( LPDIRECTDRAWSURFACE7 dstsurf, DWORD x, DWORD } } if(SUCCEEDED(ddrval)) - { result = 1; - } return result; } @@ -1682,10 +1686,8 @@ static int DirectDraw_BltFastStub4( LPDIRECTDRAWSURFACE7 dstsurf, DWORD x, DWORD * 1999.08.02 Brian King Creation * */ -int DirectDraw_BltFast( surface_type_e dsttype, DWORD left, DWORD top, surface_type_e srctype, LPRECT srcrect ) +HRESULT DirectDraw_BltFast( surface_type_e dsttype, DWORD left, DWORD top, surface_type_e srctype, LPRECT srcrect ) { - int result; - LPDIRECTDRAWSURFACE7 lpDDS4_dst, lpDDS4_src; if( dsttype == primary_surface ) { @@ -1711,8 +1713,7 @@ int DirectDraw_BltFast( surface_type_e dsttype, DWORD left, DWORD top, surface_t { lpDDS4_src = DirectDrawState.secondary.surface; } - result = DirectDraw_BltFastStub4( lpDDS4_dst, left, top, lpDDS4_src, srcrect ); - return result; + return DirectDraw_BltFastStub4( lpDDS4_dst, left, top, lpDDS4_src, srcrect ); } /* @@ -1730,12 +1731,12 @@ int DirectDraw_BltFast( surface_type_e dsttype, DWORD left, DWORD top, surface_t * 1999.08.02 Brian King Creation * */ -static int DirectDraw_BltStub( LPDIRECTDRAWSURFACE7 dstsurf, LPRECT dstrect, LPDIRECTDRAWSURFACE7 srcsurf, LPRECT srcrect, DWORD flags, LPDDBLTFX ddbltfx ) +static HRESULT DirectDraw_BltStub(LPDIRECTDRAWSURFACE7 dstsurf, LPRECT dstrect, LPDIRECTDRAWSURFACE7 srcsurf, LPRECT srcrect, DWORD flags, LPDDBLTFX ddbltfx) { int result = 0, errcnt = 0; HRESULT ddrval; - while(FAILED(ddrval = IDirectDrawSurface7_Blt( dstsurf, dstrect, srcsurf, srcrect, flags, ddbltfx))) + while(FAILED(ddrval = IDirectDrawSurface7_Blt(dstsurf, dstrect, srcsurf, srcrect, flags, ddbltfx))) { if (ddrval == DDERR_SURFACELOST) { @@ -1753,20 +1754,8 @@ static int DirectDraw_BltStub( LPDIRECTDRAWSURFACE7 dstsurf, LPRECT dstrect, LPD write_log("BltStub(): DirectDrawSURFACE7_Blt() failed with %s\n", DXError (ddrval)); break; } -#if 0 - else - { - write_log( "Blt() failed - %s\n", DXError (ddrval)); - result = 0; - break; - } -#endif } - if(SUCCEEDED(ddrval)) - { - result = 1; - } - return result; + return ddrval; } /* @@ -1866,12 +1855,10 @@ int DirectDraw_Flip(int wait) * 1999.08.02 Brian King Creation * */ -int DirectDraw_Blt( surface_type_e dsttype, LPRECT dstrect, +HRESULT DirectDraw_Blt(surface_type_e dsttype, LPRECT dstrect, surface_type_e srctype, LPRECT srcrect, - DWORD flags, LPDDBLTFX fx ) + DWORD flags, LPDDBLTFX fx) { - int result; - LPDIRECTDRAWSURFACE7 lpDDS4_dst, lpDDS4_src; if( dsttype == primary_surface ) @@ -1922,8 +1909,7 @@ int DirectDraw_Blt( surface_type_e dsttype, LPRECT dstrect, { lpDDS4_src = NULL; /* For using BltStub to do rect-fills */ } - result = DirectDraw_BltStub( lpDDS4_dst, dstrect, lpDDS4_src, srcrect, flags, fx ); - return result; + return DirectDraw_BltStub(lpDDS4_dst, dstrect, lpDDS4_src, srcrect, flags, fx); } /* diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index 65c3095c..a74bea22 100755 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -222,8 +222,8 @@ HRESULT DirectDraw_GetDC( HDC *hdc, surface_type_e surface ); HRESULT DirectDraw_ReleaseDC( HDC hdc, surface_type_e surface ); int DirectDraw_Flip( int ); HRESULT DirectDraw_UpdateOverlay(RECT sr, RECT dr); -int DirectDraw_Blt( surface_type_e dsttype, LPRECT dstrect, surface_type_e srctype, LPRECT srcrect, DWORD flags, LPDDBLTFX fx ); -int DirectDraw_BltFast( surface_type_e dsttype, DWORD left, DWORD top, surface_type_e srctype, LPRECT srcrect ); +HRESULT DirectDraw_Blt( surface_type_e dsttype, LPRECT dstrect, surface_type_e srctype, LPRECT srcrect, DWORD flags, LPDDBLTFX fx ); +HRESULT DirectDraw_BltFast( surface_type_e dsttype, DWORD left, DWORD top, surface_type_e srctype, LPRECT srcrect ); DWORD DirectDraw_GetPixelFormatBitMask( DirectDraw_Mask_e mask ); RGBFTYPE DirectDraw_GetPixelFormat( void ); DWORD DirectDraw_GetPixelFormatFlags( void ); diff --git a/od-win32/hardfile_win32.c b/od-win32/hardfile_win32.c index 1597085b..637d83d3 100755 --- a/od-win32/hardfile_win32.c +++ b/od-win32/hardfile_win32.c @@ -217,6 +217,7 @@ int hdf_open (struct hardfiledata *hfd, char *name) } hfd->handle = h; if (hfd->handle != INVALID_HANDLE_VALUE) { + hfd->handle_valid = 1; hfd_log ("HDF '%s' opened succesfully, handle=%p\n", name, hfd->handle); return 1; } @@ -226,11 +227,14 @@ int hdf_open (struct hardfiledata *hfd, char *name) void hdf_close (struct hardfiledata *hfd) { + if (!hfd->handle_valid) + return; hfd_log ("close handle=%p\n", hfd->handle); hfd->flags = 0; if (hfd->handle && hfd->handle != INVALID_HANDLE_VALUE) CloseHandle (hfd->handle); hfd->handle = 0; + hfd->handle_valid = 0; if (hfd->cache) VirtualFree (hfd->cache, 0, MEM_RELEASE); hfd->cache = 0; @@ -247,6 +251,7 @@ int hdf_dup (struct hardfiledata *hfd, void *src) hfd->handle = duphandle; hfd->cache = VirtualAlloc (NULL, CACHE_SIZE, MEM_COMMIT, PAGE_READWRITE); hfd->cache_valid = 0; + hfd->handle_valid = 1; if (!hfd->cache) { hdf_close (hfd); return 0; @@ -449,7 +454,7 @@ Return Value: status = SetupDiEnumDeviceInterfaces ( IntDevInfo, // Interface Device Info handle 0, // Device Info data - (LPGUID)&DiskClassGuid, // Interface registered by driver + &GUID_DEVINTERFACE_DISK, // Interface registered by driver Index, // Member &interfaceData // Device Interface Data ); @@ -757,7 +762,7 @@ int hdf_init (void) if (buffer) { memset (uae_drives, 0, sizeof (uae_drives)); num_drives = 0; - hIntDevInfo = SetupDiGetClassDevs ((LPGUID)&DiskClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); + hIntDevInfo = SetupDiGetClassDevs (&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); if (hIntDevInfo != INVALID_HANDLE_VALUE) { while (index < MAX_FILESYSTEM_UNITS) { memset (uae_drives + index2, 0, sizeof (struct uae_driveinfo)); @@ -799,4 +804,3 @@ char *hdf_getnameharddrive (int index, int flags) } - diff --git a/od-win32/hq2x32 b/od-win32/hq2x32 deleted file mode 100755 index e69de29b..00000000 diff --git a/od-win32/keyboard_win32.c b/od-win32/keyboard_win32.c index 7e1eb6e7..e91997a5 100755 --- a/od-win32/keyboard_win32.c +++ b/od-win32/keyboard_win32.c @@ -156,12 +156,26 @@ static struct uae_input_device_kbr_default keytrans[] = { { DIK_SLASH, INPUTEVENT_KEY_DIV }, { DIK_OEM_102, INPUTEVENT_KEY_30 }, - { DIK_BACK, INPUTEVENT_SPC_STATEREWIND }, - { DIK_VOLUMEDOWN, INPUTEVENT_SPC_VOLUME_DOWN }, { DIK_VOLUMEUP, INPUTEVENT_SPC_VOLUME_UP }, { DIK_MUTE, INPUTEVENT_SPC_VOLUME_MUTE }, + { DIK_HOME, INPUTEVENT_KEY_70 }, + { DIK_END, INPUTEVENT_KEY_71 }, + { DIK_SYSRQ, INPUTEVENT_KEY_6E }, + { DIK_F12, INPUTEVENT_KEY_6F }, + { DIK_INSERT, INPUTEVENT_KEY_47 }, + { DIK_NEXT, INPUTEVENT_KEY_48 }, + { DIK_PRIOR, INPUTEVENT_KEY_49 }, + { DIK_F11, INPUTEVENT_KEY_4B }, + + { DIK_STOP, INPUTEVENT_KEY_CDTV_STOP }, + { DIK_PLAYPAUSE, INPUTEVENT_KEY_CDTV_PLAYPAUSE }, + { DIK_PREVTRACK, INPUTEVENT_KEY_CDTV_REW }, + { DIK_NEXTTRACK, INPUTEVENT_KEY_CDTV_FF }, + { DIK_WEBBACK, INPUTEVENT_KEY_76 }, + { DIK_WEBFORWARD, INPUTEVENT_KEY_77 }, + { -1, 0 } }; @@ -291,6 +305,83 @@ static int np[] = { DIK_NUMPAD0, 0, DIK_NUMPADPERIOD, 0, DIK_NUMPAD1, 1, DIK_NUM DIK_NUMPAD3, 3, DIK_NUMPAD4, 4, DIK_NUMPAD5, 5, DIK_NUMPAD6, 6, DIK_NUMPAD7, 7, DIK_NUMPAD8, 8, DIK_NUMPAD9, 9, -1 }; +#define IECODE_UP_PREFIX 0x80 +#define RAW_STEALTH 0x68 +#define STEALTHF_E0KEY 0x08 +#define STEALTHF_UPSTROKE 0x04 +#define STEALTHF_SPECIAL 0x02 +#define STEALTHF_E1KEY 0x01 + +#define RAW_HOME 0x70 +#define RAW_END 0x71 +#define RAW_BREAK 0x6e +#define RAW_F12 0x6f +#define RAW_INSERT 0x47 +#define RAW_PAGEUP 0x48 +#define RAW_PAGEDOWN 0x49 +#define RAW_F11 0x4b +#define RAW_STOP 0x72 +#define RAW_PLAY 0x73 +#define RAW_PREVIOUS 0x74 +#define RAW_NEXT 0x75 +#define RAW_REWIND 0x76 +#define RAW_FORWARD 0x77 + +static void sendmmcodes(int code, int newstate) +{ + uae_u8 b; + + switch (code) + { + case DIK_END: + code=RAW_END; + break; + case DIK_HOME: + code=RAW_HOME; + break; + case DIK_F11: + code=RAW_F11; + break; + case DIK_INSERT: + code=RAW_INSERT; + break; + case DIK_PRIOR: + code=RAW_PAGEUP; + break; + case DIK_PAUSE: + code=RAW_BREAK; + break; + case DIK_MEDIASTOP: + code=RAW_STOP; + break; + case DIK_PLAYPAUSE: + code=RAW_PLAY; + break; + case DIK_NEXTTRACK: + code=RAW_NEXT; + break; + case DIK_PREVTRACK: + code=RAW_PREVIOUS; + break; + } + + code |= 0xe000; + b = RAW_STEALTH | IECODE_UP_PREFIX; + record_key(((b << 1) | (b >> 7)) & 0xff); + b = IECODE_UP_PREFIX; + if ((code >> 8) == 0xe0) + b |= STEALTHF_E0KEY; + if ((code >> 8) == 0xe1) + b |= STEALTHF_E1KEY; + if (!newstate) + b |= STEALTHF_UPSTROKE; + record_key(((b << 1) | (b >> 7)) & 0xff); + b = ((code >> 4) & 0x0f) | IECODE_UP_PREFIX; + record_key(((b << 1) | (b >> 7)) & 0xff); + b = (code & 0x0f) | IECODE_UP_PREFIX; + record_key(((b << 1) | (b >> 7)) & 0xff); +} + void my_kbd_handler (int keyboard, int scancode, int newstate) { int code = 0; @@ -456,7 +547,11 @@ void my_kbd_handler (int keyboard, int scancode, int newstate) return; #endif } - inputdevice_translatekeycode (keyboard, scancode, newstate); + if (inputdevice_translatekeycode (keyboard, scancode, newstate)) + return; + + if (currprefs.mmkeyboard) + sendmmcodes(scancode, newstate); } void keyboard_settrans (void) diff --git a/od-win32/machdep/maccess.h b/od-win32/machdep/maccess.h index 13b29421..a3e356e3 100755 --- a/od-win32/machdep/maccess.h +++ b/od-win32/machdep/maccess.h @@ -165,7 +165,7 @@ static __inline__ void byteput_1 (uae_cptr addr, uae_u32 b) static __inline__ uae_u32 do_get_mem_long(uae_u32 *a) { -#ifndef _MSC_VER +#if !defined(X86_MSVC_ASSEMBLY) uae_u8 *b = (uae_u8 *)a; return (*b << 24) | (*(b+1) << 16) | (*(b+2) << 8) | (*(b+3)); #else @@ -192,7 +192,7 @@ static __inline__ uae_u16 do_get_mem_word(uae_u16 *a) static __inline__ void do_put_mem_long(uae_u32 *a, uae_u32 v) { -#ifndef _MSC_VER +#if !defined(X86_MSVC_ASSEMBLY) uae_u8 *b = (uae_u8 *)a; *b = v >> 24; diff --git a/od-win32/machdep/rpt.h b/od-win32/machdep/rpt.h index c371fd15..c22b76df 100755 --- a/od-win32/machdep/rpt.h +++ b/od-win32/machdep/rpt.h @@ -50,20 +50,27 @@ STATIC_INLINE frame_time_t read_processor_time_qpc (void) STATIC_INLINE frame_time_t read_processor_time (void) { - frame_time_t foo, bar; + frame_time_t foo; if (useqpc) /* No RDTSC or RDTSC is not stable */ return read_processor_time_qpc(); - __asm +#if defined(X86_MSVC_ASSEMBLY) { - rdtsc - mov foo, eax - mov bar, edx + frame_time_t bar; + __asm + { + rdtsc + mov foo, eax + mov bar, edx + } + /* very high speed CPU's RDTSC might overflow without this.. */ + foo >>= 6; + foo |= bar << 26; } - /* very high speed CPU's RDTSC might overflow without this.. */ - foo >>= 6; - foo |= bar << 26; +#else + foo = 0; +#endif #ifdef HIBERNATE_TEST if (rpt_skip_trigger) { foo += rpt_skip_trigger; diff --git a/od-win32/midi.c b/od-win32/midi.c index 2ffd18ad..6e776f66 100755 --- a/od-win32/midi.c +++ b/od-win32/midi.c @@ -503,15 +503,15 @@ int Midi_Parse( midi_direction_e direction, BYTE *dataptr ) static unsigned char midibuf[BUFFLEN]; static long midi_inptr = 0, midi_inlast = 0; -static void add1byte(char w) //put 1 Byte to Midibuffer +static void add1byte(DWORD_PTR w) //put 1 Byte to Midibuffer { if(midi_inlast >= BUFFLEN - 10) { TRACE(("add1byte buffer full %d %d (%02.2X)\n", midi_inlast, midi_inptr, w)); return; } - midibuf[midi_inlast++] = w; + midibuf[midi_inlast++] = (uae_u8)w; } -static void add2byte(long w) //put 2 Byte to Midibuffer +static void add2byte(DWORD_PTR w) //put 2 Byte to Midibuffer { if(midi_inlast >= BUFFLEN - 10) { TRACE(("add2byte buffer full %d %d (%04.4X)\n", midi_inlast, midi_inptr, w)); @@ -521,7 +521,7 @@ static void add2byte(long w) //put 2 Byte to Midibuffer w = w>>8; midibuf[midi_inlast++] = (uae_u8)w; } -static void add3byte(long w) //put 3 Byte to Midibuffer +static void add3byte(DWORD_PTR w) //put 3 Byte to Midibuffer { if(midi_inlast >= BUFFLEN - 10) { TRACE(("add3byte buffer full %d %d (%08.8X)\n", midi_inlast, midi_inptr, w)); @@ -582,7 +582,7 @@ LONG getmidibyte(void) //return midibyte or -1 if none return rv; } -static void CALLBACK MidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2) +static void CALLBACK MidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2) { EnterCriticalSection (&cs_proc); if(wMsg == MIM_ERROR) diff --git a/od-win32/mman.c b/od-win32/mman.c index 74e768ef..6aac98cd 100755 --- a/od-win32/mman.c +++ b/od-win32/mman.c @@ -12,22 +12,60 @@ #include "autoconf.h" #include "win32.h" +#if defined(NATMEM_OFFSET) + static struct shmid_ds shmids[MAX_SHMID]; static uae_u32 gfxoffs; -uae_u32 natmem_offset = 0; +uae_u8 *natmem_offset = NULL; +#ifdef CPU_64_BIT +uae_u32 max_allowed_mman = 2048; +#else uae_u32 max_allowed_mman = 512; +#endif + +static uae_u8 stackmagic64asm[] = { + 0x48,0x8b,0x44,0x24,0x28, // mov rax,qword ptr [rsp+28h] + 0x49,0x8b,0xe1, // mov rsp,r9 + 0xff,0xd0 // call rax +}; +uae_u8 *stack_magic_amd64_asm_executable; + +void cache_free(void *cache) +{ + VirtualFree (cache, 0, MEM_RELEASE); +} + +void *cache_alloc(int size) +{ + uae_u8 *cache; + cache = VirtualAlloc (NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + return cache; +} void init_shm(void) { + static int allocated; int i; LPVOID blah = NULL; - LPBYTE address = (LPBYTE)0x10000000; // Letting the system decide doesn't seem to work on some systems + // Letting the system decide doesn't seem to work on some systems (Win9x..) + LPBYTE address = (LPBYTE)0x10000000; uae_u32 size; uae_u32 add = 0x11000000; uae_u32 inc = 0x100000; MEMORYSTATUS memstats; +#ifdef CPU_64_BIT + if (!stack_magic_amd64_asm_executable) { + stack_magic_amd64_asm_executable = cache_alloc(sizeof stackmagic64asm); + memcpy(stack_magic_amd64_asm_executable, stackmagic64asm, sizeof stackmagic64asm); + } +#endif + + if (natmem_offset && os_winnt) + VirtualFree(natmem_offset, 0, MEM_RELEASE); + natmem_offset = NULL; + memstats.dwLength = sizeof(memstats); GlobalMemoryStatus(&memstats); max_z3fastmem = 16 * 1024 * 1024; @@ -60,7 +98,7 @@ void init_shm(void) } } if (os_winnt) { - natmem_offset = (uae_u32)blah; + natmem_offset = blah; } else { VirtualFree(blah, 0, MEM_RELEASE); while (address < (LPBYTE)0xa0000000) { @@ -70,7 +108,7 @@ void init_shm(void) } else { VirtualFree (blah, 0, MEM_RELEASE); address += inc * 32; - natmem_offset = (uae_u32)address; + natmem_offset = address; break; } } @@ -83,6 +121,7 @@ void init_shm(void) write_log("NATMEM: Our special area: 0x%p-0x%p (%dM)\n", natmem_offset, (uae_u8*)natmem_offset + size + add, (size + add) >> 20); canbang = 1; + allocated = 1; } while (memstats.dwAvailPageFile + memstats.dwAvailPhys < max_z3fastmem) @@ -154,17 +193,17 @@ int mprotect(void *addr, size_t len, int prot) return result; } -void *shmat(int shmid, LPVOID shmaddr, int shmflg) +void *shmat(int shmid, void *shmaddr, int shmflg) { void *result = (void *)-1; BOOL got = FALSE; #ifdef NATMEM_OFFSET - int size=shmids[shmid].size; + unsigned int size=shmids[shmid].size; extern uae_u32 allocated_z3fastmem; if(shmids[shmid].attached ) return shmids[shmid].attached; - if (shmaddr -#include "autoconf.h" - -static struct shmid_ds shmids[ MAX_SHMID ]; - -uae_u32 natmem_offset = 0; - -void init_shm( void ) -{ - int i; - LPTSTR string = NULL; -#if 0 - LPBYTE address = NULL; // Let the system decide where to put the memory... -#else - LPBYTE address = (LPBYTE)0x10000000; // Letting the system decide doesn't seem to work on some systems -#endif - - for( i = 0; i < MAX_SHMID; i++ ) { - shmids[i].attached = 0; - shmids[i].key = -1; - shmids[i].size = 0; - shmids[i].addr = NULL; - shmids[i].name[0] = 0; - } - natmem_offset = 0; - while( address < (LPBYTE)0x20000000 ) { - if (VirtualAlloc( address, 0x18800000, MEM_RESERVE, PAGE_EXECUTE_READWRITE )) { - natmem_offset = (uae_u32)address; - break; - } - address += 0x01000000; - } - if (natmem_offset) { - write_log( "NATMEM: Our special area is 0x%x\n", natmem_offset ); - canbang = 1; - VirtualFree (natmem_offset, 0, MEM_RELEASE); - } else { - write_log( "NATMEM: No special area could be allocated!\n" ); - } -} - -static key_t get_next_shmkey( void ) -{ - key_t result = -1; - int i; - for( i = 0; i < MAX_SHMID; i++ ) - { - if( shmids[i].key == -1 ) - { - shmids[i].key = i; - result = i; - break; - } - } - return result; -} - -STATIC_INLINE key_t find_shmkey( key_t key ) -{ - int result = -1; - if( shmids[key].key == key ) - { - result = key; - } - return result; -} - -int mprotect(void *addr, size_t len, int prot) -{ - int result = 0; - - return result; -} - -void *shmat(int shmid, LPVOID shmaddr, int shmflg) -{ - char *result = (void *)-1; - BOOL locked = FALSE; - -#ifdef NATMEM_OFFSET - int size=shmids[shmid].size; - extern uae_u32 allocated_z3fastmem; - if(shmids[shmid].attached ) - return shmids[shmid].attached; - if (shmaddr -#define CAN_DO_STACK_MAGIC - #ifdef CAN_DO_STACK_MAGIC -#ifdef __GNUC__ -static inline void transfer_control(void *, int, void *, void *, int) __attribute__((noreturn)); -static inline void transfer_control(void *s, int size, void *pc, void *f, int has_retval) + +#ifdef CPU_64_BIT + + /* + * UAE - The Un*x Amiga Emulator + * + * AMD64/GCC stack magic definitions for autoconf.c + * + * Copyright 2005 Richard Drummond + */ + +#include + +struct stack_frame +{ + uae_u64 back_chain; + + /* Local area */ + uae_u32 local_has_retval; + uae_u32 local_retval; + uae_u64 dummy; /* keep 16-byte aligned */ + + /* Previous frame */ + uae_u64 end_back_chain; +}; + +typedef void stupidfunc(void*,void*,uae_u32*,void*,void*); + +extern uae_u8 *stack_magic_amd64_asm_executable; + +__declspec(noreturn) static __forceinline void transfer_control (void *s, int size, void *pc, void *f, int has_retval) +{ + struct stack_frame *stacktop = (struct stack_frame *)((char *)s + size - sizeof (struct stack_frame)); + + stacktop->end_back_chain = 0xC0DEDBAD; + stacktop->local_retval = 0; + stacktop->local_has_retval = has_retval; + stacktop->back_chain = (uae_u64) &stacktop->end_back_chain; + + ((stupidfunc*)stack_magic_amd64_asm_executable)(s, f, &(stacktop->local_retval), ((uae_u8*)stacktop) - 4 * 8, pc); + /* Not reached. */ + abort (); +} + +STATIC_INLINE uae_u32 get_retval_from_stack (void *s, int size) +{ + return ((struct stack_frame *)((char *)s + size - sizeof(struct stack_frame)))->local_retval; +} + +STATIC_INLINE int stack_has_retval (void *s, int size) +{ + return ((struct stack_frame *)((char *)s + size - sizeof(struct stack_frame)))->local_has_retval; +} + #else + __declspec(noreturn) static __forceinline void transfer_control(void *s, int size, void *pc, void *f, int has_retval) -#endif { - unsigned long *stacktop = (unsigned long *)((char *)s + size - 20); + unsigned long *stacktop = (unsigned long *)((char *)s + size - 5 * 4); stacktop[0] = 0xC0DEDBAD; /* return address */ stacktop[1] = (int)s; /* function arg 1: stack */ stacktop[2] = (int)f; /* function arg 2: trap function */ stacktop[3] = (int)stacktop; /* function arg 3: return value address */ stacktop[4] = has_retval; -#ifdef __GNUC__ - __asm__ __volatile__ ("movl %0,%%esp\n\tpushl %1\n\tret\n" : : "r" (stacktop), "r" (pc) : "memory"); -#elif defined( _MSC_VER ) /* VisualC++ */ + __asm { mov esp, stacktop push pc ret } -#endif /* Not reached. */ abort(); } static __inline__ uae_u32 get_retval_from_stack (void *s, int size) { - return *(uae_u32 *)((char *)s + size - 20); + return *(uae_u32 *)((char *)s + size - 5 * 4); } static __inline__ int stack_has_retval (void *s, int size) @@ -49,3 +95,5 @@ static __inline__ int stack_has_retval (void *s, int size) } #endif + +#endif diff --git a/od-win32/parser.c b/od-win32/parser.c index 16f59a7a..eace8349 100755 --- a/od-win32/parser.c +++ b/od-win32/parser.c @@ -324,9 +324,9 @@ int load_ghostscript (void) if (!gsdll) { HKEY key; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\AFPL Ghostscript", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS) { - int idx = 0; + int idx = 0, cnt = 20; char tmp1[MAX_DPATH]; - for (;;) { + while (cnt-- > 0) { DWORD size1 = sizeof (tmp1); FILETIME ft; if (RegEnumKeyEx (key, idx, tmp1, &size1, NULL, NULL, NULL, &ft) == ERROR_SUCCESS) { @@ -803,6 +803,7 @@ void hsyncstuff(void) { flushprtbuf (); { +#if defined(AHI) extern flashscreen; int DX_Fill( int , int , int, int, uae_u32 , enum RGBFTYPE ); //extern int warned_JIT_0xF10000; @@ -811,6 +812,7 @@ void hsyncstuff(void) DX_Fill(0,0,300,40,0x000000,9); flashscreen--; } +#endif } keycheck = 0; } diff --git a/od-win32/picasso96_win.c b/od-win32/picasso96_win.c index bfbb7f23..46ce1719 100755 --- a/od-win32/picasso96_win.c +++ b/od-win32/picasso96_win.c @@ -45,18 +45,20 @@ #include "savestate.h" #include "autoconf.h" +#if defined(PICASSO96) + #include "dxwrap.h" #include "picasso96_win.h" #include "win32gfx.h" int p96hack_vpos, p96hack_vpos2, p96refresh_active; int have_done_picasso; /* For the JIT compiler */ -int picasso_is_special = PIC_WRITE; /* ditto */ -int picasso_is_special_read = PIC_READ; /* ditto */ static int vsyncgfxwrite = 0; static int p96syncrate,vsyncgfxcount; int p96hsync_counter; -#define SWAPSPEEDUP +#if defined(X86_MSVC_ASSEMBLY) +#define SWAPSPEEDUP +#endif #ifdef PICASSO96 #ifdef DEBUG // Change this to _DEBUG for debugging #define P96TRACING_ENABLED 1 @@ -81,6 +83,18 @@ struct pixel32 pixelbase[MAXFLUSHPIXEL+2]; #define GetBytesPerPixel(x) GetBytesPerPixel2(x,__FILE__,__LINE__) +#if defined(JIT) +static int picasso_is_special = PIC_WRITE; /* ditto */ +static int picasso_is_special_read = PIC_READ; /* ditto */ +#define P96_SM_RS special_mem |= picasso_is_special_read | picasso_is_special +#define P96_SM_R special_mem |= picasso_is_special_read; +#define P96_SM_S special_mem |= picasso_is_special; +#else +#define P96_SM_RS +#define P96_SM_R +#define P96_SM_S +#endif + static uae_u32 REGPARAM2 gfxmem_lget (uaecptr) REGPARAM; static uae_u32 REGPARAM2 gfxmem_wget (uaecptr) REGPARAM; static uae_u32 REGPARAM2 gfxmem_bget (uaecptr) REGPARAM; @@ -707,8 +721,7 @@ static void do_blit( struct RenderInfo *ri, int Bpp, #endif srcp = ri->Memory + srcx*Bpp + srcy*ri->BytesPerRow; - - + DX_Invalidate (dsty, dsty + height - 1); if (! picasso_vidinfo.extra_mem) { @@ -743,7 +756,7 @@ static void do_blit( struct RenderInfo *ri, int Bpp, width *= Bpp; while (height-- > 0) { - memcpy (dstp, srcp, width); + memcpy (dstp, srcp, width); srcp += ri->BytesPerRow; dstp += picasso_vidinfo.rowbytes; @@ -1112,7 +1125,7 @@ long height, uae_u8 mask, BLIT_OPCODE opcode ) for( y = 0; y < height; y++ ) /* Vertical lines */ { - int bound = src + total_width - 4; + uae_u8 *bound = src + total_width - 4; //copy now the longs for( src2_32 = src, dst2_32 = dst; src2_32 < bound; src2_32++, dst2_32++ ) /* Horizontal bytes */ { @@ -2098,7 +2111,7 @@ uae_u32 picasso_FillRect (void) if (Width * Height <= 2500) return 0; - special_mem|=picasso_is_special_read|picasso_is_special; + P96_SM_RS; #ifdef LOCK_UNLOCK_MADNESS //PICASSO96_Unlock(); // We need this, because otherwise we're still Locked from custom.c @@ -2381,7 +2394,7 @@ uae_u32 picasso_BlitRect (void) uae_u8 Mask = (uae_u8)m68k_dreg (regs, 6); uae_u32 result = 0; - special_mem|=picasso_is_special_read|picasso_is_special; + P96_SM_RS; #ifdef LOCK_UNLOCK_MADNESS //PICASSO96_Unlock(); @@ -2430,7 +2443,7 @@ uae_u32 picasso_BlitRectNoMaskComplete (void) uae_u32 RGBFmt = m68k_dreg (regs, 7); uae_u32 result = 0; - special_mem|=picasso_is_special_read|picasso_is_special; + P96_SM_RS; #ifdef LOCK_UNLOCK_MADNESS //PICASSO96_Unlock(); @@ -2538,7 +2551,7 @@ uae_u32 picasso_BlitPattern (void) unsigned long ysize_mask; uae_u32 result = 0; - special_mem|=picasso_is_special_read|picasso_is_special; + P96_SM_RS; #ifdef LOCK_UNLOCK_MADNESS //PICASSO96_Unlock(); @@ -2713,7 +2726,7 @@ uae_u32 picasso_BlitTemplate (void) // if (W * H <= 2500) // return 0; - special_mem|=picasso_is_special_read|picasso_is_special; + P96_SM_RS; #ifdef LOCK_UNLOCK_MADNESS //PICASSO96_Unlock(); // @@@ We need to unlock here, because do_blit (later) needs to lock... @@ -3030,7 +3043,7 @@ uae_u32 picasso_BlitPlanar2Chunky (void) struct BitMap local_bm; uae_u32 result = 0; - special_mem|=picasso_is_special_read|picasso_is_special; + P96_SM_RS; #ifdef LOCK_UNLOCK_MADNESS //PICASSO96_Unlock(); @@ -3187,7 +3200,7 @@ uae_u32 picasso_BlitPlanar2Direct (void) struct ColorIndexMapping local_cim; uae_u32 result = 0; - special_mem|=picasso_is_special_read|picasso_is_special; + P96_SM_RS; #ifdef LOCK_UNLOCK_MADNESS //PICASSO96_Unlock(); @@ -3230,10 +3243,9 @@ uae_u32 picasso_BlitPlanar2Direct (void) static void flushpixels( void ) { int i,y,x,xbytes,size; - uae_u8 *dst; - uaecptr addr,xminaddr=0,xmaxaddr,ydestaddr; + uae_u8 *dst, *ydestaddr; + uaecptr addr,xminaddr=0,xmaxaddr; uae_u32 value; - int lock=0; if (pixelcount==0)return; @@ -3279,7 +3291,8 @@ static void flushpixels( void ) if(psiz==4) { int i2; - unsigned int addr,val; + unsigned int val; + uae_u8 *addr; i2=pixelbase[i].size; addr=dst + y * picasso_vidinfo.rowbytes + ((xbytes)*4); @@ -3311,7 +3324,8 @@ static void flushpixels( void ) else { int i2; - unsigned int addr,val; + unsigned int val; + uae_u8 *addr; i2=pixelbase[i].size; addr=dst + y * picasso_vidinfo.rowbytes + ((xbytes)*2); @@ -3666,7 +3680,7 @@ static uae_u32 REGPARAM2 gfxmem_lget (uaecptr addr) { uae_u32 *m; - special_mem|=picasso_is_special_read; + P96_SM_R; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; m = (uae_u32 *)(gfxmemory + addr); @@ -3676,7 +3690,7 @@ static uae_u32 REGPARAM2 gfxmem_lget (uaecptr addr) static uae_u32 REGPARAM2 gfxmem_wget (uaecptr addr) { uae_u16 *m; - special_mem|=picasso_is_special_read; + P96_SM_R; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; m = (uae_u16 *)(gfxmemory + addr); @@ -3685,7 +3699,7 @@ static uae_u32 REGPARAM2 gfxmem_wget (uaecptr addr) static uae_u32 REGPARAM2 gfxmem_bget (uaecptr addr) { - special_mem|=picasso_is_special_read; + P96_SM_R; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; return gfxmemory[addr]; @@ -3701,7 +3715,7 @@ static void REGPARAM2 gfxmem_lput (uaecptr addr, uae_u32 l) mov l,eax } #endif - special_mem|=picasso_is_special; + P96_SM_S; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; @@ -3730,7 +3744,7 @@ l2: static void REGPARAM2 gfxmem_wput (uaecptr addr, uae_u32 w) { uae_u16 *m; - special_mem|=picasso_is_special; + P96_SM_S; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; m = (uae_u16 *)(gfxmemory + addr); @@ -3742,7 +3756,7 @@ static void REGPARAM2 gfxmem_wput (uaecptr addr, uae_u32 w) static void REGPARAM2 gfxmem_bput (uaecptr addr, uae_u32 b) { - special_mem|=picasso_is_special; + P96_SM_S; addr -= gfxmem_start & gfxmem_mask; addr &= gfxmem_mask; gfxmemory[addr] = b; @@ -3837,7 +3851,7 @@ uae_u8 *restore_p96 (uae_u8 *src) return src; } -uae_u8 *save_p96 (int *len) +uae_u8 *save_p96 (int *len, uae_u8 *dstptr) { uae_u8 *dstbak,*dst; @@ -3845,7 +3859,6 @@ uae_u8 *save_p96 (int *len) return 0; } - - +#endif #endif diff --git a/od-win32/picasso96_win.h b/od-win32/picasso96_win.h index 3f5fe9eb..16e4ab79 100755 --- a/od-win32/picasso96_win.h +++ b/od-win32/picasso96_win.h @@ -470,7 +470,7 @@ struct picasso96_state_struct //here follow winuae additional entrys uae_u8 BigAssBitmap; /* Set to 1 when our Amiga screen is bigger than the displayable area */ unsigned int Version; - uaecptr HostAddress; /* Active screen address (PC-side) */ + uae_u8 *HostAddress; /* Active screen address (PC-side) */ // host address is need because Windows // support NO direct access all the time to gfx Card // everytime windows can remove your surface from card so the mainrender place diff --git a/od-win32/posixemu.c b/od-win32/posixemu.c index 90b63339..7671aa26 100755 --- a/od-win32/posixemu.c +++ b/od-win32/posixemu.c @@ -223,7 +223,7 @@ void sem_close (HANDLE * event) typedef unsigned (__stdcall *BEGINTHREADEX_FUNCPTR)(void *); -int start_penguin (void *(*f)(void *), void *arg, DWORD * foo) +int start_penguin (void *(*f)(void *), void *arg, DWORD *foo) { HANDLE hThread; int result = 1; diff --git a/od-win32/resources/winuae.exe.manifest b/od-win32/resources/winuae.exe.manifest index 1ad2ee6b..636d42c6 100755 --- a/od-win32/resources/winuae.exe.manifest +++ b/od-win32/resources/winuae.exe.manifest @@ -1,22 +1,14 @@ -รฏยปยฟ - - - - + \ No newline at end of file diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 78a9680c..218f83e4 100755 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -336,7 +336,7 @@ BEGIN PUSHBUTTON "Contributors",IDC_CONTRIBUTORS,110,55,80,15 CONTROL "",IDC_UAEHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,20,120,80,15 CONTROL "",IDC_PICASSOHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,200,90,80,20 - CONTROL "",IDC_AMIGAHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,110,90,80,15 + CONTROL "",IDC_AMIGAHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,109,74,80,15 CONTROL "",IDC_WINUAEHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,200,120,80,15 CONTROL "",IDC_AIABHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,110,120,80,15 CONTROL "",IDC_THEROOTS,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,20,145,80,15 @@ -881,13 +881,6 @@ IDR_DRIVE_SPIN_A500_1 WAVE "drive_spin.wav" IDR_DRIVE_SNATCH_A500_1 WAVE "drive_snatch.wav" IDR_DRIVE_SPINND_A500_1 WAVE "drive_spinnd.wav" -///////////////////////////////////////////////////////////////////////////// -// -// RT_MANIFEST -// - -1 RT_MANIFEST "winuae.exe.manifest" - ///////////////////////////////////////////////////////////////////////////// // // Bitmap diff --git a/od-win32/scaler.c b/od-win32/scaler.c index 51fae9ff..007c63fd 100755 --- a/od-win32/scaler.c +++ b/od-win32/scaler.c @@ -613,7 +613,7 @@ static void internal_scale2x_32_def(u32* dst0, dst1[1] = src1[0]; } -#ifdef MMX +#if defined(MMX) && (defined(X86_ASSEMBLY) || defined(X86_MSVC_ASSEMBLY)) static void internal_scale2x_16_mmx_single(u16* dst, const u16* src0, const u16* src1, const u16* src2, unsigned count) { /* always do the first and last run */ count -= 2*4; @@ -1391,7 +1391,7 @@ void AdMame2x(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ u16 *src0 = (u16 *)srcPtr; u16 *src1 = src0 + (srcPitch/2); u16 *src2 = src1 + (srcPitch/2); -#ifdef MMX +#if defined(MMX) && (defined(X86_ASSEMBLY) || defined(X86_MSVC_ASSEMBLY)) if(cpu_mmx) { internal_scale2x_16_mmx(dst0, dst1, src0, src0, src1, width); @@ -1433,7 +1433,7 @@ void AdMame2x(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ dst0 += dstPitch; dst1 += dstPitch; internal_scale2x_16_def(dst0, dst1, src0, src1, src1, width); -#ifdef MMX +#if defined(MMX) && (defined(X86_ASSEMBLY) || defined(X86_MSVC_ASSEMBLY)) } #endif } @@ -1447,7 +1447,7 @@ void AdMame2x32(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ u32 *src0 = (u32 *)srcPtr; u32 *src1 = src0 + (srcPitch/4); u32 *src2 = src1 + (srcPitch/4); -#ifdef MMX +#if defined(MMX) && (defined(X86_ASSEMBLY) || defined(X86_MSVC_ASSEMBLY)) if(cpu_mmx) { internal_scale2x_32_mmx(dst0, dst1, src0, src0, src1, width); @@ -1488,7 +1488,7 @@ void AdMame2x32(u8 *srcPtr, u32 srcPitch, /* u8 deltaPtr, */ dst0 += dstPitch/2; dst1 += dstPitch/2; internal_scale2x_32_def(dst0, dst1, src0, src1, src1, width); -#ifdef MMX +#if defined(MMX) && (defined(X86_ASSEMBLY) || defined(X86_MSVC_ASSEMBLY)) } #endif } diff --git a/od-win32/sounddep/sound.c b/od-win32/sounddep/sound.c index 242b7a76..bf79ce46 100755 --- a/od-win32/sounddep/sound.c +++ b/od-win32/sounddep/sound.c @@ -107,7 +107,7 @@ static void clearbuffer (void) hr = IDirectSoundBuffer_Lock (lpDSBsecondary, 0, dsoundbuf, &buffer, &size, NULL, NULL, 0); } if (FAILED(hr)) { - write_log ("failed to Lock sound buffer (clear): %s\n", DXError (hr)); + write_log ("SOUND: failed to Lock sound buffer (clear): %s\n", DXError (hr)); return; } memset (buffer, 0, size); @@ -129,7 +129,7 @@ static void resume_audio_ds (void) clearbuffer (); hr = IDirectSoundBuffer_Play (lpDSBsecondary, 0, 0, DSBPLAY_LOOPING); if (FAILED(hr)) - write_log ("Play failed: %s\n", DXError (hr)); + write_log ("SOUND: play failed: %s\n", DXError (hr)); writepos = snd_configsize; } @@ -142,7 +142,7 @@ static int restore (DWORD hr) #endif hr = IDirectSoundBuffer_Restore (lpDSBsecondary); if (FAILED(hr)) { - //write_log ("restore failed %s\n", DXError (hr)); + write_log ("SOUND: restore failed %s\n", DXError (hr)); return 1; } pause_audio_ds (); @@ -169,7 +169,7 @@ static int getpos (void) hr = IDirectSoundBuffer_GetCurrentPosition (lpDSBsecondary, &playpos, &safepos); if (FAILED(hr)) { - write_log ("GetCurrentPosition failed: %s\n", DXError (hr)); + write_log ("SOUND: GetCurrentPosition failed: %s\n", DXError (hr)); return -1; } return playpos; @@ -183,7 +183,7 @@ static int calibrate (void) double qv, pct; if (!QueryPerformanceFrequency(&qpf)) { - write_log ("no QPF, can't calibrate\n"); + write_log ("SOUND: no QPF, can't calibrate\n"); return 100 * 10; } pos = 1000; @@ -210,7 +210,7 @@ static int calibrate (void) tpos /= mult; diff = tpos - expected; pct = tpos * 100.0 / expected; - write_log ("sound calibration: %d %d (%d %.2f%%)\n", tpos, expected, diff, pct); + write_log ("SOUND: calibration: %d %d (%d %.2f%%)\n", tpos, expected, diff, pct); return (int)(pct * 10); } @@ -223,7 +223,7 @@ static void close_audio_ds (void) lpDSBsecondary = lpDSBprimary = 0; if (lpDS) { IDirectSound_Release (lpDS); - write_log ("DirectSound driver freed\n"); + write_log ("SOUND: DirectSound driver freed\n"); } lpDS = 0; } @@ -496,14 +496,17 @@ static void finish_sound_buffer_ds (void) double vdiff, m, skipmode; hr = IDirectSoundBuffer_GetStatus (lpDSBsecondary, &status); - if (FAILED(hr)) + if (FAILED(hr)) { + write_log ("SOUND: GetStatus() failed: %s\n", DXError(hr)); return; + } if (status & DSBSTATUS_BUFFERLOST) { + write_log ("SOUND: buffer lost\n"); restore (DSERR_BUFFERLOST); return; } if ((status & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) != (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) { - write_log ("sound status = %08.8X\n", status); + write_log ("SOUND: status = %08.8X\n", status); restore (DSERR_BUFFERLOST); return; } @@ -511,7 +514,7 @@ static void finish_sound_buffer_ds (void) hr = IDirectSoundBuffer_GetCurrentPosition (lpDSBsecondary, &playpos, &safepos); if (FAILED(hr)) { restore (hr); - //write_log ("GetCurrentPosition failed: %s\n", DirectSound_ErrorText (hr)); + write_log ("SOUND: GetCurrentPosition failed: %s\n", DXError (hr)); return; } @@ -535,7 +538,7 @@ static void finish_sound_buffer_ds (void) sleep_millis_busy (1); counter--; if (counter < 0) { - write_log ("sound system got stuck!?\n"); + write_log ("SOUND: sound system got stuck!?\n"); restore (DSERR_BUFFERLOST); return; } @@ -548,7 +551,7 @@ static void finish_sound_buffer_ds (void) if (restore (hr)) return; if (FAILED(hr)) { - write_log ("lock failed: %s (%d %d)\n", DXError (hr), writepos, sndbufsize); + write_log ("SOUND: lock failed: %s (%d %d)\n", DXError (hr), writepos, sndbufsize); return; } memcpy (b1, sndbuffer, sndbufsize >= s1 ? s1 : sndbufsize); diff --git a/od-win32/srcrelease.bat b/od-win32/srcrelease.bat index dff75e5f..de9c4527 100755 --- a/od-win32/srcrelease.bat +++ b/od-win32/srcrelease.bat @@ -50,6 +50,10 @@ rm -f winuae_msvc.plg rm -f winuae_msvc.ncb rm -rf debug rm -rf release +rm -rf debug64 +rm -rf release64 +rm -rf x64 +rm -rf _UpgradeReport_Files cd .. cd miniuae diff --git a/od-win32/stackmagic_amd64.asm b/od-win32/stackmagic_amd64.asm new file mode 100755 index 00000000..fbeef4eb --- /dev/null +++ b/od-win32/stackmagic_amd64.asm @@ -0,0 +1,14 @@ +_TEXT SEGMENT + +_stack_magic_amd64: + mov rax, [rsp+16] ; move parameter 'pc' to a spare register + mov rsp, r9 ; swap stack + mov rsp, r9 ; swap stack + call rax ; call function pointed to by 'pc' + + mov rax,rsp + sub rax,2300*512 + ret + ret + +END diff --git a/od-win32/sys/mman.h b/od-win32/sys/mman.h index eb8a81b0..8f5d2fb2 100755 --- a/od-win32/sys/mman.h +++ b/od-win32/sys/mman.h @@ -12,7 +12,7 @@ #define MAX_SHMID 256 -extern uae_u32 natmem_offset; +extern uae_u8 *natmem_offset; typedef int key_t; typedef USHORT ushort; diff --git a/od-win32/sysconfig.h b/od-win32/sysconfig.h index 0136138b..4b40ac04 100755 --- a/od-win32/sysconfig.h +++ b/od-win32/sysconfig.h @@ -9,6 +9,8 @@ #define DRIVESOUND #define GFXFILTER +#define CAN_DO_STACK_MAGIC +#define X86_MSVC_ASSEMBLY #ifndef UAE_MINI @@ -25,6 +27,7 @@ #define WINDDK /* Windows DDK available, keyboard leds and harddrive support */ #define CATWEASEL /* Catweasel MK2/3 support */ #define AHI /* AHI sound emulation */ +#define ENFORCER /* UAE Enforcer */ #define AGA /* AGA chipset emulation */ #define CD32 /* CD32 emulation */ #define CDTV /* CDTV emulation */ @@ -77,6 +80,16 @@ #include #endif +#ifdef WIN64 +#undef JIT +#undef X86_MSVC_ASSEMBLY +#define X64_MSVC_ASSEMBLY +#define CPU_64_BIT +#endif + +#if !defined(AHI) +#undef ENFORCER +#endif /* src/sysconfig.h. Generated automatically by configure. */ /* src/sysconfig.h.in. Generated automatically from configure.in by autoheader. */ diff --git a/od-win32/win32.c b/od-win32/win32.c index 14b34488..75db4905 100755 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -62,9 +62,7 @@ #include "parser.h" #include "scsidev.h" #include "disk.h" - -unsigned long *win32_stackbase; -unsigned long *win32_freestack[42]; //EXTRA_STACK_SIZE +#include "catweasel.h" extern FILE *debugfile; extern int console_logging; @@ -189,14 +187,18 @@ static void dummythread (void *dummy) static uae_u64 win32_read_processor_time (void) { +#if defined(X86_MSVC_ASSEMBLY) uae_u32 foo, bar; - __asm + __asm { rdtsc mov foo, eax mov bar, edx } return ((uae_u64)bar << 32) | foo; +#else + return 0; +#endif } static int figure_processor_speed (void) @@ -212,13 +214,14 @@ static int figure_processor_speed (void) int mmx = 0; rpt_available = no_rdtsc > 0 ? 0 : 1; +#ifdef X86_MSVC_ASSEMBLY __try { __asm { rdtsc } - } __except( GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION ) { + } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) { rpt_available = 0; write_log ("CLOCKFREQ: RDTSC not supported\n"); } @@ -235,6 +238,11 @@ static int figure_processor_speed (void) cpu_mmx = 1; } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) { } +#endif +#ifdef WIN64 + cpu_mmx = 1; + rpt_available = 0; +#endif if (QueryPerformanceFrequency(&freq)) { qpc_avail = 1; @@ -695,7 +703,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, return 0; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: - if (!mouseactive && !isfullscreen()) { + if (!mouseactive && !isfullscreen() && !gui_active) { setmouseactive (1); } if (dinput_winmouse () >= 0) @@ -899,7 +907,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, case NM_RCLICK: { LPNMMOUSE lpnm = (LPNMMOUSE) lParam; - int num = lpnm->dwItemSpec; + int num = (int)lpnm->dwItemSpec; if (num >= 6 && num <= 9) { num -= 6; if (nm->code == NM_RCLICK) { @@ -2076,6 +2084,7 @@ static void betamessage (void) static int dxdetect (void) { +#if !defined(WIN64) /* believe or not but this is MS supported way of detecting DX8+ */ HMODULE h = LoadLibrary("D3D8.DLL"); char szWrongDXVersion[ MAX_DPATH ]; @@ -2086,6 +2095,9 @@ static int dxdetect (void) WIN32GUI_LoadUIString( IDS_WRONGDXVERSION, szWrongDXVersion, MAX_DPATH ); pre_gui_message( szWrongDXVersion ); return 0; +#else + return 1; +#endif } int os_winnt, os_winnt_admin; @@ -2243,18 +2255,6 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR int multi_display = 1; int start_data = 0; -#if 1 -#ifdef __GNUC__ - __asm__ ("leal -2300*1024(%%esp),%0" : "=r" (win32_stackbase) :); -#else -__asm{ - mov eax,esp - sub eax,2300*1024 - mov win32_stackbase,eax - } -#endif -#endif - #ifdef _DEBUG { int tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); @@ -2309,7 +2309,14 @@ __asm{ #endif getstartpaths(start_data); sprintf(help_file, "%sWinUAE.chm", start_path_data); - sprintf(VersionStr, "WinUAE %d.%d.%d%s", UAEMAJOR, UAEMINOR, UAESUBREV, WINUAEBETA ? WINUAEBETASTR : ""); + sprintf(VersionStr, "WinUAE %d.%d.%d%s (%d-bit)", + UAEMAJOR, UAEMINOR, UAESUBREV, WINUAEBETA ? WINUAEBETASTR : "", + #if defined(WIN64) + 64 + #else + 32 + #endif + ); SetCurrentDirectory (start_path_data); logging_init (); @@ -2340,6 +2347,9 @@ __asm{ DirectDraw_Release(); betamessage (); keyboard_settrans (); +#ifdef CATWEASEL + catweasel_init(); +#endif #ifdef PARALLEL_PORT paraport_mask = paraport_init (); #endif @@ -2416,6 +2426,15 @@ int driveclick_loadresource (struct drvsample *sp, int drivetype) return ok; } +#if defined(WIN64) + +static LONG WINAPI ExceptionFilter( struct _EXCEPTION_POINTERS * pExceptionPointers, DWORD ec) +{ + write_log("EVALEXCEPTION!\n"); + return EXCEPTION_EXECUTE_HANDLER; +} +#else + #if 0 #include #endif @@ -2543,6 +2562,8 @@ static LONG WINAPI ExceptionFilter( struct _EXCEPTION_POINTERS * pExceptionPoint return lRet ; } +#endif + void systray (HWND hwnd, int remove) { NOTIFYICONDATA nid; @@ -2599,27 +2620,83 @@ void systraymenu (HWND hwnd) winuae_active (hwnd, FALSE); } +static void LLError(const char *s) +{ + DWORD err = GetLastError(); + + if (err == ERROR_MOD_NOT_FOUND) + return; + write_log("%s failed to open %d\n", s, err); +} HMODULE WIN32_LoadLibrary (const char *name) { - HMODULE m; - char *s = xmalloc (strlen (start_path_exe) + strlen (WIN32_PLUGINDIR) + strlen (name) + 1); - if (s) { - sprintf (s, "%s%s%s", start_path_exe, WIN32_PLUGINDIR, name); - m = LoadLibrary (s); - xfree (s); + HMODULE m = NULL; + char *newname; + DWORD err = -1; + char *p; + int round; + + newname = xmalloc(strlen(name) + 1 + 10); + if (!newname) + return NULL; + for (round = 0; round < 4; round++) { + char *s; + strcpy(newname, name); +#ifdef CPU_64_BIT + switch(round) + { + case 0: + p = strstr(newname,"32"); + if (p) { + p[0] = '6'; + p[1] = '4'; + } + break; + case 1: + p = strchr(newname,'.'); + strcpy(p,"_64"); + strcat(p, strchr(name,'.')); + break; + case 2: + p = strchr(newname,'.'); + strcpy(p,"64"); + strcat(p, strchr(name,'.')); + break; + } +#endif + s = xmalloc (strlen (start_path_exe) + strlen (WIN32_PLUGINDIR) + strlen (newname) + 1); + if (s) { + sprintf (s, "%s%s%s", start_path_exe, WIN32_PLUGINDIR, newname); + m = LoadLibrary (s); + if (m) + goto end; + LLError(s); + xfree (s); + } + m = LoadLibrary (newname); if (m) - return m; + goto end; + LLError(newname); +#ifndef CPU_64_BIT + break; +#endif } - return LoadLibrary (name); +end: + xfree(newname); + return m; } +uae_u8 *win32_stackbase; + int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HANDLE thread; DWORD_PTR oldaff; + win32_stackbase = _alloca(32768 * 32); + thread = GetCurrentThread(); oldaff = SetThreadAffinityMask(thread, 1); __try { diff --git a/od-win32/win32.h b/od-win32/win32.h index e6f9655a..af7e371e 100755 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -21,8 +21,8 @@ extern int manual_painting_needed; extern int manual_palette_refresh_needed; extern int mouseactive, focus; extern int ignore_messages_all; -#define WINUAEBETA 0 -#define WINUAEBETASTR "" +#define WINUAEBETA 1 +#define WINUAEBETASTR " Beta 1" extern char start_path_exe[MAX_DPATH]; extern char start_path_data[MAX_DPATH]; diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index 6f2b05fc..b17b7893 100755 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -883,7 +883,9 @@ void flush_clear_screen (void) uae_u8 *gfx_lock_picasso (void) { - return ddraw_dolock (); + uae_u8 *p = ddraw_dolock (); + picasso_vidinfo.rowbytes = DirectDraw_GetSurfacePitch(); + return p; } void gfx_unlock_picasso (void) @@ -1390,32 +1392,32 @@ static COLORREF BuildColorRef( int color, RGBFTYPE pixelformat ) * Definitions: * - primary is the displayed (visible) surface in VRAM, which may have an associated offscreen surface (or back-buffer) */ -int DX_Fill( int dstx, int dsty, int width, int height, uae_u32 color, RGBFTYPE rgbtype ) +int DX_Fill(int dstx, int dsty, int width, int height, uae_u32 color, RGBFTYPE rgbtype) { int result = 0; RECT dstrect; RECT srcrect; DDBLTFX ddbltfx; - memset( &ddbltfx, 0, sizeof( ddbltfx ) ); - ddbltfx.dwFillColor = BuildColorRef( color, rgbtype ); - ddbltfx.dwSize = sizeof( ddbltfx ); + memset(&ddbltfx, 0, sizeof(ddbltfx)); + ddbltfx.dwFillColor = BuildColorRef(color, rgbtype); + ddbltfx.dwSize = sizeof(ddbltfx); /* Set up our source rectangle. This NEVER needs to be adjusted for windowed display, since the * source is ALWAYS in an offscreen buffer, or we're in full-screen mode. */ - SetRect( &srcrect, dstx, dsty, dstx+width, dsty+height ); + SetRect(&srcrect, dstx, dsty, dstx+width, dsty+height); /* Set up our destination rectangle, and adjust for blit to windowed display (if necessary ) */ - SetRect( &dstrect, dstx, dsty, dstx+width, dsty+height ); - if( !(currentmode->flags & (DM_DX_FULLSCREEN | DM_OVERLAY))) - OffsetRect( &dstrect, amigawin_rect.left, amigawin_rect.top ); + SetRect(&dstrect, dstx, dsty, dstx+width, dsty+height); + if(!(currentmode->flags & (DM_DX_FULLSCREEN | DM_OVERLAY))) + OffsetRect(&dstrect, amigawin_rect.left, amigawin_rect.top); /* Render our fill to the visible (primary) surface */ - if( ( result = DirectDraw_Blt( primary_surface, &dstrect, invalid_surface, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx ) ) ) + if((result = DirectDraw_Blt(primary_surface, &dstrect, invalid_surface, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx))) { - if( DirectDraw_GetLockableType() == secondary_surface ) + if(DirectDraw_GetLockableType() == secondary_surface) { /* We've colour-filled the visible, but still need to colour-fill the offscreen */ - result = DirectDraw_Blt( secondary_surface, &srcrect, invalid_surface, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx ); + result = DirectDraw_Blt(secondary_surface, &srcrect, invalid_surface, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); } } return result; @@ -1426,9 +1428,9 @@ int DX_Fill( int dstx, int dsty, int width, int height, uae_u32 color, RGBFTYPE * - primary is the displayed (visible) surface in VRAM, which may have an associated offscreen surface (or back-buffer) */ -static DDBLTFX fx = { sizeof( DDBLTFX ) }; +static DDBLTFX fx = { sizeof(DDBLTFX) }; -static DWORD BLIT_OPCODE_TRANSLATION[ BLIT_LAST ] = +static DWORD BLIT_OPCODE_TRANSLATION[BLIT_LAST] = { BLACKNESS, /* BLIT_FALSE */ NOTSRCERASE,/* BLIT_NOR */ @@ -1448,53 +1450,46 @@ static DWORD BLIT_OPCODE_TRANSLATION[ BLIT_LAST ] = WHITENESS /* BLIT_TRUE */ }; -int DX_Blit( int srcx, int srcy, int dstx, int dsty, int width, int height, BLIT_OPCODE opcode ) +int DX_Blit(int srcx, int srcy, int dstx, int dsty, int width, int height, BLIT_OPCODE opcode) { - int result = 0; - RECT dstrect; - RECT srcrect; - DWORD dwROP = BLIT_OPCODE_TRANSLATION[ opcode ]; + HRESULT result; + RECT dstrect, srcrect; + DWORD dwROP = BLIT_OPCODE_TRANSLATION[opcode]; + + if(dwROP == -1) { + /* Unsupported blit opcode! */ + return 0; + } + fx.dwROP = dwROP; /* Set up our source rectangle. This NEVER needs to be adjusted for windowed display, since the * source is ALWAYS in an offscreen buffer, or we're in full-screen mode. */ - SetRect( &srcrect, srcx, srcy, srcx+width, srcy+height ); + SetRect(&srcrect, srcx, srcy, srcx+width, srcy+height); /* Set up our destination rectangle, and adjust for blit to windowed display (if necessary ) */ - SetRect( &dstrect, dstx, dsty, dstx+width, dsty+height ); + SetRect(&dstrect, dstx, dsty, dstx+width, dsty+height); - if( !(currentmode->flags & (DM_DX_FULLSCREEN | DM_OVERLAY))) - OffsetRect( &dstrect, amigawin_rect.left, amigawin_rect.top ); - - if( dwROP == -1 ) - { - /* Unsupported blit opcode! */ - return 0; - } - else - { - fx.dwROP = dwROP; - } + if(!(currentmode->flags & (DM_DX_FULLSCREEN | DM_OVERLAY))) + OffsetRect(&dstrect, amigawin_rect.left, amigawin_rect.top); /* Render our blit within the primary surface */ - result = DirectDraw_Blt( primary_surface, &dstrect, DirectDraw_GetLockableType(), &srcrect, DDBLT_WAIT | DDBLT_ROP, &fx ); - - if( !result ) - { - BLIT_OPCODE_TRANSLATION[ opcode ] = -1; - } - else if( DirectDraw_GetLockableType() == secondary_surface ) - { + result = DirectDraw_Blt(primary_surface, &dstrect, DirectDraw_GetLockableType(), &srcrect, DDBLT_WAIT | DDBLT_ROP, &fx); + if (FAILED(result)) { + write_log("DX_Blit1() failed %s\n", DXError(result)); + return 0; + } else if(DirectDraw_GetLockableType() == secondary_surface) { /* We've just blitted from the offscreen to the visible, but still need to blit from offscreen to offscreen * NOTE: reset our destination rectangle again if its been modified above... */ - if( ( srcx != dstx ) || ( srcy != dsty ) ) - { - if(!(currentmode->flags & DM_DX_FULLSCREEN)) - SetRect( &dstrect, dstx, dsty, dstx+width, dsty+height ); - result = DirectDraw_Blt( secondary_surface, &dstrect, secondary_surface, &srcrect, DDBLT_WAIT | DDBLT_ROP, &fx ); + if((srcx != dstx) || (srcy != dsty)) { + SetRect(&dstrect, dstx, dsty, dstx+width, dsty+height); + result = DirectDraw_Blt(secondary_surface, &dstrect, secondary_surface, &srcrect, DDBLT_WAIT | DDBLT_ROP, &fx); + if (FAILED(result)) { + write_log("DX_Blit2() failed %s\n", DXError(result)); + } } } - return result; + return 1; } void DX_WaitVerticalSync( void ) @@ -1502,6 +1497,7 @@ void DX_WaitVerticalSync( void ) DirectDraw_WaitForVerticalBlank (DDWAITVB_BLOCKBEGIN); } +#if 0 uae_u32 DX_ShowCursor( uae_u32 activate ) { uae_u32 result = 0; @@ -1509,7 +1505,6 @@ uae_u32 DX_ShowCursor( uae_u32 activate ) result = 1; return result; } - uae_u32 DX_MoveCursor( uae_u32 x, uae_u32 y ) { uae_u32 result = 0; @@ -1528,6 +1523,7 @@ uae_u32 DX_MoveCursor( uae_u32 x, uae_u32 y ) result = 1; return result; } +#endif static void open_screen( void ) { @@ -1922,9 +1918,9 @@ static BOOL doInit (void) if (currentmode->current_depth < 15 && (currprefs.chipset_mask & CSMASK_AGA) && isfullscreen () && !WIN32GFX_IsPicassoScreen()) { static int warned; if (!warned) { - char szMessage[ MAX_DPATH ]; + char szMessage[MAX_DPATH]; currentmode->current_depth = 16; - WIN32GUI_LoadUIString( IDS_AGA8BIT, szMessage, MAX_DPATH ); + WIN32GUI_LoadUIString(IDS_AGA8BIT, szMessage, MAX_DPATH); gui_message(szMessage); } warned = 1; diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 7364d6b1..fbacf197 100755 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -284,7 +284,11 @@ static HWND cachedlist = NULL; #define MIN_SLOW_MEM 0 #define MAX_SLOW_MEM 4 #define MIN_Z3_MEM 0 +#if defined(WIN64) +#define MAX_Z3_MEM 12 +#else #define MAX_Z3_MEM 10 +#endif #define MIN_P96_MEM 0 #define MAX_P96_MEM 6 #define MIN_M68K_PRIORITY 1 @@ -503,7 +507,7 @@ end: static int scan_roms_2 (char *pathp) { HKEY fkey = NULL; - char buf[MAX_PATH], path[MAX_PATH]; + char buf[MAX_DPATH], path[MAX_DPATH]; WIN32_FIND_DATA find_data; HANDLE handle; uae_u8 *keybuf; @@ -530,7 +534,7 @@ static int scan_roms_2 (char *pathp) if (handle == INVALID_HANDLE_VALUE) goto end; for (;;) { - char tmppath[MAX_PATH]; + char tmppath[MAX_DPATH]; strcpy (tmppath, path); strcat (tmppath, find_data.cFileName); if (find_data.nFileSizeLow < 10000000 && scan_rom (tmppath, fkey, keybuf, keysize)) @@ -815,6 +819,7 @@ int DirectorySelection(HWND hDlg, int flag, char *path) // flag = 14 for loading filesystem int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs, char *path_out, int *multi) { + static int statefile_previousfilter; OPENFILENAME openFileName; char full_path[MAX_DPATH] = ""; char full_path2[MAX_DPATH]; @@ -826,6 +831,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs char *p, *nextp; int all = 1; int next; + int filterindex = 0; char szTitle[MAX_DPATH]; char szFormat[MAX_DPATH]; @@ -962,6 +968,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs p += strlen(p) + 1; *p = 0; all = 0; + filterindex = statefile_previousfilter; } openFileName.lpstrTitle = szTitle; openFileName.lpstrDefExt = "USS"; @@ -1016,7 +1023,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; openFileName.lpstrCustomFilter = NULL; openFileName.nMaxCustFilter = 0; - openFileName.nFilterIndex = 0; + openFileName.nFilterIndex = filterindex; openFileName.lpstrFile = full_path; openFileName.nMaxFile = MAX_DPATH; openFileName.lpstrFileTitle = file_name; @@ -1097,6 +1104,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs break; case IDC_DOSAVESTATE: case IDC_DOLOADSTATE: + statefile_previousfilter = openFileName.nFilterIndex; savestate_initsave (full_path, openFileName.nFilterIndex); break; case IDC_CREATE: @@ -1144,7 +1152,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs amiga_path = strstr (openFileName.lpstrFile, openFileName.lpstrFileTitle); if (amiga_path && amiga_path != openFileName.lpstrFile) { *amiga_path = 0; - if( hWinUAEKey ) + if(hWinUAEKey) RegSetValueEx(hWinUAEKey, "hdfPath", 0, REG_SZ, (CONST BYTE *)openFileName.lpstrFile, strlen(openFileName.lpstrFile) + 1); } } @@ -1938,7 +1946,7 @@ static int listview_entry_from_click (HWND list, int *column) return -1; } -static int CALLBACK InfoSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK InfoSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; @@ -2218,10 +2226,9 @@ static struct ConfigStruct *initloadsave (HWND hDlg, struct ConfigStruct *config return config; } -static BOOL CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { char *cfgfile; - int val; static int recursive; static struct ConfigStruct *config; @@ -2319,6 +2326,7 @@ static BOOL CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM break; case IDC_CONFIGLINK: if (HIWORD (wParam) == CBN_SELCHANGE || HIWORD (wParam) == CBN_KILLFOCUS) { + LRESULT val; char tmp[MAX_DPATH]; tmp[0] = 0; val = SendDlgItemMessage (hDlg, IDC_CONFIGLINK, CB_GETCURSEL, 0, 0L); @@ -2398,7 +2406,7 @@ static BOOL CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM #define MAX_CONTRIBUTORS_LENGTH 2048 -static int CALLBACK ContributorsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK ContributorsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CHARFORMAT CharFormat; char szContributors1[ MAX_CONTRIBUTORS_LENGTH ]; @@ -2578,7 +2586,7 @@ static void resetregistry (void) RegDeleteValue (hWinUAEKey, "QuickStartHostConfig"); } -static BOOL CALLBACK PathsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK PathsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive; char tmp[MAX_DPATH]; @@ -2941,9 +2949,9 @@ static void testimage (HWND hDlg, int num) } } -static BOOL CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static BOOL CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive; int ret = FALSE, i; @@ -3125,7 +3133,7 @@ static void init_aboutdlg (HWND hDlg) } } -static BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK AboutDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { @@ -3137,9 +3145,7 @@ static BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP case WM_COMMAND: if (wParam == IDC_CONTRIBUTORS) - { DisplayContributors (hDlg); - } break; case WM_SETCURSOR: return TRUE; @@ -3240,8 +3246,9 @@ static int storedrefreshrates[MAX_REFRESH_RATES + 1]; static void init_frequency_combo (HWND hDlg, int dmode) { - int i, j, freq, index, tmp; + int i, j, freq, tmp; char hz[20], hz2[20], txt[100]; + LRESULT index; i = 0; index = 0; while ((freq = DisplayModes[dmode].refresh[i]) > 0 && index < MAX_REFRESH_RATES) { @@ -3572,8 +3579,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l if (msg == WM_COMMAND && HIWORD (wParam) == CBN_SELCHANGE) { if (LOWORD (wParam) == IDC_DISPLAYSELECT) { - LONG posn; - posn = SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_GETCURSEL, 0, 0); + LRESULT posn = SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_GETCURSEL, 0, 0); if (posn != CB_ERR && posn != workprefs.gfx_display) { if (Displays[posn].disabled) posn = 0; @@ -3584,7 +3590,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l } return; } else if (LOWORD (wParam) == IDC_RESOLUTION) { - LONG posn = SendDlgItemMessage (hDlg, IDC_RESOLUTION, CB_GETCURSEL, 0, 0); + LRESULT posn = SendDlgItemMessage (hDlg, IDC_RESOLUTION, CB_GETCURSEL, 0, 0); if (posn == CB_ERR) return; workprefs.gfx_width_fs = DisplayModes[posn].res.width; @@ -3607,7 +3613,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l SetDlgItemInt (hDlg, IDC_YSIZE, workprefs.gfx_height_win, FALSE); init_frequency_combo (hDlg, posn); } else if (LOWORD (wParam) == IDC_REFRESHRATE) { - LONG posn1, posn2; + LRESULT posn1, posn2; posn1 = SendDlgItemMessage (hDlg, IDC_REFRESHRATE, CB_GETCURSEL, 0, 0); if (posn1 == CB_ERR) return; @@ -3635,7 +3641,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l static int hw3d_changed; -static BOOL CALLBACK DisplayDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK DisplayDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; HKEY hPixelFormatKey; @@ -3801,7 +3807,7 @@ static void values_from_chipsetdlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l } } -static BOOL CALLBACK ChipsetDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK ChipsetDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; @@ -3933,7 +3939,7 @@ static void fix_values_memorydlg (void) workprefs.chipset_mask |= CSMASK_ECS_AGNUS; } -static BOOL CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; @@ -3983,9 +3989,9 @@ static BOOL CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l static void addromfiles (HKEY fkey, HWND hDlg, DWORD d, char *path, uae_u8 *keybuf, int keysize, int type) { int idx, idx2; - char tmp[1000]; - char tmp2[1000]; - char seltmp[1000]; + char tmp[MAX_DPATH]; + char tmp2[MAX_DPATH]; + char seltmp[MAX_DPATH]; struct romdata *rdx; rdx = scan_single_rom (path, keybuf, keysize); @@ -4016,16 +4022,16 @@ static void addromfiles (HKEY fkey, HWND hDlg, DWORD d, char *path, uae_u8 *keyb if (seltmp[0]) SendDlgItemMessage (hDlg, d, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)seltmp); else - SetDlgItemText( hDlg, d, path); + SetDlgItemText(hDlg, d, path); } static void getromfile (HWND hDlg, DWORD d, char *path, int size) { - DWORD val = SendDlgItemMessage (hDlg, d, CB_GETCURSEL, 0, 0L); + LRESULT val = SendDlgItemMessage (hDlg, d, CB_GETCURSEL, 0, 0L); if (val == CB_ERR) { SendDlgItemMessage (hDlg, d, WM_GETTEXT, (WPARAM)size, (LPARAM)path); } else { - char tmp1[MAX_PATH], tmp2[MAX_PATH]; + char tmp1[MAX_DPATH], tmp2[MAX_DPATH]; struct romdata *rd; SendDlgItemMessage (hDlg, d, CB_GETLBTEXT, (WPARAM)val, (LPARAM)tmp1); path[0] = 0; @@ -4104,7 +4110,7 @@ static void init_kickstart (HWND hDlg) RegCloseKey (fkey); } -static BOOL CALLBACK KickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK KickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive; char tmp[MAX_DPATH]; @@ -4230,7 +4236,7 @@ static void misc_kbled (HWND hDlg, int v, int nv) static void misc_getkbled (HWND hDlg, int v, int n) { - int nv = SendDlgItemMessage(hDlg, v, CB_GETCURSEL, 0, 0L); + LRESULT nv = SendDlgItemMessage(hDlg, v, CB_GETCURSEL, 0, 0L); if (nv != CB_ERR) { workprefs.keyboard_leds[n] = nv; misc_kbled (hDlg, v, nv); @@ -4240,7 +4246,7 @@ static void misc_getkbled (HWND hDlg, int v, int n) static void misc_getpri (HWND hDlg, int v, int *n) { - int nv = SendDlgItemMessage(hDlg, v, CB_GETCURSEL, 0, 0L); + LRESULT nv = SendDlgItemMessage(hDlg, v, CB_GETCURSEL, 0, 0L); if (nv != CB_ERR) *n = nv; } @@ -4319,7 +4325,7 @@ static void values_to_miscdlg (HWND hDlg) SendDlgItemMessage( hDlg, IDC_STATE_BUFFERSIZE, WM_SETTEXT, 0, (LPARAM)txt); } -static BOOL MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { char txt[100]; @@ -4442,7 +4448,7 @@ static BOOL MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) return FALSE; } -static BOOL CALLBACK MiscDlgProc1 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK MiscDlgProc1 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_INITDIALOG) { pages[MISC1_ID] = hDlg; @@ -4454,7 +4460,7 @@ static BOOL CALLBACK MiscDlgProc1 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP return MiscDlgProc (hDlg, msg, wParam, lParam); } -static BOOL CALLBACK MiscDlgProc2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK MiscDlgProc2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_INITDIALOG) { pages[MISC2_ID] = hDlg; @@ -4669,7 +4675,7 @@ static void values_from_cpudlg (HWND hDlg) SendMessage(pages[MEMORY_ID], WM_USER, 0, 0 ); } -static BOOL CALLBACK CPUDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK CPUDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; @@ -4838,7 +4844,8 @@ static void values_to_sounddlg (HWND hDlg) int produce_sound = workprefs.produce_sound; int stereo = workprefs.sound_stereo; char txt[100], *p; - int i, idx, selected; + int i, selected; + LRESULT idx; if (workprefs.sound_maxbsiz & (workprefs.sound_maxbsiz - 1)) workprefs.sound_maxbsiz = DEFAULT_SOUND_MAXB; @@ -4967,8 +4974,8 @@ static void values_to_sounddlg (HWND hDlg) static void values_from_sounddlg (HWND hDlg) { - int idx, i; char txt[6]; + LRESULT idx; idx = SendDlgItemMessage (hDlg, IDC_SOUNDFREQ, CB_GETCURSEL, 0, 0); if (idx >= 0) { @@ -5011,17 +5018,17 @@ static void values_from_sounddlg (HWND hDlg) idx = SendDlgItemMessage (hDlg, IDC_SOUNDDRIVE, CB_GETCURSEL, 0, 0); if (idx >= 0) { - i = SendDlgItemMessage (hDlg, IDC_SOUNDDRIVESELECT, CB_GETCURSEL, 0, 0); - if (i >= 0) { - if (i > DS_BUILD_IN_SOUNDS) { - int j = i - (DS_BUILD_IN_SOUNDS + 1); + LRESULT res = SendDlgItemMessage (hDlg, IDC_SOUNDDRIVESELECT, CB_GETCURSEL, 0, 0); + if (res >= 0) { + if (res > DS_BUILD_IN_SOUNDS) { + int j = res - (DS_BUILD_IN_SOUNDS + 1); char *p = drivesounds; while (j-- > 0) p += strlen (p) + 1; workprefs.dfxclick[idx] = -1; strcpy (workprefs.dfxclickexternal[idx], p); } else { - workprefs.dfxclick[idx] = i; + workprefs.dfxclick[idx] = res; workprefs.dfxclickexternal[idx][0] = 0; } } @@ -5030,7 +5037,7 @@ static void values_from_sounddlg (HWND hDlg) extern int sound_calibrate (HWND, struct uae_prefs*); -static BOOL CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; int numdevs; @@ -5130,7 +5137,7 @@ struct hfdlg_vals static struct hfdlg_vals empty_hfdlg = { "", "", "", "", 32, 2, 1, 0, 512, 1, 0, 0 }; static struct hfdlg_vals current_hfdlg; -static int CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; BROWSEINFO browse_info; @@ -5269,10 +5276,10 @@ static void hardfile_testrdb (HWND hDlg) sethardfile (hDlg); } -static int CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; - int i; + LRESULT res; switch (msg) { case WM_INITDIALOG: @@ -5293,24 +5300,24 @@ static int CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LP EnableWindow (GetDlgItem (hDlg, IDC_HF_CREATE), CalculateHardfileSize (hDlg) > 0); break; case IDC_HF_TYPE: - i = SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_GETCURSEL, 0, 0); - sethfdostype (hDlg, i); - EnableWindow (GetDlgItem (hDlg, IDC_HF_DOSTYPE), i >= 2); + res = SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_GETCURSEL, 0, 0); + sethfdostype (hDlg, (int)res); + EnableWindow (GetDlgItem (hDlg, IDC_HF_DOSTYPE), res >= 2); break; case IDC_HF_CREATE: { UINT setting = CalculateHardfileSize (hDlg); char dostype[16]; GetDlgItemText (hDlg, IDC_HF_DOSTYPE, dostype, sizeof (dostype)); - i = SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_GETCURSEL, 0, 0); - if (i == 0) + res = SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_GETCURSEL, 0, 0); + if (res == 0) dostype[0] = 0; if (!CreateHardFile(hDlg, setting, dostype)) { char szMessage[MAX_DPATH]; char szTitle[MAX_DPATH]; WIN32GUI_LoadUIString (IDS_FAILEDHARDFILECREATION, szMessage, MAX_DPATH); WIN32GUI_LoadUIString (IDS_CREATIONERROR, szTitle, MAX_DPATH); - MessageBox( hDlg, szMessage, szTitle, + MessageBox(hDlg, szMessage, szTitle, MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND); } } @@ -5324,10 +5331,10 @@ static int CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LP DiskSelection (hDlg, IDC_PATH_FILESYS, 12, &workprefs, 0); break; case IDOK: - if( strlen( current_hfdlg.filename ) == 0 ) + if( strlen(current_hfdlg.filename) == 0 ) { - char szMessage[ MAX_DPATH ]; - char szTitle[ MAX_DPATH ]; + char szMessage[MAX_DPATH]; + char szTitle[MAX_DPATH]; WIN32GUI_LoadUIString( IDS_MUSTSELECTFILE, szMessage, MAX_DPATH ); WIN32GUI_LoadUIString( IDS_SETTINGSERROR, szTitle, MAX_DPATH ); @@ -5369,10 +5376,11 @@ static int CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LP return FALSE; } -static int CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; - int i, posn, index; + int i, index; + LRESULT posn; switch (msg) { case WM_INITDIALOG: @@ -5408,7 +5416,7 @@ static int CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, L posn = SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_GETCURSEL, 0, 0); if (posn != CB_ERR) - strcpy (current_hfdlg.filename, hdf_getnameharddrive (posn, 0)); + strcpy (current_hfdlg.filename, hdf_getnameharddrive ((int)posn, 0)); current_hfdlg.rw = IsDlgButtonChecked (hDlg, IDC_RW); recursive--; break; @@ -5665,7 +5673,7 @@ static void hilitehd (void) ListView_SetItemState( cachedlist, clicked_entry, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED ); } -static BOOL CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { @@ -5906,17 +5914,17 @@ static void addfloppytype (HWND hDlg, int n) static void getfloppytype (HWND hDlg, int n) { int f_type = floppybuttons[n][3]; - int val = SendDlgItemMessage (hDlg, f_type, CB_GETCURSEL, 0, 0L); + LRESULT val = SendDlgItemMessage (hDlg, f_type, CB_GETCURSEL, 0, 0L); if (val != CB_ERR && workprefs.dfxtype[n] != val - 1) { - workprefs.dfxtype[n] = val - 1; + workprefs.dfxtype[n] = (int)val - 1; addfloppytype (hDlg, n); } } static int getfloppybox (HWND hDlg, int f_text, char *out, int maxlen) { - int val; + LRESULT val; out[0] = 0; val = SendDlgItemMessage (hDlg, f_text, CB_GETCURSEL, 0, 0L); @@ -5981,7 +5989,7 @@ static void diskselect (HWND hDlg, WPARAM wParam, struct uae_prefs *p, int drv) addfloppytype (hDlg, drv); } -static BOOL CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; int i; @@ -6152,7 +6160,7 @@ static BOOL CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l break; case WM_HSCROLL: - workprefs.floppy_speed = SendMessage (GetDlgItem (hDlg, IDC_FLOPPYSPD), TBM_GETPOS, 0, 0); + workprefs.floppy_speed = (int)SendMessage (GetDlgItem (hDlg, IDC_FLOPPYSPD), TBM_GETPOS, 0, 0); if (workprefs.floppy_speed > 0) { workprefs.floppy_speed--; workprefs.floppy_speed = 1 << workprefs.floppy_speed; @@ -6207,7 +6215,7 @@ static void addswapperfile (HWND hDlg, int entry) } } -static BOOL CALLBACK SwapperDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK SwapperDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; static int entry; @@ -6555,15 +6563,15 @@ static void values_from_portsdlg (HWND hDlg) int *port = i == 0 ? &workprefs.jport0 : &workprefs.jport1; int prevport = *port; int id = i == 0 ? IDC_PORT0_JOYS : IDC_PORT1_JOYS; - int v = SendDlgItemMessage (hDlg, id, CB_GETCURSEL, 0, 0L); + LRESULT v = SendDlgItemMessage (hDlg, id, CB_GETCURSEL, 0, 0L); if (v != CB_ERR && v > 0) { v--; if (v < JSEM_LASTKBD) - *port = JSEM_KBDLAYOUT + v; + *port = JSEM_KBDLAYOUT + (int)v; else if (v >= JSEM_LASTKBD + inputdevice_get_device_total (IDTYPE_JOYSTICK)) - *port = JSEM_MICE + v - inputdevice_get_device_total (IDTYPE_JOYSTICK) - JSEM_LASTKBD; + *port = JSEM_MICE + (int)v - inputdevice_get_device_total (IDTYPE_JOYSTICK) - JSEM_LASTKBD; else - *port = JSEM_JOYS + v - JSEM_LASTKBD; + *port = JSEM_JOYS + (int)v - JSEM_LASTKBD; } if (*port != prevport) { lastside = i; @@ -6608,7 +6616,7 @@ static void values_from_portsdlg (HWND hDlg) #endif } - workprefs.win32_midioutdev = SendDlgItemMessage( hDlg, IDC_MIDIOUTLIST, CB_GETCURSEL, 0, 0 ); + workprefs.win32_midioutdev = (int)SendDlgItemMessage( hDlg, IDC_MIDIOUTLIST, CB_GETCURSEL, 0, 0 ); workprefs.win32_midioutdev -= 2; if( bNoMidiIn ) @@ -6617,7 +6625,7 @@ static void values_from_portsdlg (HWND hDlg) } else { - workprefs.win32_midiindev = SendDlgItemMessage( hDlg, IDC_MIDIINLIST, CB_GETCURSEL, 0, 0 ); + workprefs.win32_midiindev = (int)SendDlgItemMessage( hDlg, IDC_MIDIINLIST, CB_GETCURSEL, 0, 0 ); } EnableWindow( GetDlgItem( hDlg, IDC_MIDIINLIST ), workprefs.win32_midioutdev < -1 ? FALSE : TRUE); @@ -6650,7 +6658,7 @@ static void values_from_portsdlg (HWND hDlg) workprefs.serial_direct = 0; if (IsDlgButtonChecked (hDlg, IDC_SERIAL_DIRECT)) workprefs.serial_direct = 1; - GetDlgItemText (hDlg, IDC_PS_PARAMS, workprefs.ghostscript_parameters, 256); + GetDlgItemText (hDlg, IDC_PS_PARAMS, workprefs.ghostscript_parameters, sizeof workprefs.ghostscript_parameters); v = GetDlgItemInt (hDlg, IDC_PRINTERAUTOFLUSH, &success, FALSE); if (success) workprefs.parallel_autoflush_time = v; @@ -6659,7 +6667,7 @@ static void values_from_portsdlg (HWND hDlg) static void values_to_portsdlg (HWND hDlg) { - LONG result = 0; + LRESULT result = 0; if( strcmp (workprefs.prtname, "none")) { @@ -6713,10 +6721,11 @@ static void values_to_portsdlg (HWND hDlg) else { int t = (workprefs.sername[0] == '\0' ? 0 : workprefs.sername[3] - '0'); - int i, result = -1; + int i; + LRESULT result = -1; for (i = 0; i < MAX_SERIALS; i++) { if (!strcmp (comports[i], workprefs.sername)) { - result = SendDlgItemMessage( hDlg, IDC_SERIAL, CB_SETCURSEL, i + 1, 0L ); + result = SendDlgItemMessage(hDlg, IDC_SERIAL, CB_SETCURSEL, i + 1, 0L); break; } } @@ -6853,7 +6862,7 @@ static void init_portsdlg( HWND hDlg ) } /* Handle messages for the Joystick Settings page of our property-sheet */ -static BOOL CALLBACK PortsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK PortsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; int temp; @@ -7034,8 +7043,9 @@ static void clearinputlistview (HWND hDlg) static void values_from_inputdlg (HWND hDlg) { - int item, doselect = 0, v; + int doselect = 0, v; BOOL success; + LRESULT item; v = GetDlgItemInt( hDlg, IDC_INPUTDEADZONE, &success, FALSE ); if (success) { @@ -7057,7 +7067,7 @@ static void values_from_inputdlg (HWND hDlg) item = SendDlgItemMessage( hDlg, IDC_INPUTAMIGACNT, CB_GETCURSEL, 0, 0L ); if (item != CB_ERR && input_selected_sub_num != item) { - input_selected_sub_num = item; + input_selected_sub_num = (int)item; doselect = 0; init_inputdlg_2 (hDlg); update_listview_input (hDlg); @@ -7065,9 +7075,9 @@ static void values_from_inputdlg (HWND hDlg) } item = SendDlgItemMessage( hDlg, IDC_INPUTTYPE, CB_GETCURSEL, 0, 0L ); - if( item != CB_ERR ) { + if(item != CB_ERR) { if (item != workprefs.input_selected_setting) { - workprefs.input_selected_setting = item; + workprefs.input_selected_setting = (int)item; input_selected_widget = -1; inputdevice_updateconfig (&workprefs); enable_for_inputdlg( hDlg ); @@ -7076,9 +7086,9 @@ static void values_from_inputdlg (HWND hDlg) } } item = SendDlgItemMessage( hDlg, IDC_INPUTDEVICE, CB_GETCURSEL, 0, 0L ); - if( item != CB_ERR ) { + if(item != CB_ERR) { if (item != input_selected_device) { - input_selected_device = item; + input_selected_device = (int)item; input_selected_widget = -1; input_selected_event = -1; InitializeListView (hDlg); @@ -7088,8 +7098,8 @@ static void values_from_inputdlg (HWND hDlg) } } item = SendDlgItemMessage( hDlg, IDC_INPUTAMIGA, CB_GETCURSEL, 0, 0L ); - if( item != CB_ERR) { - input_selected_event = item; + if(item != CB_ERR) { + input_selected_event = (int)item; doselect = 1; } @@ -7114,10 +7124,10 @@ static void input_swap (HWND hDlg) static void input_copy (HWND hDlg) { int dst = workprefs.input_selected_setting; - int src = SendDlgItemMessage( hDlg, IDC_INPUTCOPYFROM, CB_GETCURSEL, 0, 0L ); + LRESULT src = SendDlgItemMessage( hDlg, IDC_INPUTCOPYFROM, CB_GETCURSEL, 0, 0L ); if (src == CB_ERR) return; - inputdevice_copy_single_config (&workprefs, src, workprefs.input_selected_setting, input_selected_device); + inputdevice_copy_single_config (&workprefs, (int)src, workprefs.input_selected_setting, input_selected_device); init_inputdlg (hDlg); } @@ -7137,7 +7147,7 @@ static void input_toggleautofire (void) name, custom, af, input_selected_sub_num); } -static BOOL CALLBACK InputDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK InputDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { char name_buf[MAX_DPATH] = "", desc_buf[128] = ""; char *posn = NULL; @@ -7418,11 +7428,12 @@ static void values_from_hw3ddlg (HWND hDlg) static void filter_preset (HWND hDlg, WPARAM wParam) { - int item, ok, err, load; + int ok, err, load; char tmp1[MAX_DPATH], tmp2[MAX_DPATH]; DWORD outsize; HKEY fkey; struct uae_prefs *p = &workprefs; + LRESULT item; load = 0; ok = 0; @@ -7435,7 +7446,7 @@ static void filter_preset (HWND hDlg, WPARAM wParam) item = SendDlgItemMessage (hDlg, IDC_FILTERPRESETS, CB_GETCURSEL, 0, 0); tmp1[0] = 0; if (item != CB_ERR) { - filterpreset = item; + filterpreset = (int)item; SendDlgItemMessage (hDlg, IDC_FILTERPRESETS, CB_GETLBTEXT, (WPARAM)item, (LPARAM)tmp1); } else { SendDlgItemMessage (hDlg, IDC_FILTERPRESETS, WM_GETTEXT, (WPARAM)item, (LPARAM)tmp1); @@ -7522,7 +7533,7 @@ static void filter_handle (HWND hDlg) workprefs.gfx_filter = uaefilters[item].type; item = SendDlgItemMessage (hDlg, IDC_FILTERFILTER, CB_GETCURSEL, 0, 0L); if (item != CB_ERR) - workprefs.gfx_filter_filtermode = item; + workprefs.gfx_filter_filtermode = (int)item; if (of != workprefs.gfx_filter || off != workprefs.gfx_filter_filtermode) { values_to_hw3ddlg (hDlg); hw3d_changed = 1; @@ -7533,10 +7544,10 @@ static void filter_handle (HWND hDlg) updatedisplayarea (); } -static BOOL CALLBACK hw3dDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK hw3dDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive; - int item; + LRESULT item; switch (msg) { @@ -7599,12 +7610,12 @@ static BOOL CALLBACK hw3dDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPar recursive--; break; case WM_HSCROLL: - currprefs.gfx_filter_horiz_zoom = workprefs.gfx_filter_horiz_zoom = SendMessage( GetDlgItem( hDlg, IDC_FILTERHZ ), TBM_GETPOS, 0, 0 ); - currprefs.gfx_filter_vert_zoom = workprefs.gfx_filter_vert_zoom = SendMessage( GetDlgItem( hDlg, IDC_FILTERVZ ), TBM_GETPOS, 0, 0 ); - currprefs.gfx_filter_horiz_offset = workprefs.gfx_filter_horiz_offset = SendMessage( GetDlgItem( hDlg, IDC_FILTERHO ), TBM_GETPOS, 0, 0 ); - currprefs.gfx_filter_vert_offset = workprefs.gfx_filter_vert_offset = SendMessage( GetDlgItem( hDlg, IDC_FILTERVO ), TBM_GETPOS, 0, 0 ); - currprefs.gfx_filter_scanlines = workprefs.gfx_filter_scanlines = SendMessage( GetDlgItem( hDlg, IDC_FILTERSL ), TBM_GETPOS, 0, 0 ); - currprefs.gfx_filter_scanlinelevel = workprefs.gfx_filter_scanlinelevel = SendMessage( GetDlgItem( hDlg, IDC_FILTERSL2 ), TBM_GETPOS, 0, 0 ); + currprefs.gfx_filter_horiz_zoom = workprefs.gfx_filter_horiz_zoom = (int)SendMessage( GetDlgItem( hDlg, IDC_FILTERHZ ), TBM_GETPOS, 0, 0 ); + currprefs.gfx_filter_vert_zoom = workprefs.gfx_filter_vert_zoom = (int)SendMessage( GetDlgItem( hDlg, IDC_FILTERVZ ), TBM_GETPOS, 0, 0 ); + currprefs.gfx_filter_horiz_offset = workprefs.gfx_filter_horiz_offset = (int)SendMessage( GetDlgItem( hDlg, IDC_FILTERHO ), TBM_GETPOS, 0, 0 ); + currprefs.gfx_filter_vert_offset = workprefs.gfx_filter_vert_offset = (int)SendMessage( GetDlgItem( hDlg, IDC_FILTERVO ), TBM_GETPOS, 0, 0 ); + currprefs.gfx_filter_scanlines = workprefs.gfx_filter_scanlines = (int)SendMessage( GetDlgItem( hDlg, IDC_FILTERSL ), TBM_GETPOS, 0, 0 ); + currprefs.gfx_filter_scanlinelevel = workprefs.gfx_filter_scanlinelevel = (int)SendMessage( GetDlgItem( hDlg, IDC_FILTERSL2 ), TBM_GETPOS, 0, 0 ); SetDlgItemInt (hDlg, IDC_FILTERHZV, workprefs.gfx_filter_horiz_zoom, TRUE); SetDlgItemInt (hDlg, IDC_FILTERVZV, workprefs.gfx_filter_vert_zoom, TRUE); SetDlgItemInt (hDlg, IDC_FILTERHOV, workprefs.gfx_filter_horiz_offset, TRUE); @@ -7656,14 +7667,14 @@ static void values_to_avioutputdlg(HWND hDlg) static void values_from_avioutputdlg(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - int tmp; + LRESULT tmp; updatewinfsmode (&workprefs); tmp = SendMessage(GetDlgItem(hDlg, IDC_AVIOUTPUT_FPS), TBM_GETPOS, 0, 0); if (tmp < 1) tmp = 1; if (tmp != avioutput_fps) { - avioutput_fps = tmp; + avioutput_fps = (int)tmp; AVIOutput_Restart (); } avioutput_framelimiter = IsDlgButtonChecked (hDlg, IDC_AVIOUTPUT_FRAMELIMITER) ? 0 : 1; @@ -7716,7 +7727,7 @@ static void enable_for_avioutputdlg(HWND hDlg) EnableWindow(GetDlgItem(hDlg, IDC_AVIOUTPUT_ACTIVATED), (!avioutput_audio && !avioutput_video) ? FALSE : TRUE); } -static BOOL CALLBACK AVIOutputDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK AVIOutputDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; @@ -7922,7 +7933,7 @@ static int GetPanelRect (HWND hDlg, RECT *r) static int ToolTipImageIDs[] = { 1, IDB_XARCADE, -1 }; static WNDPROC ToolTipWndProcOld; -static long FAR PASCAL ToolTipWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +static LRESULT FAR PASCAL ToolTipWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT r1; POINT p1; @@ -7975,7 +7986,7 @@ static BOOL CALLBACK childenumproc (HWND hwnd, LPARAM lParam) TOOLINFO ti; char tmp[MAX_DPATH]; char *p; - int v; + LRESULT v; tmp[0] = 0; SendMessage (hwnd, WM_GETTEXT, (WPARAM)sizeof (tmp), (LPARAM)tmp); @@ -8013,9 +8024,9 @@ static BOOL CALLBACK childenumproc (HWND hwnd, LPARAM lParam) panelDlg, NULL, hInst, NULL); ToolTipHWNDS2[idx].hwnd = ToolTipHWND2; ToolTipHWNDS2[idx+1].hwnd = NULL; - ToolTipHWNDS2[idx].proc = (WNDPROC)GetWindowLongPtr (ToolTipHWND2, GWL_WNDPROC); + ToolTipHWNDS2[idx].proc = (WNDPROC)GetWindowLongPtr (ToolTipHWND2, GWLP_WNDPROC); ToolTipHWNDS2[idx].imageid = ToolTipImageIDs[i + 1]; - SetWindowLongPtr (ToolTipHWND2, GWL_WNDPROC, (LONG_PTR)ToolTipWndProc); + SetWindowLongPtr (ToolTipHWND2, GWLP_WNDPROC, (LONG_PTR)ToolTipWndProc); SetWindowPos (ToolTipHWND2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); SendMessage(ToolTipHWND2, TTM_SETDELAYTIME, (WPARAM)TTDT_AUTOPOP, (LPARAM)MAKELONG(20000, 0)); @@ -8396,7 +8407,7 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage) } static int dialogreturn; -static BOOL CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; @@ -8440,8 +8451,8 @@ static BOOL CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPara case TVN_SELCHANGED: { LPNMTREEVIEW tv = (LPNMTREEVIEW)lParam; - currentpage = tv->itemNew.lParam & 0xffff; - configtypepanel = configtype = tv->itemNew.lParam >> 16; + currentpage = (int)(tv->itemNew.lParam & 0xffff); + configtypepanel = configtype = (int)(tv->itemNew.lParam >> 16); updatePanel (hDlg, currentpage); return TRUE; } @@ -8492,7 +8503,7 @@ static ACCEL EmptyAccel[] = { }; static int init_page (int tmpl, int icon, int title, - BOOL (CALLBACK FAR *func) (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam), ACCEL *accels, char *help) + INT_PTR (CALLBACK FAR *func) (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam), ACCEL *accels, char *help) { static id = 0; int i = -1; diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index 10aa4cec..e320ee0c 100755 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -10,6 +10,9 @@ + @@ -81,7 +84,110 @@ + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -897,418 +1614,6266 @@ Name="rips" > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + @@ -1352,23 +7933,15 @@ /> - - - - + + + + + + @@ -1412,7 +8001,39 @@ /> + + + + + + + + + + + + - - - - + + + @@ -1448,7 +8069,39 @@ /> + + + + + + + + + + + + + + + @@ -1476,7 +8137,39 @@ /> + + + + + + + + + + + + + + + @@ -1504,7 +8205,39 @@ /> + + + + + + + + + + + + - - + + + @@ -1536,7 +8273,39 @@ /> + + + + + + + + + + + + - - + + + + + + - - + + - - - - + + - - - - - - + + - - - - - - - - + + + + - - - - + + + + + + - - + + + + + + - - + + + - - - - - - - - - - - - - - - - - + + - - - - - - + + - - - - - - - - + + - - - - - - + + - - - - - - - - - - + + - - - - - - + + - - - - + + + + + + - - - - + + - - - - - - + + + + - - - - - - - - + + - - + + + - - - - - - + + - - - - - - + + - - - - - - - - + + - - - - - - + + - - - - + + + - - - - + + - - - - - - - - + + - - - - - - - - + + - - - - - - - - - - + + - - - - - - + + - - - - - - - - + + - - - - - - + + - - - - - - - - - - - - - - - - + + - - - - - - + + - - - - - - - - + + - - - - - - + + - - - - - - - - + + - - - - - - + + - - - - - - - - + + - - - - - - + + - - - - - - - - - - - - - - - diff --git a/prowizard/include/extern.h b/prowizard/include/extern.h index a6866f83..d72b5cca 100755 --- a/prowizard/include/extern.h +++ b/prowizard/include/extern.h @@ -290,7 +290,7 @@ extern short testSpecialCruncherData ( long , long ); extern void Rip_SpecialCruncherData ( char * , int , int ); extern short test_1_start ( Ulong ); extern short test_smps ( long, long, long, Uchar, Uchar ); -extern long GetFileSize ( char * ); +extern long GetFileSizeX ( char * ); /* globals */ /* Some say it's badly coding when using Globals ... sure it is, now what's the solution ? */ diff --git a/prowizard/misc/misc.c b/prowizard/misc/misc.c index d05fc605..6165c1ac 100755 --- a/prowizard/misc/misc.c +++ b/prowizard/misc/misc.c @@ -31,7 +31,7 @@ void Support_Types ( void ) } /* get "_TYPES_" size */ - types_file_size = GetFileSize ( _TYPES_FILENAME ); + types_file_size = GetFileSizeX ( _TYPES_FILENAME ); fseek ( types_file , 0 , 0 ); /* just to be sure. put the fp back at the beginning */ PW_i = 0; /* will inc up to _KNOWN_FORMATS */ @@ -399,7 +399,7 @@ void Rip_SpecialCruncherData ( char *Packer_Name , int Header_Size , int Packer_ } /* yet again on Xigh's suggestion. How to handle 'correctly' a file size */ -long GetFileSize (char *infile) +long GetFileSizeX (char *infile) { long i; struct stat *Stat; diff --git a/scsidev.c b/scsidev.c index 7840d9cf..c38783d5 100755 --- a/scsidev.c +++ b/scsidev.c @@ -50,7 +50,7 @@ static int scsierr(SCSI *scgp) if(cp->error != SCG_NO_ERROR || cp->ux_errno != 0 || *(u_char *)&cp->scb != 0) - return -1; + return -1; return 0; } @@ -69,11 +69,11 @@ static int inquiry (SCSI *scgp, void *bp, int cnt) scmd->cdb.g0_cdb.cmd = SC_INQUIRY; scmd->cdb.g0_cdb.lun = scgp->lun; scmd->cdb.g0_cdb.count = cnt; - + scgp->cmdname = "inquiry"; if (scsicmd(scgp) < 0) - return (-1); + return (-1); return (0); } @@ -83,7 +83,7 @@ static void print_product(struct scsi_inquiry *ip) write_log ("'%.16s' ", ip->ident); write_log ("'%.4s' ", ip->revision); if (ip->add_len < 31) { - write_log ("NON CCS "); + write_log ("NON CCS "); } } @@ -99,7 +99,7 @@ static SCSI *openscsi (int scsibus, int target, int lun) { SCSI *scgp = scsi_smalloc (); if (!scgp) { - return NULL; + return NULL; } scgp->debug = getenvint ("UAE_SCSI_DEBUG", 0); @@ -111,11 +111,11 @@ static SCSI *openscsi (int scsibus, int target, int lun) scgp->lun = lun; if (!scsi_open(scgp, NULL, scsibus, target, lun)) { - scsi_sfree (scgp); - return NULL; + scsi_sfree (scgp); + return NULL; } else { - return scgp; - } + return scgp; + } } static void closescsi (SCSI *scgp) @@ -160,9 +160,9 @@ static struct scsidevdata *get_scsidev_data (int unit) int i; for (i = 0; i < num_drives; i++) { - if (unit == drives[i].aunit) { - return &drives[i]; - } + if (unit == drives[i].aunit) { + return &drives[i]; + } } return NULL; } @@ -170,21 +170,21 @@ static struct scsidevdata *get_scsidev_data (int unit) static struct scsidevdata *add_scsidev_data (int bus, int target, int lun, int aunit) { if (num_drives + 1 < MAX_DRIVES) { - memset(&drives[num_drives], 0, sizeof(drives[num_drives])); - drives[num_drives].bus = bus; - drives[num_drives].target = target; - drives[num_drives].lun = lun; - drives[num_drives].aunit = aunit; + memset(&drives[num_drives], 0, sizeof(drives[num_drives])); + drives[num_drives].bus = bus; + drives[num_drives].target = target; + drives[num_drives].lun = lun; + drives[num_drives].aunit = aunit; #if !defined(UAE_SCSIDEV_THREADS) - drives[num_drives].scgp = scgp; - drives[num_drives].max_dma = scsi_bufsize (scgp, 512 * 1024); + drives[num_drives].scgp = scgp; + drives[num_drives].max_dma = scsi_bufsize (scgp, 512 * 1024); #endif - /* check if this drive is an ATAPI drive */ - scgp->scsibus = bus; - scgp->target = target; - scgp->lun = lun; - drives[num_drives].isatapi = scsi_isatapi (scgp); - return &drives[num_drives++]; + /* check if this drive is an ATAPI drive */ + scgp->scsibus = bus; + scgp->target = target; + scgp->lun = lun; + drives[num_drives].isatapi = scsi_isatapi (scgp); + return &drives[num_drives++]; } return NULL; @@ -195,7 +195,7 @@ static int start_thread (struct scsidevdata *sdd) { #ifdef UAE_SCSIDEV_THREADS if (sdd->thread_running) - return 1; + return 1; init_comm_pipe (&sdd->requests, 10, 1); uae_sem_init (&sdd->sync_sem, 0, 0); uae_start_thread (scsidev_thread, sdd, &sdd->tid); @@ -205,7 +205,7 @@ static int start_thread (struct scsidevdata *sdd) return 1; #endif } - + /************* Exec device functions ****************/ @@ -221,7 +221,7 @@ static uae_u32 scsidev_open (void) /* Check unit number */ if ((sdd = get_scsidev_data (unit)) && - start_thread (sdd)) { + start_thread (sdd)) { opencount++; put_word (m68k_areg(regs, 6)+32, get_word (m68k_areg(regs, 6)+32) + 1); put_long (tmp1 + 24, unit); /* io_Unit */ @@ -281,8 +281,8 @@ static LONG TestNegativeTime(LONG block) -150 == 100:00:00 = 00:00:00 */ if (block > (97 * 60 * 75)) { - /* must be a negative block */ - block -= 100 * 60 * 75; + /* must be a negative block */ + block -= 100 * 60 * 75; } return block; } @@ -322,9 +322,9 @@ static void scsidev_do_scsi (struct scsidevdata *sdd, uaecptr request) /* do transfer directly to and from Amiga memory */ if (!bank_data || !bank_data->check (scsi_data, scsi_len) || - !bank_cmd || !bank_cmd->check (scsi_cmd, scsi_cmd_len)) { - put_byte (request + 31, (uae_u8)-5); /* IOERR_BADADDRESS */ - return; + !bank_cmd || !bank_cmd->check (scsi_cmd, scsi_cmd_len)) { + put_byte (request + 31, (uae_u8)-5); /* IOERR_BADADDRESS */ + return; } #ifdef SCSI_IS_NOT_THREAD_SAFE @@ -339,46 +339,46 @@ static void scsidev_do_scsi (struct scsidevdata *sdd, uaecptr request) memcpy(&scmd->cdb, bank_cmd->xlateaddr (scsi_cmd), scsi_cmd_len); scmd->target = sdd->target; scmd->sense_len = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */ - (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */ - -1; + (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */ + -1; scmd->sense_count = 0; *(uae_u8 *)&scmd->scb = 0; #ifdef DEBUG_CDR /* please ignore this code - it can be used to debug raw CD-R writing... */ if (!(scsi_len % 2368)) { - /* Structure for generating bytes 2353...2368 if writing in ultra raw mode */ - typedef struct QDATAtag { - BYTE ControlAdr; - BCD Tno; - BCD Point; - BCD Min; - BCD Sec; - BCD Frame; - BYTE Zero; - BCD PMin; - BCD PSec; - BCD PFrame; - WORD Crc; - BYTE Reserved[3]; - BYTE PChannel; - } QDATA; - - int i = scsi_len / 2368; - QDATA *data = (QDATA *)&((unsigned char *)scmd->addr)[2352]; - for (; i > 0; i--, data = (QDATA *)&((unsigned char *)data)[2368]) { - printf ("$%02x: $%02x $%02x | $%02x:$%02x:$%02x = %6ld | $%02x | $%02x:$%02x:$%02x = %6ld\n", - (int)data->ControlAdr, (int)*(UBYTE *)&data->Tno, (int)*(UBYTE *)&data->Point, - (int)*(UBYTE *)&data->Min, (int)*(UBYTE *)&data->Sec, (int)*(UBYTE *)&data->Frame, - BCDTime2Block_Pointer (&data->Min) + 150, - *(UBYTE *)&data->Zero, - *(UBYTE *)&data->PMin, *(UBYTE *)&data->PSec, *(UBYTE *)&data->PFrame, - BCDTime2Block_Pointer (&data->PMin)); - } - fflush (stdout); + /* Structure for generating bytes 2353...2368 if writing in ultra raw mode */ + typedef struct QDATAtag { + BYTE ControlAdr; + BCD Tno; + BCD Point; + BCD Min; + BCD Sec; + BCD Frame; + BYTE Zero; + BCD PMin; + BCD PSec; + BCD PFrame; + WORD Crc; + BYTE Reserved[3]; + BYTE PChannel; + } QDATA; + + int i = scsi_len / 2368; + QDATA *data = (QDATA *)&((unsigned char *)scmd->addr)[2352]; + for (; i > 0; i--, data = (QDATA *)&((unsigned char *)data)[2368]) { + printf ("$%02x: $%02x $%02x | $%02x:$%02x:$%02x = %6ld | $%02x | $%02x:$%02x:$%02x = %6ld\n", + (int)data->ControlAdr, (int)*(UBYTE *)&data->Tno, (int)*(UBYTE *)&data->Point, + (int)*(UBYTE *)&data->Min, (int)*(UBYTE *)&data->Sec, (int)*(UBYTE *)&data->Frame, + BCDTime2Block_Pointer (&data->Min) + 150, + *(UBYTE *)&data->Zero, + *(UBYTE *)&data->PMin, *(UBYTE *)&data->PSec, *(UBYTE *)&data->PFrame, + BCDTime2Block_Pointer (&data->PMin)); + } + fflush (stdout); } #endif - + scgp->scsibus = sdd->bus; scgp->target = sdd->target; scgp->lun = sdd->lun; @@ -388,129 +388,129 @@ static void scsidev_do_scsi (struct scsidevdata *sdd, uaecptr request) /* replace MODE_SELECT/SENSE_6 if we access a ATAPI drive, otherwise send it now */ if (sdd->isatapi && - (scmd->cdb.g0_cdb.cmd == MODE_SELECT_6 || - scmd->cdb.g0_cdb.cmd == MODE_SENSE_6)) { - uae_u8 buffer[256 + 2], *data = scmd->addr, *tmp; - int len = 0, page_len, i; - int do_it = 1; - uae_u8 sp = scmd->cdb.g0_cdb.high_addr & 1; - uae_u8 alloc_len = scmd->cdb.g0_cdb.count; - uae_u8 pcf_page_code = scmd->cdb.g0_cdb.mid_addr; - uae_u8 cmd = scmd->cdb.g0_cdb.cmd; - - memset (&scmd->cdb.g1_cdb, 0, sizeof(scmd->cdb.g1_cdb)); - if (cmd == MODE_SELECT_6) { - /* expand parameter list */ - tmp = data; - buffer[len++] = *tmp++; /* first byte, should be 0 */ - buffer[len++] = 0; /* reserved */ - buffer[len++] = *tmp++; /* medium type */ - buffer[len++] = 0; *tmp++; /* ignore host application code */ - for (i = 0; i < 4; i++) { - buffer[len++] = 0; - } - if (*tmp) { - /* skip block descriptor */ - tmp += 8; - } - tmp++; - page_len = scsi_len - (tmp - data); - if (page_len > 0) { - memcpy (&buffer[len], tmp, page_len); - len += page_len; - - scmd->cdb.g1_cdb.cmd = MODE_SELECT_10; - scmd->cdb.g1_cdb.lun = sdd->lun; - scmd->cdb.g1_cdb.res = 1 << 3; /* PF bit */ - scmd->cdb.g1_cdb.reladr = sp; - scmd->cdb.g1_cdb.count[0] = len >> 8; - scmd->cdb.g1_cdb.count[1] = len; - } else { - do_it = 0; - scmd->error = 0; - *(uae_u8 *)&scmd->scb = 0; - scmd->ux_errno = 0; - } - } else { - /* MODE_SENSE_6 */ - len = alloc_len + 2; - scmd->cdb.g1_cdb.cmd = MODE_SENSE_10; - scmd->cdb.g1_cdb.lun = sdd->lun; - scmd->cdb.g1_cdb.addr[0] = pcf_page_code; - scmd->cdb.g1_cdb.count[0] = len >> 8; - scmd->cdb.g1_cdb.count[1] = len; - } - if (do_it) { - scmd->cdb_len = 10; - scmd->addr = buffer; - scmd->size = len; - scmd->sense_count = 0; - *(uae_u8 *)&scmd->scb = 0; - - scsicmd (scgp); - - if (cmd == MODE_SENSE_6 && - !scmd->error && - !scmd->ux_errno && - !*(uae_u8 *)&scmd->scb) { - int req_len = len; - - /* compress result */ - tmp = buffer; - len = 0; - tmp++; /* skip first byte of length - should better be zero */ - data[len++] = *tmp++; /* mode data length */ - data[len++] = *tmp++; /* medium type */ - data[len++] = 0; /* host application type */ - data[len++] = 0; /* block descr length */ - tmp += 4; - if (*tmp) { - /* skip block descr - should not happen */ - tmp += *tmp; - } - tmp++; - memcpy (&data[len], tmp, req_len - (tmp - buffer)); - } - } + (scmd->cdb.g0_cdb.cmd == MODE_SELECT_6 || + scmd->cdb.g0_cdb.cmd == MODE_SENSE_6)) { + uae_u8 buffer[256 + 2], *data = scmd->addr, *tmp; + int len = 0, page_len, i; + int do_it = 1; + uae_u8 sp = scmd->cdb.g0_cdb.high_addr & 1; + uae_u8 alloc_len = scmd->cdb.g0_cdb.count; + uae_u8 pcf_page_code = scmd->cdb.g0_cdb.mid_addr; + uae_u8 cmd = scmd->cdb.g0_cdb.cmd; + + memset (&scmd->cdb.g1_cdb, 0, sizeof(scmd->cdb.g1_cdb)); + if (cmd == MODE_SELECT_6) { + /* expand parameter list */ + tmp = data; + buffer[len++] = *tmp++; /* first byte, should be 0 */ + buffer[len++] = 0; /* reserved */ + buffer[len++] = *tmp++; /* medium type */ + buffer[len++] = 0; *tmp++; /* ignore host application code */ + for (i = 0; i < 4; i++) { + buffer[len++] = 0; + } + if (*tmp) { + /* skip block descriptor */ + tmp += 8; + } + tmp++; + page_len = scsi_len - (tmp - data); + if (page_len > 0) { + memcpy (&buffer[len], tmp, page_len); + len += page_len; + + scmd->cdb.g1_cdb.cmd = MODE_SELECT_10; + scmd->cdb.g1_cdb.lun = sdd->lun; + scmd->cdb.g1_cdb.res = 1 << 3; /* PF bit */ + scmd->cdb.g1_cdb.reladr = sp; + scmd->cdb.g1_cdb.count[0] = len >> 8; + scmd->cdb.g1_cdb.count[1] = len; + } else { + do_it = 0; + scmd->error = 0; + *(uae_u8 *)&scmd->scb = 0; + scmd->ux_errno = 0; + } + } else { + /* MODE_SENSE_6 */ + len = alloc_len + 2; + scmd->cdb.g1_cdb.cmd = MODE_SENSE_10; + scmd->cdb.g1_cdb.lun = sdd->lun; + scmd->cdb.g1_cdb.addr[0] = pcf_page_code; + scmd->cdb.g1_cdb.count[0] = len >> 8; + scmd->cdb.g1_cdb.count[1] = len; + } + if (do_it) { + scmd->cdb_len = 10; + scmd->addr = buffer; + scmd->size = len; + scmd->sense_count = 0; + *(uae_u8 *)&scmd->scb = 0; + + scsicmd (scgp); + + if (cmd == MODE_SENSE_6 && + !scmd->error && + !scmd->ux_errno && + !*(uae_u8 *)&scmd->scb) { + int req_len = len; + + /* compress result */ + tmp = buffer; + len = 0; + tmp++; /* skip first byte of length - should better be zero */ + data[len++] = *tmp++; /* mode data length */ + data[len++] = *tmp++; /* medium type */ + data[len++] = 0; /* host application type */ + data[len++] = 0; /* block descr length */ + tmp += 4; + if (*tmp) { + /* skip block descr - should not happen */ + tmp += *tmp; + } + tmp++; + memcpy (&data[len], tmp, req_len - (tmp - buffer)); + } + } } else { - scsicmd (scgp); + scsicmd (scgp); } - + put_word (acmd + 18, scmd->error == SCG_FATAL ? 0 : scsi_cmd_len); /* fake scsi_CmdActual */ put_byte (acmd + 21, *(uae_u8 *)&scmd->scb); /* scsi_Status */ if (*(uae_u8 *)&scmd->scb) { - put_byte (request + 31, 45); /* HFERR_BadStatus */ - - /* copy sense? */ - for (sactual = 0; - scsi_sense && sactual < scsi_sense_len && sactual < scmd->sense_count; - sactual++) { - put_byte (scsi_sense + sactual, scmd->u_sense.cmd_sense[sactual]); - } - put_long (acmd + 8, 0); /* scsi_Actual */ + put_byte (request + 31, 45); /* HFERR_BadStatus */ + + /* copy sense? */ + for (sactual = 0; + scsi_sense && sactual < scsi_sense_len && sactual < scmd->sense_count; + sactual++) { + put_byte (scsi_sense + sactual, scmd->u_sense.cmd_sense[sactual]); + } + put_long (acmd + 8, 0); /* scsi_Actual */ } else { - int i; - - for (i = 0; i < scsi_sense_len; i++) { - put_byte (scsi_sense + i, 0); - } - sactual = 0; - - if (scmd->error != SCG_NO_ERROR || - scmd->ux_errno != 0) { - /* we might have been limited by the hosts DMA limits, - which is usually indicated by ENOMEM */ - if (scsi_len > (unsigned int)sdd->max_dma && - scmd->ux_errno == ENOMEM) { - put_byte (request + 31, (uae_u8)-4); /* IOERR_BADLENGTH */ - } else { - put_byte (request + 31, 20); /* io_Error, but not specified */ - put_long (acmd + 8, 0); /* scsi_Actual */ - } - } else { - put_byte (request + 31, 0); - put_long (acmd + 8, scsi_len - scmd->resid); /* scsi_Actual */ - } + int i; + + for (i = 0; i < scsi_sense_len; i++) { + put_byte (scsi_sense + i, 0); + } + sactual = 0; + + if (scmd->error != SCG_NO_ERROR || + scmd->ux_errno != 0) { + /* we might have been limited by the hosts DMA limits, + which is usually indicated by ENOMEM */ + if (scsi_len > (unsigned int)sdd->max_dma && + scmd->ux_errno == ENOMEM) { + put_byte (request + 31, (uae_u8)-4); /* IOERR_BADLENGTH */ + } else { + put_byte (request + 31, 20); /* io_Error, but not specified */ + put_long (acmd + 8, 0); /* scsi_Actual */ + } + } else { + put_byte (request + 31, 0); + put_long (acmd + 8, scsi_len - scmd->resid); /* scsi_Actual */ + } } put_word (acmd + 28, sactual); @@ -522,13 +522,13 @@ static void scsidev_do_scsi (struct scsidevdata *sdd, uaecptr request) static void scsidev_do_io (struct scsidevdata *sdd, uaecptr request) { uae_u32 tmp2, dataptr, offset; - + tmp2 = get_word (request+28); /* io_Command */ switch (tmp2) { case 28: - /* HD_SCSICMD */ - scsidev_do_scsi (sdd, request); - break; + /* HD_SCSICMD */ + scsidev_do_scsi (sdd, request); + break; default: /* Command not understood. */ put_byte (request+31, (uae_u8)-3); /* io_Error */ @@ -559,13 +559,13 @@ static uae_u32 scsidev_beginio (void) #ifdef UAE_SCSIDEV_THREADS { - uae_pt data; + uae_pt data; - /* clear IOF_QUICK */ - put_byte (request+30, get_byte (request+30) & ~1); - /* forward to unit thread */ - write_comm_pipe_u32 (&sdd->requests, request, 1); - return 0; + /* clear IOF_QUICK */ + put_byte (request+30, get_byte (request+30) & ~1); + /* forward to unit thread */ + write_comm_pipe_u32 (&sdd->requests, request, 1); + return 0; } #else put_byte (request+30, get_byte (request+30) & ~1); @@ -581,13 +581,13 @@ static void *scsidev_thread (void *sddv) #ifdef DEBUGME printf ("scsidev_penguin: sdd = 0x%x ready\n", sdd); -#endif +#endif /* init SCSI */ if (!(sdd->scgp = openscsi (sdd->bus, sdd->target, sdd->lun)) || - (sdd->max_dma = scsi_bufsize (sdd->scgp, 512 * 1024)) <= 0) { - sdd->thread_running = 0; - uae_sem_post (&sdd->sync_sem); - return 0; + (sdd->max_dma = scsi_bufsize (sdd->scgp, 512 * 1024)) <= 0) { + sdd->thread_running = 0; + uae_sem_post (&sdd->sync_sem); + return 0; } sdd->thread_running = 1; uae_sem_post (&sdd->sync_sem); @@ -597,21 +597,21 @@ static void *scsidev_thread (void *sddv) request = (uaecptr)read_comm_pipe_u32_blocking (&sdd->requests); #ifdef DEBUGME - printf ("scsidev_penguin: sdd = 0x%x\n", sdd); - printf ("scsidev_penguin: req = %08lx\n", (unsigned long)request); - printf ("scsidev_penguin: cmd = %d\n", (int)get_word(request+28)); + printf ("scsidev_penguin: sdd = 0x%x\n", sdd); + printf ("scsidev_penguin: req = %08lx\n", (unsigned long)request); + printf ("scsidev_penguin: cmd = %d\n", (int)get_word(request+28)); #endif - if (!request) { - printf ("scsidev_penguin: going down with 0x%x\n", sdd->sync_sem); + if (!request) { + printf ("scsidev_penguin: going down with 0x%x\n", sdd->sync_sem); /* Death message received. */ - sdd->thread_running = 0; + sdd->thread_running = 0; uae_sem_post (&sdd->sync_sem); /* Die. */ return 0; } - scsidev_do_io (sdd, request); - uae_ReplyMsg (request); + scsidev_do_io (sdd, request); + uae_ReplyMsg (request); } return 0; } @@ -628,43 +628,43 @@ static uae_u32 scsidev_init (void) #ifdef DEBUGME printf("scsidev_init()\n"); #endif - + if (scgp) { - /* we still have everything in place */ - return m68k_dreg (regs, 0); /* device base */ + /* we still have everything in place */ + return m68k_dreg (regs, 0); /* device base */ } - + /* init global SCSI */ if (!(scgp = openscsi (-1, -1, -1))) { - return 0; + return 0; } uae_sem_init (&scgp_sem, 0, 1); /* add all units we find */ for (scgp->scsibus=0; scgp->scsibus < 8; scgp->scsibus++) { - if (!scsi_havebus(scgp, scgp->scsibus)) - continue; - printf("scsibus%d:\n", scgp->scsibus); - for (scgp->target=0; scgp->target < 16; scgp->target++) { - struct scsi_inquiry inq; - scgp->lun = 0; - if (inquiry (scgp, &inq, sizeof(inq))) { - continue; - } - for (scgp->lun=0; scgp->lun < 8; scgp->lun++) { - if (!inquiry (scgp, &inq, sizeof(inq))) { - int aunit = BTL2UNIT(scgp->scsibus, scgp->target, scgp->lun); - struct scsidevdata *sdd; - - write_log (" %2.01d,%d (= %3.d): ", scgp->target, scgp->lun, aunit); - print_product (&inq); - sdd = add_scsidev_data (scgp->scsibus, scgp->target, scgp->lun, aunit); - write_log (!sdd ? " - init failed ???" : sdd->isatapi ? " - ATAPI" : " - SCSI"); - write_log ("\n"); + if (!scsi_havebus(scgp, scgp->scsibus)) + continue; + printf("scsibus%d:\n", scgp->scsibus); + for (scgp->target=0; scgp->target < 16; scgp->target++) { + struct scsi_inquiry inq; + scgp->lun = 0; + if (inquiry (scgp, &inq, sizeof(inq))) { + continue; + } + for (scgp->lun=0; scgp->lun < 8; scgp->lun++) { + if (!inquiry (scgp, &inq, sizeof(inq))) { + int aunit = BTL2UNIT(scgp->scsibus, scgp->target, scgp->lun); + struct scsidevdata *sdd; + + write_log (" %2.01d,%d (= %3.d): ", scgp->target, scgp->lun, aunit); + print_product (&inq); + sdd = add_scsidev_data (scgp->scsibus, scgp->target, scgp->lun, aunit); + write_log (!sdd ? " - init failed ???" : sdd->isatapi ? " - ATAPI" : " - SCSI"); + write_log ("\n"); } - } - } + } + } } return m68k_dreg (regs, 0); /* device base */ } @@ -709,7 +709,7 @@ void scsidev_install (void) /* initcode */ initcode = here (); calltrap (deftrap (scsidev_init)); dw (RTS); - + /* Open */ openfunc = here (); calltrap (deftrap (scsidev_open)); dw (RTS); @@ -788,25 +788,25 @@ void scsidev_reset (void) #ifdef SCSI_CLOSE #ifdef UAE_SCSIDEV_THREADS { - int i; - - for (i = 0; i < num_drives; i++) { - if (!drives[i].thread_running) { - continue; - } - write_comm_pipe_int (&drives[i].requests, 0, 1); - uae_sem_wait (&drives[i].sync_sem); - } - num_drives = 0; + int i; + + for (i = 0; i < num_drives; i++) { + if (!drives[i].thread_running) { + continue; + } + write_comm_pipe_int (&drives[i].requests, 0, 1); + uae_sem_wait (&drives[i].sync_sem); + } + num_drives = 0; } #endif - + if (scgp) { - closescsi (scgp); - scgp = NULL; + closescsi (scgp); + scgp = NULL; } #endif - + opencount = 0; } diff --git a/sdl-joystick.c b/sdl-joystick.c index a01d0aca..bece7db7 100755 --- a/sdl-joystick.c +++ b/sdl-joystick.c @@ -48,7 +48,7 @@ static void read_joy(int nr) return; } else if (isjoy (nr, 1)) { if (JSEM_ISNUMPAD (1, &currprefs) || JSEM_ISCURSOR (1, &currprefs) || JSEM_ISSOMEWHEREELSE (1, &currprefs)) - return; + return; } else return; } diff --git a/tui.c b/tui.c index f7f7d1ba..63dc123b 100755 --- a/tui.c +++ b/tui.c @@ -263,7 +263,7 @@ static void print_configuration (void) sprintf (tmp, "Picasso 96 %d MB", currprefs.gfxmem_size / 0x100000); tui_puts(tmp); } else - tui_puts ("Picasso 96 Off"); + tui_puts ("Picasso 96 Off"); y++; tui_gotoxy (OPTION_COLUMN, y++); @@ -627,7 +627,7 @@ static void OtherOptions (void) case 0: currprefs.jport0 = (currprefs.jport0 + 1) % 6; if (currprefs.jport0 == currprefs.jport1) - currprefs.jport1 = (currprefs.jport1 + 5) % 6; + currprefs.jport1 = (currprefs.jport1 + 5) % 6; break; case 1: currprefs.jport1 = (currprefs.jport1 + 1) % 6; diff --git a/uaelib.c b/uaelib.c index 2ec8328b..09c0dc1e 100755 --- a/uaelib.c +++ b/uaelib.c @@ -416,6 +416,7 @@ static uae_u32 uaelib_demux (void) case 80: return currprefs.maprom ? currprefs.maprom : 0xffffffff; case 81: return cfgfile_uaelib (ARG1, ARG2, ARG3, ARG4); case 82: return cfgfile_uaelib_modify (ARG1, ARG2, ARG3, ARG4, ARG5); + case 83: currprefs.mmkeyboard = ARG1 ? 1 : 0; return currprefs.mmkeyboard; } return 0; } @@ -426,6 +427,7 @@ static uae_u32 uaelib_demux (void) void emulib_install (void) { uaecptr a = here (); + currprefs.mmkeyboard = 0; org (RTAREA_BASE + 0xFF60); dw (0x4eb9); dw ((RTAREA_BASE >> 16) | get_word(RTAREA_BASE + 36)); diff --git a/unzip.c b/unzip.c index ee414f00..123b4fb4 100755 --- a/unzip.c +++ b/unzip.c @@ -29,7 +29,7 @@ #ifndef local # define local static #endif -/* compile with -Dlocal if your debugger can't find static symbols */ +/* compile with -Dlocal if your debugger can't find stosaatic symbols */ diff --git a/zfile.c b/zfile.c index 78bd0f0e..837374dd 100755 --- a/zfile.c +++ b/zfile.c @@ -575,6 +575,8 @@ static int zlib_test (int needzlib, int nomsg) return 1; #ifdef _WIN32 zlib = WIN32_LoadLibrary ("zlib1.dll"); + if (!zlib) + zlib = WIN32_LoadLibrary("zlib1_64.dll"); if (zlib) { pinflateInit2 = (INFLATEINIT2)GetProcAddress (zlib, "inflateInit2_"); pinflateInit = (INFLATEINIT)GetProcAddress (zlib, "inflateInit_");