mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-09-15 06:56:46 +00:00
Changes made to the update routines
- Cleaned up the process for determining the ranges of pages touched that have to be blitted onto the screen (find_next_page_set() and find_next_page_clear() functions) Changes made to do_handle_screen_fault() - An unhandled address is now dealt by the default SIGSEGV handler - Print out the address of the instruction that caused the exception
This commit is contained in:
parent
d583307d6b
commit
bd3734e10a
@ -240,19 +240,31 @@ static fbcopy_func fbcopy_funcs[ID_DEPTH_COUNT][2][2] = {
|
|||||||
* Screen fault handler
|
* Screen fault handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void do_handle_screen_fault(uintptr addr)
|
const uintptr INVALID_PC = (uintptr)-1;
|
||||||
|
|
||||||
|
static inline void do_handle_screen_fault(uintptr addr, uintptr pc = INVALID_PC)
|
||||||
{
|
{
|
||||||
if ((addr < mainBuffer.memStart) || (addr >= mainBuffer.memEnd)) {
|
/* Someone attempted to write to the frame buffer. Make it writeable
|
||||||
fprintf(stderr, "Segmentation fault at 0x%08X\n", addr);
|
* now so that the data could actually be written. It will be made
|
||||||
abort();
|
* read-only back in one of the screen update_*() functions.
|
||||||
|
*/
|
||||||
|
if ((addr >= mainBuffer.memStart) && (addr < mainBuffer.memEnd)) {
|
||||||
|
const int page = (addr - mainBuffer.memStart) >> mainBuffer.pageBits;
|
||||||
|
caddr_t page_ad = (caddr_t)(addr & ~(mainBuffer.pageSize - 1));
|
||||||
|
LOCK_VOSF;
|
||||||
|
PFLAG_SET(page);
|
||||||
|
mprotect(page_ad, mainBuffer.pageSize, PROT_READ | PROT_WRITE);
|
||||||
|
UNLOCK_VOSF;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int page = (addr - mainBuffer.memStart) >> mainBuffer.pageBits;
|
/* Otherwise, we don't know how to handle the fault, let it crash */
|
||||||
caddr_t page_ad = (caddr_t)(addr & ~(mainBuffer.pageSize - 1));
|
fprintf(stderr, "do_handle_screen_fault: unhandled address 0x%08X", addr);
|
||||||
LOCK_VOSF;
|
if (pc != INVALID_PC)
|
||||||
PFLAG_SET(page);
|
fprintf(stderr, " [IP=0x%08X]", pc);
|
||||||
mprotect(page_ad, mainBuffer.pageSize, PROT_READ | PROT_WRITE);
|
fprintf(stderr, "\n");
|
||||||
UNLOCK_VOSF;
|
|
||||||
|
signal(SIGSEGV, SIG_DFL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_SIGINFO_T)
|
#if defined(HAVE_SIGINFO_T)
|
||||||
@ -269,7 +281,7 @@ static void Screen_fault_handler(int, siginfo_t * sip, void *)
|
|||||||
static void Screen_fault_handler(int, struct sigcontext scs)
|
static void Screen_fault_handler(int, struct sigcontext scs)
|
||||||
{
|
{
|
||||||
D(bug("Screen_fault_handler: ADDR=0x%08X from IP=0x%08X\n", scs.cr2, scs.eip));
|
D(bug("Screen_fault_handler: ADDR=0x%08X from IP=0x%08X\n", scs.cr2, scs.eip));
|
||||||
do_handle_screen_fault((uintptr)scs.cr2);
|
do_handle_screen_fault((uintptr)scs.cr2, (uintptr)scs.eip);
|
||||||
}
|
}
|
||||||
|
|
||||||
# elif defined(__m68k__) && defined(__NetBSD__)
|
# elif defined(__m68k__) && defined(__NetBSD__)
|
||||||
@ -342,20 +354,12 @@ static inline void update_display_window_vosf(void)
|
|||||||
{
|
{
|
||||||
int page = 0;
|
int page = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (PFLAG_ISCLEAR_4(page))
|
const int first_page = find_next_page_set(page);
|
||||||
page += 4;
|
if (first_page >= mainBuffer.pageCount)
|
||||||
|
|
||||||
while (PFLAG_ISCLEAR(page))
|
|
||||||
page++;
|
|
||||||
|
|
||||||
if (page >= mainBuffer.pageCount)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const int first_page = page;
|
page = find_next_page_clear(first_page);
|
||||||
while ((page < mainBuffer.pageCount) && PFLAG_ISSET(page)) {
|
PFLAG_CLEAR_RANGE(first_page, page);
|
||||||
PFLAG_CLEAR(page);
|
|
||||||
++page;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the dirty pages read-only again
|
// Make the dirty pages read-only again
|
||||||
const int32 offset = first_page << mainBuffer.pageBits;
|
const int32 offset = first_page << mainBuffer.pageBits;
|
||||||
@ -465,21 +469,13 @@ static inline void update_display_dga_vosf(void)
|
|||||||
{
|
{
|
||||||
int page = 0;
|
int page = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (PFLAG_ISCLEAR_4(page))
|
const int first_page = find_next_page_set(page);
|
||||||
page += 4;
|
if (first_page >= mainBuffer.pageCount)
|
||||||
|
|
||||||
while (PFLAG_ISCLEAR(page))
|
|
||||||
page++;
|
|
||||||
|
|
||||||
if (page >= mainBuffer.pageCount)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const int first_page = page;
|
page = find_next_page_clear(first_page);
|
||||||
while ((page < mainBuffer.pageCount) && PFLAG_ISSET(page)) {
|
PFLAG_CLEAR_RANGE(first_page, page);
|
||||||
PFLAG_CLEAR(page);
|
|
||||||
++page;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the dirty pages read-only again
|
// Make the dirty pages read-only again
|
||||||
const int32 offset = first_page << mainBuffer.pageBits;
|
const int32 offset = first_page << mainBuffer.pageBits;
|
||||||
const uint32 length = (page - first_page) << mainBuffer.pageBits;
|
const uint32 length = (page - first_page) << mainBuffer.pageBits;
|
||||||
|
Loading…
Reference in New Issue
Block a user