From: Toni Wilen Date: Mon, 25 Jul 2005 13:30:25 +0000 (+0300) Subject: imported winuaesrc1100b5.zip X-Git-Tag: 2100~304 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=4b704f2ccf8e019ad9e0be0f7636fdf4ff85e014;p=francis%2Fwinuae.git imported winuaesrc1100b5.zip --- diff --git a/blitter.c b/blitter.c index 3bf706de..5a0c8c9e 100755 --- a/blitter.c +++ b/blitter.c @@ -37,7 +37,6 @@ 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; @@ -65,61 +64,131 @@ 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 int *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] = +/* + +Confirmed blitter ínformation by Toni Wilen +(order of channels or position of idle cycles are not confirmed) + +1=BLTCON0 channel mask +2=total cycles per blitted word +3=steals all cycles if BLTNASTY=1 (always if A-channel is enabled. this is illogical..) +4=total cycles per blitted word in fillmode +5=cycle diagram (first cycle) +6=main cycle diagram (ABCD=channels,-=idle cycle,x=idle cycle but bus allocated) + +1 234 5 6 + +F 4*4*ABC- ABCD +E 4*4*ABC- ABCx +D 3*4 AB- ABD +C 3*4 AB- ABx +B 3*3*AC- ACD +A 3*3*AC- ACx +9 2*3 A- AD +8 2*3 A- Ax +7 4 4 -BC- -BCD +6 4 4 -BC- -BC- +5 3 4 -B- -BD +4 3 4 -B- -B- +3 3 3 -C- -CD +2 3 3 -C- -C- +1 2 3 -D -D +0 2 3 -- -- + +NOTES: (BLTNASTY=1) + +- Blitter ALWAYS needs free bus cycle, even if it is running an "idle" cycle. + Exception: possible extra fill mode idle cycle.is "real" idle cycle. +- Fill mode may add one extra real idle cycle.(depends on channel mask) +- All blits with channel A enabled use all available bus cycles + (stops CPU accesses to chip RAM if BLTNASTY=1) + Can someone explain this? Why does idle cycles need bus cycles? +- idle cycles (no A-channel enabled) are not "used" by blitter, they are freely + available for CPU.. + +BLTNASTY=0 makes things even more interesting.. + +- even zero channel blits get slower if BLTNASTY=0 depending on the number of + active bitplanes. ALSO "2 cycle" blits with one real cycle and one idle cycle + have the exact same speed as zero channel blit in all situations -> only the + total number of cycles count, number of active channels does not matter. + +*/ + + +/* -1 = idle cycle and allocate bus */ + +static int blit_cycle_diagram[][10] = { { 0, 2, 0,0 }, /* 0 */ - { 0, 2, 4,0 }, /* 1 */ - { 0, 2, 3,0 }, /* 2 */ + { 0, 2, 0,4 }, /* 1 */ + { 0, 3, 0,3,0 }, /* 2 */ { 2, 3, 0,3,4, 3,0 }, /* 3 */ - { 0, 3, 2,0,0 }, /* 4 */ + { 0, 3, 0,2,0 }, /* 4 */ { 2, 3, 0,2,4, 2,0 }, /* 5 */ - { 0, 3, 2,3,0 }, /* 6 */ + { 0, 4, 0,2,3,0 }, /* 6 */ { 3, 4, 0,2,3,4, 2,3,0 }, /* 7 */ - { 0, 2, 1,0 }, /* 8 */ + { 0, 2, 1,-1 }, /* 8 */ { 2, 2, 1,4, 1,0 }, /* 9 */ - { 0, 2, 1,3 }, /* A */ + { 0, 3, 1,3,-1 }, /* A */ { 3, 3, 1,3,4, 1,3,0 }, /* B */ - { 2, 3, 0,1,2, 1,2 }, /* C */ + { 2, 3, 1,2,-1, 1,2 }, /* C */ { 3, 3, 1,2,4, 1,2,0 }, /* D */ - { 0, 3, 1,2,3 }, /* E */ + { 0, 4, 1,2,3,-1 }, /* 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] = +/* 5 = fill mode idle cycle ("real" idle cycle) */ + +static int 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 */ + { 0, 3, 0,5,0 }, /* 0 */ + { 0, 3, 3,5,4 }, /* 1 */ + { 0, 3, 0,3,0 }, /* 2 */ + { 2, 3, 3,5,4, 3,0 }, /* 3 */ + { 0, 4, 0,2,5,0 }, /* 4 */ + { 3, 4, 0,2,5,4, 2,0,0 }, /* 5 */ + { 0, 4, 2,3,5,0 }, /* 6 */ + { 3, 4, 2,3,5,4, 2,3,0 }, /* 7 */ + { 0, 3, 1,5,-1 }, /* 8 */ + { 2, 3, 1,5,4, 1,0}, /* 9 */ + { 0, 3, 1,3,5, }, /* 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 */ + { 2, 4, 1,2,5,-1, 1,2 }, /* C */ + { 3, 4, 1,2,5,4, 1,2,0 }, /* D */ + { 0, 4, 1,2,3,-1 }, /* E */ { 4, 4, 1,2,3,4, 1,2,3,0 } /* F */ }; -static uae_u8 blit_cycle_diagram_line[] = +/* + + line draw takes 4 cycles (two 2-cycle blits combined) + it also have real idle cycles and only 2 dma fetches + (read from C, write to D, but see below) + + Oddities: + + - first word is written to address pointed by BLTDPT + but all following writes go to address pointed by BLTCPT! + - BLTDMOD is ignored by blitter (BLTCMOD is used) + - state of D-channel enable bit does not matter! + - disabling A-channel freezes the content of BPLAPT + +*/ + +static int blit_cycle_diagram_line[] = { - 0, 2, 0,4,0,4 /* total guess.. */ + 0, 4, 3,5,4,5 /* guessed */ }; +static int blit_cycle_diagram_finald[] = + { 0, 2, 0,4 }; + void build_blitfilltable(void) { unsigned int d, fillmask; @@ -179,10 +248,10 @@ STATIC_INLINE int channel_state (int cycles) return blit_diag[((cycles - blit_diag[0]) % blit_diag[1]) + 2]; } -int is_bitplane_dma (int hpos); +extern 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)) + if (cycle_line[hpos] == 0 && !is_bitplane_dma (hpos)) return 1; return 0; } @@ -504,22 +573,23 @@ static void decide_blitter_line (int hpos) hpos++; if (dmaen (DMA_BLITTER)) { while (blit_last_hpos < hpos) { - int c = blit_cyclecounter % 2; + int c = channel_state (blit_cyclecounter); for (;;) { - if (blit_cyclecounter < 0) { + + if (c == 5) { blit_cyclecounter++; break; } #if 1 - if ((c == 0 || c == 1) && !canblit(blit_last_hpos)) + if (c && !canblit(blit_last_hpos)) break; #endif #if 1 - //if (c == 1) + if (c != 0) cycle_line[blit_last_hpos] |= CYCLE_BLITTER; #endif blit_cyclecounter++; - if (c == 1) { + if (c == 4) { /* believe it or not but try Cardamon or Cardamom without this.. */ if (ddat1use) bltdpt = bltcpt; @@ -742,11 +812,21 @@ void decide_blitter (int hpos) } #endif for (;;) { - if (c && !canblit (blit_last_hpos)) { + if (c == 5) { /* real idle cycle */ + blit_cyclecounter++; + break; + } + + /* all cycles need free bus, even idle cycles (except fillmode idle) */ + if (!canblit (blit_last_hpos)) { blit_misscyclecounter++; break; } - if (c == 4) { + + if (c < 0) { /* no channel but bus still needs to be allocated.. */ + cycle_line[blit_last_hpos] |= CYCLE_BLITTER; + blit_cyclecounter++; + } else if (c == 4) { if (blitter_doddma ()) { cycle_line[blit_last_hpos] |= CYCLE_BLITTER; blit_cyclecounter++; @@ -827,14 +907,10 @@ static void blit_bltset (int con) 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); @@ -888,7 +964,7 @@ void blit_modset (void) blit_modaddd = mult * blt_info.bltdmod; } -void reset_blit (int bltcon) +void reset_blit (int bltcon) { if (bltstate == BLT_done) return; @@ -897,7 +973,7 @@ void reset_blit (int bltcon) blit_modset (); } -void do_blitter (int hpos) +void do_blitter (int hpos) { int cycles; #ifdef BLITTER_DEBUG diff --git a/compemu_raw_x86.c b/compemu_raw_x86.c index 158db86c..aa331717 100755 --- a/compemu_raw_x86.c +++ b/compemu_raw_x86.c @@ -2627,15 +2627,16 @@ static void raw_init_cpu(void) /* Have CMOV support? */ have_cmov = c->x86_hwcap & (1 << 15); +#if 0 /* Can the host CPU suffer from partial register stalls? */ have_rat_stall = (c->x86_vendor == X86_VENDOR_INTEL); -#if 1 /* It appears that partial register writes are a bad idea even on AMD K7 cores, even though they are not supposed to have the dreaded rat stall. Why? Anyway, that's why we lie about it ;-) */ if (c->x86_processor == X86_PROCESSOR_ATHLON) have_rat_stall = 1; #endif + have_rat_stall = 1; /* Alignments */ if (tune_alignment) { diff --git a/custom.c b/custom.c index 9bad294c..48ba5967 100755 --- a/custom.c +++ b/custom.c @@ -3788,7 +3788,7 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) if (cycle && !s->dmacycle) return; /* Superfrog intro flashing bee fix */ - dma = hpos < plfstrt || diwstate != DIW_waiting_stop || !dmaen (DMA_BITPLANE); + dma = hpos < plfstrt || diwstate != DIW_waiting_stop; if (vpos == s->vstop || vpos == sprite_vblank_endline) { s->dmastate = 0; posctl = 1; @@ -4962,8 +4962,8 @@ int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int noget) 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 + 1 || vbstrt < value - 1) { vbstrt = value; varsync (); } break; - case 0x1CE: if (vbstop > value + 1 || vbstrt < value - 1) { vbstop = value; varsync (); } break; + case 0x1CC: if (vbstrt < value || vbstrt > value + 1) { vbstrt = value; varsync (); } break; + case 0x1CE: if (vbstop < value || vbstop > value + 1) { 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; @@ -5448,7 +5448,8 @@ STATIC_INLINE decide_fetch_ce (int hpos) STATIC_INLINE int dma_cycle(void) { - int hpos, cycles = 0, bnasty = 0; + int hpos, cycles = 0; + static int bnasty; for (;;) { int bpldma; @@ -5460,19 +5461,21 @@ STATIC_INLINE int dma_cycle(void) decide_line (hpos); decide_fetch_ce (hpos); bpldma = is_bitplane_dma (hpos); - if (cycle_line[hpos] == 0 && !bpldma) { - if (bltstate == BLT_done || bnasty >= 3) + if (bltstate != BLT_done) { + if (!blitpri && bnasty >= 3 && !cycle_line[hpos] && !bpldma) { + bnasty = 0; break; + } decide_blitter (hpos); - if (cycle_line[hpos] == 0) - break; - if (!blitpri || blit_singlechannel) - bnasty++; - } else if (bpldma && (blit_singlechannel || !blitpri)) { + bnasty++; + } else if (bpldma || cycle_line[hpos]) { bnasty++; } + if (cycle_line[hpos] == 0 && !bpldma) + break; /* bus was allocated to dma channel, wait for next cycle.. */ } + bnasty = 0; cycle_line[hpos] |= CYCLE_CPU; return cycles; } diff --git a/gencpu.c b/gencpu.c index 3181df4c..f3a0bc0e 100755 --- a/gencpu.c +++ b/gencpu.c @@ -1881,6 +1881,7 @@ static void gen_opcode (unsigned long int opcode) printf("\t\tSET_VFLG (1);\n"); printf("\t\tif (dst < 0) SET_NFLG (1);\n"); } + printf ("\t\tm68k_incpc (%d);\n", m68k_pc_offset); printf ("\t\tException (5, oldpc);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t} else {\n"); @@ -1924,6 +1925,7 @@ static void gen_opcode (unsigned long int opcode) printf("\t\tSET_VFLG (1);\n"); printf("\t\tSET_ZFLG (1);\n"); } + printf ("\t\tm68k_incpc (%d);\n", m68k_pc_offset); printf ("\t\tException (5, oldpc);\n"); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t} else {\n"); diff --git a/od-win32/ahidsound.c b/od-win32/ahidsound.c index e49f3be9..1f43db69 100755 --- a/od-win32/ahidsound.c +++ b/od-win32/ahidsound.c @@ -497,6 +497,7 @@ int ahi_open_sound (void) static void *bswap_buffer = NULL; static uae_u32 bswap_buffer_size = 0; +static double syncdivisor; uae_u32 ahi_demux (void) { @@ -701,10 +702,11 @@ uae_u32 ahi_demux (void) dllname = (char *)get_real_address ((uae_u32)dllname); result=(uae_u32) LoadLibrary(dllname); write_log("%s windows dll/alib loaded at %d (0 mean failure)\n",dllname,result); + syncdivisor = (3580000.0 * CYCLE_UNIT) / (double)syncbase; return result; } - case 101: //get dll label + case 101: //get dll label { HMODULE m; char *funcname; @@ -714,10 +716,24 @@ uae_u32 ahi_demux (void) return (uae_u32) GetProcAddress(m,funcname); } - case 102: //execute native code - return emulib_ExecuteNativeCode2 (); + case 102: //execute native code + { + uae_u32 ret; + unsigned long rate1; + double v; + rate1 = read_processor_time(); + ret = emulib_ExecuteNativeCode2 (); + rate1 = read_processor_time() - rate1; + v = syncdivisor * rate1; + if (v > 0) { + if (v > 1000000 * CYCLE_UNIT) + v = 1000000 * CYCLE_UNIT; + do_extra_cycles((unsigned long)(syncdivisor * rate1)); //compensate the time stay in native func + } + return ret; + } - case 103: //close dll + case 103: //close dll { HMODULE libaddr; libaddr = (HMODULE) m68k_dreg (regs, 1); diff --git a/od-win32/avioutput.c b/od-win32/avioutput.c index e15116cf..02938efb 100755 --- a/od-win32/avioutput.c +++ b/od-win32/avioutput.c @@ -895,7 +895,6 @@ void AVIOutput_Initialize(void) void frame_drawn(void) { double diff, skipmode; - static int frame; if (!avioutput_video || !avioutput_enabled) return; diff --git a/od-win32/win32.h b/od-win32/win32.h index d3aed571..6854b165 100755 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -22,7 +22,7 @@ extern int manual_palette_refresh_needed; extern int mouseactive, focus; extern int ignore_messages_all; #define WINUAEBETA 1 -#define WINUAEBETASTR " Beta 3" +#define WINUAEBETASTR " Beta 5" extern char start_path_exe[MAX_DPATH]; extern char start_path_data[MAX_DPATH]; diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index 61b04506..240ce533 100755 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -5,7 +5,6 @@ Name="winuae" ProjectGUID="{4ADAA943-1AC8-4FB5-82E5-4FB753B6C2DA}" RootNamespace="winuae" - SignManifests="true" >