ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/video_vosf.h
(Generate patch)

Comparing BasiliskII/src/Unix/video_vosf.h (file contents):
Revision 1.10 by cebix, 2000-11-30T16:20:52Z vs.
Revision 1.11 by gbeauche, 2001-01-11T16:39:08Z

# Line 240 | Line 240 | static fbcopy_func fbcopy_funcs[ID_DEPTH
240   *      Screen fault handler
241   */
242  
243 < static inline void do_handle_screen_fault(uintptr addr)
243 > const uintptr INVALID_PC = (uintptr)-1;
244 >
245 > static inline void do_handle_screen_fault(uintptr addr, uintptr pc = INVALID_PC)
246   {
247 <        if ((addr < mainBuffer.memStart) || (addr >= mainBuffer.memEnd)) {
248 <                fprintf(stderr, "Segmentation fault at 0x%08X\n", addr);
249 <                abort();
247 >        /* Someone attempted to write to the frame buffer. Make it writeable
248 >         * now so that the data could actually be written. It will be made
249 >         * read-only back in one of the screen update_*() functions.
250 >         */
251 >        if ((addr >= mainBuffer.memStart) && (addr < mainBuffer.memEnd)) {
252 >                const int page  = (addr - mainBuffer.memStart) >> mainBuffer.pageBits;
253 >                caddr_t page_ad = (caddr_t)(addr & ~(mainBuffer.pageSize - 1));
254 >                LOCK_VOSF;
255 >                PFLAG_SET(page);
256 >                mprotect(page_ad, mainBuffer.pageSize, PROT_READ | PROT_WRITE);
257 >                UNLOCK_VOSF;
258 >                return;
259          }
260          
261 <        const int page  = (addr - mainBuffer.memStart) >> mainBuffer.pageBits;
262 <        caddr_t page_ad = (caddr_t)(addr & ~(mainBuffer.pageSize - 1));
263 <        LOCK_VOSF;
264 <        PFLAG_SET(page);
265 <        mprotect(page_ad, mainBuffer.pageSize, PROT_READ | PROT_WRITE);
266 <        UNLOCK_VOSF;
261 >        /* Otherwise, we don't know how to handle the fault, let it crash */
262 >        fprintf(stderr, "do_handle_screen_fault: unhandled address 0x%08X", addr);
263 >        if (pc != INVALID_PC)
264 >                fprintf(stderr, " [IP=0x%08X]", pc);
265 >        fprintf(stderr, "\n");
266 >        
267 >        signal(SIGSEGV, SIG_DFL);
268   }
269  
270   #if defined(HAVE_SIGINFO_T)
# Line 269 | Line 281 | static void Screen_fault_handler(int, si
281   static void Screen_fault_handler(int, struct sigcontext scs)
282   {
283          D(bug("Screen_fault_handler: ADDR=0x%08X from IP=0x%08X\n", scs.cr2, scs.eip));
284 <        do_handle_screen_fault((uintptr)scs.cr2);
284 >        do_handle_screen_fault((uintptr)scs.cr2, (uintptr)scs.eip);
285   }
286  
287   # elif defined(__m68k__) && defined(__NetBSD__)
# Line 342 | Line 354 | static inline void update_display_window
354   {
355          int page = 0;
356          for (;;) {
357 <                while (PFLAG_ISCLEAR_4(page))
358 <                        page += 4;
347 <                
348 <                while (PFLAG_ISCLEAR(page))
349 <                        page++;
350 <                
351 <                if (page >= mainBuffer.pageCount)
357 >                const int first_page = find_next_page_set(page);
358 >                if (first_page >= mainBuffer.pageCount)
359                          break;
360 <                
361 <                const int first_page = page;
362 <                while ((page < mainBuffer.pageCount) && PFLAG_ISSET(page)) {
356 <                        PFLAG_CLEAR(page);
357 <                        ++page;
358 <                }
360 >
361 >                page = find_next_page_clear(first_page);
362 >                PFLAG_CLEAR_RANGE(first_page, page);
363  
364                  // Make the dirty pages read-only again
365                  const int32 offset  = first_page << mainBuffer.pageBits;
# Line 465 | Line 469 | static inline void update_display_dga_vo
469   {
470          int page = 0;
471          for (;;) {
472 <                while (PFLAG_ISCLEAR_4(page))
473 <                        page += 4;
470 <                
471 <                while (PFLAG_ISCLEAR(page))
472 <                        page++;
473 <                
474 <                if (page >= mainBuffer.pageCount)
472 >                const int first_page = find_next_page_set(page);
473 >                if (first_page >= mainBuffer.pageCount)
474                          break;
475 <                
476 <                const int first_page = page;
477 <                while ((page < mainBuffer.pageCount) && PFLAG_ISSET(page)) {
478 <                        PFLAG_CLEAR(page);
480 <                        ++page;
481 <                }
482 <                
475 >
476 >                page = find_next_page_clear(first_page);
477 >                PFLAG_CLEAR_RANGE(first_page, page);
478 >
479                  // Make the dirty pages read-only again
480                  const int32 offset  = first_page << mainBuffer.pageBits;
481                  const uint32 length = (page - first_page) << mainBuffer.pageBits;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines