From: <gb...@di...> - 2000-09-03 11:17:39
|
Hi, I am in the process of porting the new UAE JIT Compiler for Linux/x86. For that purpose, I need a few information and arrangements. ;-) 1. Ability to directly access the Mac address space ------------------------------------------------ For faster performance and actually simpler porting, I want BasiliskII being able to directly access the Mac address space only through one offset. i.e. as Lauri did for Windows NT: ROMBaseMac - RAMBaseMac == ROMBaseHost - RAMBaseHost VIDBaseMac - ROMBaseMac == VIDBaseHost - ROMBaseHost Implementation: the main trouble will come from the Mac Frame Buffer. (a) In order to mmap() correctly the address space in VideoInit(), I would like to know what is the current ROMBaseMac. This is currently not possible since VideoInit() is executed before Init680x0(). I am not willing to duplicate code. (b) In order to get a chance to mmap() the address space as above-mentioned, MacRAM would not get allocated before VideoInit() is executed. MacROM will possibly have to be relocated later. (c) The relocation may fail. i.e. the address space could not be allocated as above-mentioned. BasiliskII will have to quit. (d) Due to the different frame layout that could be used, I implemented video handling on SIGSEGV (see below). Drawback: DGA mode will be slower since a temp frame buffer will have to be used too. 2. Video on SIGSEGV signals ------------------------ The idea is to make the frame buffer write-protected. Then, when a SEGV occurs, the protection is released but the page number is kept so that the pages to redraw could be found quickly. When redrawing occurs, pages are write-protected back. I am using a Linux 2.2.5 kernel and retrieving the address that caused the violation is hacky. Reading from the kernel sources, I guessed that address would be kept in particular location of the stack when the signal handler is run. i.e. the hack is: void Screen_fault_handler(int, struct sigcontext scs) { uint32 faultive_address = scs.cr2; ... } The Video on SEGV method is portable provided that the host system supports siginfo_t for signal handlers (such as Solaris or newer 2.3.x and 2.4.x Linux kernels). i.e. the si_addr address field will contain the address that caused the violation. This method provides faster screen updates though that was not the intended purpose. That purpose was to copy to the host frame buffer and make the necessary color conversions when redrawing the regions that changed. e.g. RGB 555 -> BGR 565. 3. Translation cache flush rules ----------------------------- The rules are a little different than for UAE. TC flush will occur when: - Code is created and executed from Execute68k(), Execute68kTrap() - FlushCodeCache() is called - A-Traps: FlushCodeCacheRange, FlushInstructionCache - BlockMove() Please complete the above list if necessary. Notes: - The translation cache does not necessarily have to be flushed completely. - Correct flush rules are needed if one doesn't want to checksum the entire block each time. - M68K_EXEC_RETURN has to be made an end-block marker. Ideally, it would be best to have it right into the table68k. 4. I don't want to break the CVS tree ;-) ---------------------------------- I don't really have a "port" so I don't know what I can change in fact. I implemented (2) in video_x.cpp except support of siginfo_t and DGA changes when direct memory will be implemented. It is conditioned on through the ENABLE_VIDEO_ON_SEGV macro-def. I don't have a better name, so please tell me if you have a better one. I intend to make direct memory access conditioned through the ENABLE_DIRECT_ADDRESSING macro-def. Here again, I am open to any other suggestion. Actually, I never used CVS but I would like to try to commit the port I made from Lauri's FPU code. Should I make it the default one when an i386 cpu is detected ? A check for GCC will be required as well. -- Gwenolé Beauchesne |
From: <gb...@di...> - 2000-09-03 21:08:21
|
Hi, > I am in the process of porting the new UAE JIT Compiler for Linux/x86. > For that purpose, I need a few information and arrangements. ;-) > > 1. Ability to directly access the Mac address space > ------------------------------------------------ > > For faster performance and actually simpler porting, I want BasiliskII > being able to directly access the Mac address space only through one > offset. Implemented. And indeed, what a nice piece of improvement: near twice the speed! TODO: - handle DGA modes - handle siginfo_t - make other blitters than RGB555_RGB565 (either big or little endian versions). [In fact, other layouts than 16-bit on a little-endian machine would just require a byteswapping] - clean up before committing (?) - reversed address space (see below) 4. Reversed Address Space ---------------------- I had some success with reversed address space and the memory banking method although the gain was not that impressive (~5%, as expected) except for FPU-related operations (~30%, !?). <http://www.multimania.com/gbeauche/basilisk2/wip/> File: BasiliskII_RAS.tar.gz The diffs can be easily found since I prefixed them with "ras--" into comments. The key functions were: - RAS_Mac2HostAddr_Reverse(addr, n) return the translated address of the block freshly reversed - RAS_Mac2HostAddr(addr, n) return the translated address correctly offset - RAS_Reverse(addr, n) reverse the specified region of memory Those functions are defined in cpu_emulation.h Note however that I didn't checked all the patches for "correctness" yet, especially audio that makes strange sounds. Now I know this method can work and could actually be beneficial (?) if we use direct memory accessing, I wonder how hard it would be to make clean changes into the base source tree. A more clever way has to be found if one would like to easily experiment another addressing method: Byte-swapped Address Space, that will work well provided that unaligned accesses don't occur. I was hinted that a real m68k does not handle unaligned access, does it ? Another problem with reversed address space arises with the use of direct addressing when patching the ROM since PatchROM() relies on a native m68k byte-order. As I used memory banks, I could bypass this problem because I had specialised accessors that would handle ROM read/writes either in a reversed fashion or in the standard way. i.e. First, the ROM is left unreversed and accessors don't handle reversal. Then, after PatchROM() is executed (say Start680x0), the ROM is reversed and the new handlers are set. Since changing (with use of Read/WriteMacIntXX) rom_patches.cpp to handle direct memory accessing and reversed address space would require too much work, a simple solution would be to wrap the (uintXX *) that is used to iterate over the ROM, into an object that will do the job. e.g. uint16 * wp = <something>; would be translated into: rom_word_ptr wp = <something>; rom_word_ptr would have proper operator overloading. If that does not suffice, operator * could also return a helper-object that will do the byteswapping, if required. -- Gwenolé Beauchesne |
From: Christian B. <cb...@st...> - 2000-09-04 17:15:52
|
Hi! On Sun, Sep 03, 2000 at 11:16:49PM +0200, Gwenole Beauchesne wrote: > > 1. Ability to directly access the Mac address space > > Implemented. And indeed, what a nice piece of improvement: near twice > the speed! Cool! > 4. Reversed Address Space > [...] > Note however that I didn't checked all the patches for "correctness" > yet, especially audio that makes strange sounds. It may not be obvious, but part of the intention behind the Mac2Host_memcpy() etc. functions in cpu_emulation.h was to allow for a reversed address space. It's not used consequently in all modules, however. > I was hinted that a real m68k does not handle unaligned access, does it ? Starting with the 68020, all 680x0 can access any data at any alignment (except for the 68060 which needs operating system support under certain circumstances). > Another problem with reversed address space arises with the use of > direct addressing when patching the ROM since PatchROM() relies on a > native m68k byte-order. Yes, that's because the WriteMac*() functions may not yet be operational at PatchROM() time. Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/ |
From: <gb...@di...> - 2000-09-18 22:38:54
|
Hi, [Direct Addressing] > > Implemented. And indeed, what a nice piece of improvement: near twice > > the speed! In the event that a temporary frame buffer is needed in DGA mode, the user will notice that this mode will be up to 50% slower than in windowed mode. Despite all my efforts, I could only get direct addressing + DGA + temporary frame buffer 3% slower than memory banks + DGA with no temporary frame buffer (the original B2 without my patches) whereas the windowed mode in direct addressing is 50-60% faster than without direct addressing. I told you earlier that I will try direct addressing for Solaris. I tried and it failed :-/ Actually, under Solaris, the only reasonnable mappable region is above 0xE0000000. That's not enough to "triple allocate" the Mac address space. By "triple allocation" I mean allocating RAM, ROM, VID so that the gaps between each of them in the host address space are the same as those in the mac address space. In fact triple allocation could come down to "double allocation" since ROM is relocatable and can be for example next to the RAM region. A solution for Solaris and other systems that don't allow such a mapping is to use a table of offsets. That table is only 16 KB long if I take 1 MB pages and a 32-bit addressing host system. I would like to commit the patches but be advised that: - I altered main.cpp so that RAM and ROM base addresses are known before invokation of VideoInit(). This is enabled only in emulated_68k mode. That code comes from uae_cpu/basilisk_glue.cpp as you suggested. - I added a few lines in rom_patches and rsrc_patches for the ScratchMem hook in direct addressing. This works great, thanks Christian for that trick! - I have an extra file (video_vosf.cpp) for Video on SEGV signals that I will probably split into two files: video_vosf.h and blitters.h. Those files are only meant to be included from video_x.cpp. - I have specialised VideoRefresh functions to handle different sort of display updates. I also had a genvideo module that would generate specialised C handlers according to depth, xshm presence, static/dynamic updates of the screen, etc. I removed the genvideo thing because the benefits are not so impressive. There are more and more #defines :-/ - enable_vosf for Video on SEGV signals - direct_addressing as its name indicates - maybe direct_addressing_lt (lite) for the hack with a table of offsets - have_siginfo_t - have_sigcontext_subterfuge The last two macros are defined in acconfig.h and set at configure time for the config.h file. Besides, those tests are quite huge: ~45 lines each in configure.in... > > 4. Reversed Address Space > > [...] > > Note however that I didn't checked all the patches for "correctness" > > yet, especially audio that makes strange sounds. > > It may not be obvious, but part of the intention behind the Mac2Host_memcpy() > etc. functions in cpu_emulation.h was to allow for a reversed address space. > It's not used consequently in all modules, however. The reason why I chose the prepare,reverse,reverse-back approach is that the reversal can take place without any extra memory. I reckon that the Mac2Host_* functions are cleaner. Maybe next step would be to use them in all places that make use of Mac2HostAddr() and assume a forward address space. The point with direct addressing under Linux/i386 is that in some conditions, it could turn out to real addressing. Then, the JIT compiler will only have to generate load/stores without any other offset... I am pretty sure that this is where the major speed increase will come from. More if no byteswapping at all is needed. Bye. -- Gwenolé Beauchesne |
From: <gb...@di...> - 2000-09-19 10:18:44
|
Hi, > A solution for Solaris and other systems that don't allow such a mapping > is to use a table of offsets. That table is only 16 KB long if I take > 1 MB pages and a 32-bit addressing host system. Hmm, a much simpler solution would be to wipe out the "triple allocation" process and its heuristics. Indeed, I have just realized that the framebuffer is relocatable too... ;-) Bye. -- Gwenolé Beauchesne |
From: <gb...@di...> - 2000-09-19 11:44:36
|
Hi, > windowed mode. Despite all my efforts, I could only get direct > addressing + DGA + temporary frame buffer 3% slower than memory banks + > DGA with no temporary frame buffer (the original B2 without my patches) With the new direct addressing scheme, DGA is as fast as Windowed mode on raw cpu performance. For graphics performace in DGA mode, it is now as fast as without direct addressing. The reason of that is probably because of a better locality in accesses to memory. The Mac address space was allocated at once (RAM + ROM + VID). I will try that new scheme under Solaris this afternoon. Bye. -- Gwenolé Beauchesne |
From: <gb...@di...> - 2000-09-19 18:02:02
|
Hi, > I will try that new scheme under Solaris this afternoon. It does work! ;-) I will commit soon the diffs. In fact, it might also not be necessary to move RAM/ROM base address determination from uae_cpu/basilisk_glue.cpp to main.cpp The different addressing modes will be configured through --enable-addressing=mode where mode is one of: fastest, real, direct, banks. fastest is the default mode and will try to choose the best addressing mode available for the target system. Tests are: * real addressing: - ability to mmap 0x2000 bytes from 0x0000 - ability for Video on SEGV signals (VOSF) on little endian machines or big endian ones in a video mode other that 16 bits per pixel * direct addressing: - VOSF * banks: - no test, default mode * VOSF: - siginfo_t and si_addr set correctly - sigcontext hack I will probably include config.guess and config.sub in order to retrieve canonical information about the host or the target (cpu, os, vendor) and set macros such as OS_linux, CPU_i386 instead of relying on compiler-specific macros. What do you think about it ? Bye. -- Gwenolé Beauchesne |
From: Christian B. <cb...@st...> - 2000-09-19 18:10:48
|
Hi! On Tue, Sep 19, 2000 at 08:11:03PM +0200, Gwenole Beauchesne wrote: > It does work! ;-) Cool! :-) > * real addressing: > - ability to mmap 0x2000 bytes from 0x0000 > - ability for Video on SEGV signals (VOSF) on little endian machines or > big endian ones in a video mode other that 16 bits per pixel Ability for unaligned accesses? And does real addressing work on little-endian machines? > I will probably include config.guess and config.sub Ok. Maybe some of the CPU/OS detection in the configure.in can be cleaned up this way. Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/ |
From: <gb...@di...> - 2000-09-20 14:00:43
|
Hi, [Real Addressing rules] > Ability for unaligned accesses? Actually, this is the job of the do_get_mem/do_put_mem functions. If the host provides unaligned access, that's fine. > And does real addressing work on little-endian machines? Unfortunately, while I was running a Speedometer Graphics performance test (16-bit mode), Basilisk exitted at the end of that test, just before displaying the result or beepin). It seems that it tried to access some function located at 0x00ED466A [*]. How come previous tests ran well ? The only thing I haven't enabled in regards to Real Addressing on the AmigaOS, is the patch to disable overwriting of SysBase. What is it ? I tried to apply this patch but with no avail :-/ [*] Looks specific to Speedometer. [live debugging ;-)] Actually, it further seems to be the result of a TST.B (A0). Not very informative... Real addressing will work on platforms that provide VOSF, especially the ability to retrieve the faultive address when a SEGV signal is caught. This is implemented through the use of the si_addr field of siginfo_t on platforms that support extended signal handlers, or through a sigcontext hack on Linux/i386. Once the faultive address is known, write permission is enabled back to the corresponding page. Later, on screen update, I retrieve the dirty pages and update the host frame buffer. I will also experiment an hybrid between the update in DGA mode and Windowed mode. In DGA mode, there are two temporary frame buffers, one to which data is actually written, the other that is a copy. Then, I use a variant of the static_update method to update the screen. This approach is actually faster than having just one temporary frame buffer and blitting the complete dirty pages. > > I will probably include config.guess and config.sub BTW, I took those from the SDL library, not those from the latest devel autoconf package. Bye. -- Gwenolé Beauchesne |
From: <gb...@di...> - 2000-09-20 14:40:52
|
Hi, > [*] Looks specific to Speedometer. [live debugging ;-)] Actually, it > further seems to be the result of a TST.B (A0). Not very informative... That piece of code is at ROMBase + 0xdbae on my Quadra 630 ROM. -- Gwenolé Beauchesne |
From: Christian B. <cb...@st...> - 2000-09-24 13:41:49
|
Hi! On Wed, Sep 20, 2000 at 04:09:43PM +0200, Gwenole Beauchesne wrote: > The only thing I haven't enabled in regards to Real Addressing on the > AmigaOS, is the patch to disable overwriting of SysBase. What is it ? AmigaOS stores a pointer to ExecBase at address 4 (the only absolute address used in AmigaOS) which must not be overwritten by MacOS. Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/ |
From: Christian B. <cb...@st...> - 2000-09-04 17:02:54
|
Hi! On Sun, Sep 03, 2000 at 01:26:06PM +0200, Gwenole Beauchesne wrote: > (a) In order to mmap() correctly the address space in VideoInit(), I > would like to know what is the current ROMBaseMac. This is currently not > possible since VideoInit() is executed before Init680x0(). I think the complete part in uae_cpu/basilisk_glue.cpp, lines 59..82 (#if REAL_ADDRESSING .. #endif) could be moved into main.cpp/InitAll(), after the call to CheckROM() has been made. > (b) In order to get a chance to mmap() the address space as > above-mentioned, MacRAM would not get allocated before VideoInit() is > executed. This is harder. I placed VideoInit() at the latest possible point in the initialization order because it may switch to a screen mode where it's no longer possible to put up dialog boxes for error messages from modules that are initialized earlier. > (d) Due to the different frame layout that could be used, I implemented > video handling on SIGSEGV (see below). Drawback: DGA mode will be slower > since a temp frame buffer will have to be used too. But the whole point of DGA mode is to avoid a temporary frame buffer... > i.e. the hack is: > void Screen_fault_handler(int, struct sigcontext scs) > { > uint32 faultive_address = scs.cr2; I'm using a similar method to access the CPU registers in the native NetBSD/m68k version. Unfortunately, NetBSD doesn't seem to support siginfo_t. > TC flush will occur when: > - Code is created and executed from Execute68k(), Execute68kTrap() > - FlushCodeCache() is called > - A-Traps: FlushCodeCacheRange, FlushInstructionCache > - BlockMove() Why is this not simply done every time a MOVEC *,CACR or CPUSH is executed to clear the emulated 680x0's caches? > 4. I don't want to break the CVS tree ;-) > I don't really have a "port" so I don't know what I can change in fact. If you are convinced that it will still work on non-x86 machines and other operating systems (including NetBSD/m68k, where it runs without CPU emulation), you can check it in. > Actually, I never used CVS There's a nice tutorial at http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html#Insight > Should I make it the default one when an i386 cpu is detected ? If it's an improvement, then yes. Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/ |
From: <gb...@di...> - 2000-09-05 10:59:32
|
Hi, > I think the complete part in uae_cpu/basilisk_glue.cpp, lines 59..82 > (#if REAL_ADDRESSING .. #endif) could be moved into main.cpp/InitAll(), > after the call to CheckROM() has been made. I think so as well, especially the fact that the switch/cases are already in place. Even the memory_init() could be moved because in DIRECT_ADDRESSING mode, I made it do nothing. > > (b) In order to get a chance to mmap() the address space as > > above-mentioned, MacRAM would not get allocated before VideoInit() is > > executed. > > This is harder. I placed VideoInit() at the latest possible point in the > initialization order because it may switch to a screen mode where it's > no longer possible to put up dialog boxes for error messages from modules > that are initialized earlier. Still in direct addressing mode, the trick was to call other buffer initialization routines after InitAll() is completed in main_unix.cpp. The function (VideoInitBuffer) takes only one parameter: the new memory area allocated for the temporary frame buffer. > > (d) Due to the different frame layout that could be used, I implemented > > video handling on SIGSEGV (see below). Drawback: DGA mode will be slower > > since a temp frame buffer will have to be used too. > > But the whole point of DGA mode is to avoid a temporary frame buffer... The rationale is currently as follows according to DGA screen depths: - 8 : no temporary frame buffer is required - 15 : a temp buffer is needed because because long get/put have to be word swapped - 16 : temp buffer required because color conversion is necessary - 24 : byteswap All the cases above-mentioned are true only if the host is little-endian. Otherwise, no temp buffer at all is required. Note: for windowed mode, the reasoning is a bit different since I should take into account the underlying bitmap bit order instead of the host's. See the tests you are take when calling video_x.cpp/set_video_monitor. Another though about direct addressing: MacOS seems to try to write to ROM then read back for some testing purposes, right ? I used Lauri's method to handle that, i.e. protect the ROM area from writes. When an access violation occurs, the Screen_fault_handler() will just advance the host (x86) instruction pointer to the next instruction. But since I don't want to have an advance() function for any target processor, I wonder if the ScratchMem method used for real addressing is safe all the time ? If so, correct #if should also be added in main.cpp and rsrc_patches.cpp. > > TC flush will occur when: > > - Code is created and executed from Execute68k(), Execute68kTrap() > > - FlushCodeCache() is called > > - A-Traps: FlushCodeCacheRange, FlushInstructionCache > > - BlockMove() > > Why is this not simply done every time a MOVEC *,CACR or CPUSH is executed > to clear the emulated 680x0's caches? Yes, Bernie's compiler does that but I was just wondering about self-modifying code and other ways to detect it and avoid complete checksuming of basic blocks. BTW, I was also wondering how hard it would be to patch the Segment Loader and compile, possibly in a more aggressive way, blocks that got loaded. I was also thinking about the use of MAE's dispatching method instead of going every time through the TLB to find and check for a compiled block. In other words, take one unused opcode, put it in place of the first opcode of the block and patch the jump table accordingly. This would make it easily possible to port the JIT compiler on a system that doesn't have GCC and its "Label as Value" extension, say under Windows and VC++ ;-) The TLB is still needed, to recover the original opcode and to push back the special compile_opcode. Overlapping of compiled blocks should be taken care of as well since the original m68k opcode got replace with one of the special compile_opcodes. I have not started to work on compemu_*.c yet. For starters, I will probably create a similar framework that would just generate calls to the appropriate instruction handlers. Then, there would just be the need to have specific "call <target>" instruction generator per target processor. I am also thinking/experimenting/working on another emulator that should enable retargetting of a JIT compiler in near no time. In fact, that's not really a code generator, just a code "copier". GCC will be mandatory because of the following (at least) two features: - "Label as Value" : to determine code ranges to copy - "Explicit Reg Vars" : for static register allocation. If the host permits it, I intend to cache D0, D1, A0, A1, A7 in no particular order. Q&D profiling shows that those are the most frequently used registers. Sure this won't provide as much power as of a customized JIT compiler with dynamic register allocation but the point is that no code generator is needed. ;-) I have not seen this implemented before in a real emulator. I got the idea by reading again: "Optimizing direct threaded code by selective inlining" Ian Piumarta and Fabio Ricardi PLDI'98. (ACM) If you don't have access to the ACM, I could try to recover from my memory the link from which I got the article. > If you are convinced that it will still work on non-x86 machines and other > operating systems (including NetBSD/m68k, where it runs without CPU > emulation), you can check it in. I won't commit the direct addressing diffs before I see it working, at least, on Solaris/SPARC which supports siginfo_t. > > Actually, I never used CVS > > There's a nice tutorial at > http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html#Insight Thanks, I will check it out. > > Should I make it the default one when an i386 cpu is detected ? > > If it's an improvement, then yes. Is "it works (enable scrollbars)" a right answer ? ;-) PS: sorry, I did not notice I wrote so much text. Bye, -- Gwenolé Beauchesne |
From: <gb...@di...> - 2000-09-05 11:17:28
|
> "Optimizing direct threaded code by selective inlining" > Ian Piumarta and Fabio Ricardi > PLDI'98. (ACM) > > If you don't have access to the ACM, I could try to recover from my > memory the link from which I got the article. Google was faster: <http://www-sor.inria.fr/publi/ODCSI_pldi98.html> Bye, -- Gwenolé Beauchesne |
From: <gb...@di...> - 2000-09-06 23:01:58
|
Hi, I tried to run in direct addressing mode with DGA with no avail :-/ Basically, all I needed to do was just retrieve the host real frame buffer to buffer_copy, then allocate the_buffer later as I did for windowed mode. Unfortunately, for some reason, I don't even reach that part of code. In video_x.cpp/init_xf86_dga, the third XSync() seems to completely lock BasiliskII. As I tried to run B2 with strace, the last system call that got traced was indeed a select(). Commenting out the line, would just make Basilisk hang a few X calls later. That problem was encountered with an i740 X server. Using a traditional S3 Virge (I have two cards in the same box :), the problem is different: everything goes well up to "Starting the emulation..." then, Basilisk simply quits. There was no SEGV signal, otherwise the Screen_fault_handler would have caught it and reported it. Removing direct addressing automagically enables Basilisk back to run in fullscreen DGA mode. Do you happen to have any idea about that ? -- Gwenolé Beauchesne |
From: Christian B. <cb...@st...> - 2000-09-12 18:34:42
|
Hi! On Tue, Sep 05, 2000 at 01:08:01PM +0200, Gwenole Beauchesne wrote: > MacOS seems to try to write to ROM then read back for some testing > purposes, right ? There are two places I know of where the MacOS writes to the ROM: 1. The resource manager does it when using ROM resources. But it doesn't seem to do any harm when the writes are allowed to take place. 2. The longword at address 0 is set to point into the ROM (probably to make broken programs that write to a dereferenced NULL pointer not destroy any RAM contents). Unfortunately, some versions of MacOS itself are also "broken" in that sense and that is the main reason for the "ScratchMem" handling on the Amiga (otherwise, MacOS would crash on boot). This approach seems to be safe. > Yes, Bernie's compiler does that but I was just wondering about > self-modifying code and other ways to detect it and avoid complete > checksuming of basic blocks. MacOS will flush the cache in all instances where self-modifying code is used (or code is loaded) when the CPU is a 68040. > > > Should I make it the default one when an i386 cpu is detected ? > > > > If it's an improvement, then yes. > > Is "it works (enable scrollbars)" a right answer ? ;-) It is. :-) Bye, Christian -- / Coding on PowerPC and proud of it \/ http://www.uni-mainz.de/~bauec002/ |