On 10 November 2012 04:30, Stas Sergeev wrote: > I wonder if something trivial can work instead. > And I mean _really_ trivial. :)
I wish ;) > For example: > - the signal handler just records what page have > faulted, and unprotects it. > - all the subsequent writes to that page are uncaught, > so they are fast, but without a screen update > - the main dosemu loop later checks the list of the > faulted pages, compares their content to their old > copy stored elsewhere, and, for every mismatch, > calls the vgaemu_write_xxx(), which would also update > the backed-up copy. This is more or less the strategy that's been used in DOSEMU since even before instremu.c existed, where pages are protected r/o. Problem is that that works perfectly for normal "video" modes, but not for planar VGA modes such as 640x480 at 16 colors where VGA memory should be regarded as MMIO. That is, every write to and read from the 64K buffer at 0xa0000 needs to translated to a write or read to/from some combination of the four underlying planes totalling 256K. Other emulators have the same issue. I once looked at QEMU, and they put it through MMIO logic in the software MMU; instead of going via page tables, a function is called. > I am certainly missing something here, but I still > beleive we can have a clean code, without a vgaemu > stuff spread all around. The recent cpuemu bugs were > because of the missing vgaemu hooks, for instance. > And having the entire instremu.c, just for that? > There _must_ be some magic way to throw all the mess > to the trash can. Or at least I hope so. :) instremu.c is actually redundant now, however it is only used when code is executed natively, via vm86() or DPMI. It could be replaced by dynamically switching between native and cpuemu on demand (but I never got round to implementing that) The recent bugs have nothing to do with instremu.c. Instead with the JIT active, there is a very small "instremu.c" in src/emu-i386/simx86/sigsegv.c:e_vgaemu_fault(), that traps and interpretes *generated* instructions. The alternative to this technique (as was already implemented by Alberto) is to put the correct checks in software in the JIT code so it doesn't trap. I've slowly been moving the code to this approach, it's what used in L_VGAREAD and L_VGAWRITE in codegen-x86.c. The simulator always checks in software so it never traps (that's also nice for debugging, valgrind, etc). Of course software checks make the generated code a bit slower but this is offset by fewer traps, and from what I understand (from the blogs at emulators.com), traps have become much more expensive in newer CPUs vs the great speed at which software checks can be performed. The new bugs you mention are actually regressions from a few cpuemu optimizations that I made this year, and also an unintended consequence of the LINEAR2UNIX strategy -- it used to be that 0xa0000 was always translated to &mem_base[0xa0000], writes were trapped so an update was triggered, but now it translated to the pointer in alias-mapped vga memory, that is not protected, so it messed up the update strategy (for prince2). For 1.4.1 I should just make LINEAR2UNIX translate again to &mem_base[0xa0000], to make it trap on r/o pages (its purpose is to bypass read protection because of cpuemu, not to bypass read protection because of vgaemu). After, I will look at a more elegant approach. To eradicate all mentions of vgaemu in cpuemu we'd have to implement generic MMIO functionality. It's just that write now, vgaemu is the only MMIO, so it was coded explicitly (hmm I can just think of one exception, the LDT write traps for Windows 3.1, but that's very limited). Bart ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_nov _______________________________________________ Dosemu-devel mailing list Dosemu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dosemu-devel