/* File: mcon.c Written by: John van Groningen */ /* #define MACOSX */ #define G_POWER #define NEW_HEADERS #ifdef MACHO # define MACOSX # define MACHO_EXCEPTIONS #endif #ifdef MACOSX # define FLUSH_PORT_BUFFER #endif #if defined (MACOSX) || defined (MACHO) # define STACK_OVERFLOW_EXCEPTION_HANDLER #endif #ifdef MACHO # define NEWLINE_CHAR '\r' #else # define NEWLINE_CHAR '\n' #endif #ifdef MACHO # define MAYBE_USE_STDIO #endif #ifdef MACOSX # define TARGET_API_MAC_CARBON 1 #endif #ifndef NEW_HEADERS #include #include #include #else # ifndef MACHO extern void sprintf (char *,...); # endif #endif #define MULW(a,b) ((int)((short)(a)*(short)(b))) #define UDIVW(a,b) ((unsigned short)((unsigned short)(a)/(unsigned short)(b))) #include #include #include #include #ifndef NEW_HEADERS //# include #include #endif #include #include #include #include #ifndef NEW_HEADERS //# include #endif #ifdef G_POWER void first_function (void) { } #endif #ifdef STACK_OVERFLOW_EXCEPTION_HANDLER # ifdef MACHO # include # ifdef MACHO_EXCEPTIONS # include # endif # else # include # include # include # include # include # define SIGBUS 10 # define SIGSEGV 11 # define SIG_DFL (void (*)())0 # define SIG_IGN (void (*)())1 struct sigaction { void (*sa_handler)(); unsigned int sa_mask; int sa_flags; }; struct sigaltstack { char *ss_sp; int ss_size; int ss_flags; }; struct sigcontext { int sc_onstack; int sc_mask; int sc_ir; int sc_psw; int sc_sp; void *sc_regs; }; struct vm_region_basic_info { int protection; int max_protection; unsigned int inheritance; int shared; int reserved; int offset; int behavior; unsigned short user_wired_count; }; static CFBundleRef systemBundle=NULL; static int initSystemBundle (void) { FSRefParam fileRefParam; FSRef fileRef; OSErr error; CFURLRef url; { int i; char *p; p=(char*)&fileRefParam; for (i=0; ivisRgn); #endif for (y=0,screen_y_pos=char_asc_lead; yportRect,0,-char_height,erase_region); #endif EraseRgn (erase_region); DisposeRgn (erase_region); BlockMove ((char*)chars[1],(char*)chars,(MAX_N_COLUMNS+1)*(n_lines-1)); chars[n_lines-1][0]=NEWLINE_CHAR; #ifdef FLUSH_PORT_BUFFER QDFlushPortBuffer (GetWindowPort (window),NULL); #endif add_IO_time(); } static void print_newline() { screen_chars[cur_y][cur_x]=NEWLINE_CHAR; ++cur_y; cur_x=0; g_cur_x=0; if (cur_y>=n_screen_lines){ cur_y=n_screen_lines-1; scroll_window (c_window,screen_chars,n_screen_lines); } #ifdef FLUSH_PORT_BUFFER else QDFlushPortBuffer (GetWindowPort (c_window),NULL); #endif MoveTo (0,MULW(cur_y,char_height)+char_asc_lead); } static void window_print_char (char c) { if (c==NEWLINE_CHAR) print_newline(); else { char *screen_char; int w; w=CharWidth (c); if (g_cur_x+w>=c_window_width || cur_x+1>=MAX_N_COLUMNS) print_newline(); g_cur_x+=w; screen_char=&screen_chars[cur_y][cur_x]; *screen_char=c; screen_char[1]=NEWLINE_CHAR; DrawChar (c); ++cur_x; } } static void make_error_window_visible () { if (!error_window_visible){ add_execute_time(); ShowWindow (e_window); #ifdef MACOSX ValidWindowRect (e_window,&e_local_window_rect); #else ValidRect (&e_local_window_rect); #endif add_IO_time(); error_window_visible=1; } } static void make_console_window_visible () { if (!console_window_visible){ add_execute_time(); ShowWindow (c_window); #ifdef MACOSX ValidWindowRect (c_window,&c_local_window_rect); #else ValidRect (&c_local_window_rect); #endif add_IO_time(); console_window_visible=1; } } /* #ifdef powerc QDGlobals qd; #endif **/ #ifndef MACOSX #ifdef NO_INIT extern QDGlobals qd; #else QDGlobals qd; #endif #endif #ifdef MAYBE_USE_STDIO static int use_stdio; #define swap_nl_cr(c) (((c)=='\n' || (c)=='\r') ? ((c) ^ ((char)('\n' ^ '\r'))) : (c)) #define oputc(c) putchar(swap_nl_cr(c)) #define eputc(c) putc(swap_nl_cr (c),stderr) #endif void w_print_char (char c) { GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ oputc (c); return; } #endif #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (c_window)); #else port=NULL; if (qd.thePort!=c_window){ port=qd.thePort; SetPort (c_window); } #endif if (!console_window_visible) make_console_window_visible(); window_print_char (c); #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } static void w_print_text_without_newlines (char *s,unsigned long length) { unsigned long text_length,n; text_length=TextWidth (s,0,length); if (g_cur_x+text_length=n_e_screen_lines){ e_cur_y=n_e_screen_lines-1; scroll_window (e_window,e_screen_chars,n_e_screen_lines); } #ifdef FLUSH_PORT_BUFFER else QDFlushPortBuffer (GetWindowPort (e_window),NULL); #endif MoveTo (0,MULW(e_cur_y,char_height)+char_asc_lead); } static void e_print_char (char c) { if (c==NEWLINE_CHAR) e_print_newline(); else { char *screen_char; int w; w=CharWidth (c); if (e_g_cur_x+w>=e_window_width || e_cur_x+1>=MAX_N_COLUMNS) e_print_newline(); e_g_cur_x+=w; screen_char=&e_screen_chars[e_cur_y][e_cur_x]; *screen_char=c; screen_char[1]=NEWLINE_CHAR; DrawChar (c); ++e_cur_x; } } void ew_print_char (char c) { GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ eputc (c); return; } #endif #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (e_window)); #else port=NULL; if (qd.thePort!=e_window){ port=qd.thePort; SetPort (e_window); } #endif if (!error_window_visible) make_error_window_visible(); e_print_char (c); #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } static void e_print_text_without_newlines (char *s,unsigned long length) { unsigned long text_length,n; text_length=TextWidth (s,0,length); if (e_g_cur_x+text_lengthwhat==updateEvt){ if ((WindowPtr)event_p->message==c_window){ w_remove_cursor(); update_window (c_window,screen_chars,n_screen_lines,g_cur_x,cur_y); w_show_cursor(); } else if ((WindowPtr)event_p->message==e_window) update_window (e_window,e_screen_chars,n_e_screen_lines,e_g_cur_x,e_cur_y); } else if (event_p->what==mouseDown){ WindowPtr window; if (FindWindow (event_p->where,&window)==inContent) select_window (window); } } static int w_read_char() { add_execute_time(); while (1){ #ifndef MACOSX SystemTask(); #endif if (!GetNextEvent (everyEvent,&my_event)) continue; switch (my_event.what){ case keyDown: case autoKey: { int c; c=my_event.message & 0xff; add_IO_time(); return c; } case updateEvt: case mouseDown: handle_update_or_mouse_down_event (&my_event); break; } } } static void w_read_line() { int b_cur_x,b_cur_y,n_chars_read,c; n_chars_read=0; b_cur_x=cur_x; b_cur_y=cur_y; do { w_show_cursor(); c=w_read_char(); w_remove_cursor(); if (c=='\b'){ if (n_chars_read>0){ while (cur_x==0){ int line_length,x,c; char *screen_line; --cur_y; screen_line=screen_chars[cur_y]; line_length=0; x=0; while (c=screen_line[line_length],c!=NEWLINE_CHAR){ ++line_length; x+=CharWidth (c); } cur_x=line_length; g_cur_x=x; } if (cur_x>0){ int w; char *screen_char; --cur_x; screen_char=&screen_chars[cur_y][cur_x]; w=CharWidth (*screen_char); *screen_char=NEWLINE_CHAR; g_cur_x-=w; --n_chars_read; w_remove_char (w); } } } else { if (c==NEWLINE_CHAR){ if (cur_y+10){ --b_cur_y; print_newline(); } } else { char *screen_char; int w; w=CharWidth (c); if (g_cur_x+w>=c_window_width || cur_x+1>=MAX_N_COLUMNS) if (cur_y+10){ --b_cur_y; print_newline(); } else continue; g_cur_x+=w; screen_char=&screen_chars[cur_y][cur_x]; *screen_char=c; screen_char[1]=NEWLINE_CHAR; DrawChar (c); ++cur_x; ++n_chars_read; } } } while (c!=NEWLINE_CHAR); { char *char_p,*screen_p; input_buffer_length=n_chars_read+1; input_buffer_pos=0; char_p=input_buffer; screen_p=&screen_chars[b_cur_y][b_cur_x]; while (n_chars_read!=0){ int c; while (c=*screen_p++,c==NEWLINE_CHAR){ ++b_cur_y; screen_p=screen_chars[b_cur_y]; } *char_p++=c; --n_chars_read; } *char_p++=NEWLINE_CHAR; } } int w_get_char (void) { int c; #ifdef MAYBE_USE_STDIO if (use_stdio){ c=getchar(); return swap_nl_cr (c); } #endif if (input_buffer_length==0){ GrafPtr port; #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (c_window)); #else port=NULL; if (qd.thePort!=c_window){ port=qd.thePort; SetPort (c_window); } #endif if (!console_window_visible) make_console_window_visible(); w_read_line(); #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } c=input_buffer[input_buffer_pos] & 0xff; ++input_buffer_pos; --input_buffer_length; return c; } unsigned long w_get_string (char *string,unsigned long max_length) { unsigned long length; #ifdef MAYBE_USE_STDIO if (use_stdio){ int i; length=fread (string,1,max_length,stdin); for (i=0; i=256) result=0; #ifdef MAYBE_USE_STDIO if (use_stdio){ if (c!=EOF) ungetc (swap_nl_cr (c),stdin); } else { #endif --input_buffer_pos; ++input_buffer_length; #ifdef MAYBE_USE_STDIO } #endif *r_p=0.0; if (result){ s[n]='\0'; #if !defined (G_POWER) result=convert_string_to_real (s,r_p); #else if (sscanf (s,"%lg",r_p)!=1) result=0; #endif } return result; } unsigned long w_get_text (char *string,unsigned long max_length) { unsigned long length,l; char *sp,*dp; GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ int length; fgets (string,(int)max_length,stdin); for (length=0; lengthmax_length) length=max_length; for (l=length,sp=&input_buffer[input_buffer_pos],dp=string; l!=0; --l) *dp++=*sp++; input_buffer_pos+=length; input_buffer_length-=length; #ifndef MACOSX if (port!=NULL) #endif SetPort (port); return length; } void w_print_string (char *s) { char *end_s,c; GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ int c; flockfile (stdin); while ((c=*s)!='\0'){ putchar_unlocked (swap_nl_cr (c)); ++s; } funlockfile (stdin); return; } #endif #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (c_window)); #else port=NULL; if (qd.thePort!=c_window){ port=qd.thePort; SetPort (c_window); } #endif if (!console_window_visible) make_console_window_visible(); end_s=s; while (*s!='\0'){ while (c=*end_s,c!='\0' && c!=NEWLINE_CHAR) ++end_s; w_print_text_without_newlines (s,end_s-s); if (*end_s=='\0') break; print_newline(); s=++end_s; } #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } void ew_print_string (char *s) { char *end_s,c; GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ int c; flockfile (stderr); while ((c=*s)!='\0'){ putc_unlocked (swap_nl_cr (c),stderr); ++s; } funlockfile (stderr); return; } #endif #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (e_window)); #else port=NULL; if (qd.thePort!=e_window){ port=qd.thePort; SetPort (e_window); } #endif if (!error_window_visible) make_error_window_visible(); end_s=s; while (*s!='\0'){ while (c=*end_s,c!='\0' && c!=NEWLINE_CHAR) ++end_s; e_print_text_without_newlines (s,end_s-s); if (*end_s=='\0') break; e_print_newline(); s=++end_s; } #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } #if !defined (G_POWER) extern char *convert_int_to_string (char *string,int i); extern char *convert_real_to_string (char *string,double *r_p); extern int convert_string_to_real (char *string,double *r_p); #endif void w_print_int (int n) { char int_string [32]; GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ printf ("%d",n); return; } #endif #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (c_window)); #else port=NULL; if (qd.thePort!=c_window){ port=qd.thePort; SetPort (c_window); } #endif if (!console_window_visible) make_console_window_visible(); #if !defined (G_POWER) { char *end_p; end_p=convert_int_to_string (int_string,n); w_print_text_without_newlines (int_string,end_p-int_string); } #else sprintf (int_string,"%d",n); { int string_length; char *p; string_length=0; for (p=int_string; *p; ++p) ++string_length; w_print_text_without_newlines (int_string,string_length); } #endif #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } void ew_print_int (int n) { char int_string [32]; GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ fprintf (stderr,"%d",n); return; } #endif #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (e_window)); #else port=NULL; if (qd.thePort!=e_window){ port=qd.thePort; SetPort (e_window); } #endif if (!error_window_visible) make_error_window_visible(); #if !defined (G_POWER) { char *end_p; end_p=convert_int_to_string (int_string,n); e_print_text_without_newlines (int_string,end_p-int_string); } #else sprintf (int_string,"%d",n); { int string_length; char *p; string_length=0; for (p=int_string; *p; ++p) ++string_length; e_print_text_without_newlines (int_string,string_length); } #endif #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } void w_print_real (double r) { char real_string [40]; GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ printf ("%.15g",r); return; } #endif #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (c_window)); #else port=NULL; if (qd.thePort!=c_window){ port=qd.thePort; SetPort (c_window); } #endif if (!console_window_visible) make_console_window_visible(); #if !defined (G_POWER) { char *end_p; end_p=convert_real_to_string (real_string,&r); w_print_text_without_newlines (real_string,end_p-real_string); } #else sprintf (real_string,"%.15g",r); { int string_length; char *p; string_length=0; for (p=real_string; *p; ++p) ++string_length; w_print_text_without_newlines (real_string,string_length); } #endif #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } void ew_print_real (double r) { char real_string [40]; GrafPtr port; #ifdef MAYBE_USE_STDIO if (use_stdio){ fprintf (stderr,"%.15g",r); return; } #endif #ifdef MACOSX GetPort (&port); SetPort (GetWindowPort (e_window)); #else port=NULL; if (qd.thePort!=e_window){ port=qd.thePort; SetPort (e_window); } #endif if (!error_window_visible) make_error_window_visible(); #if !defined (G_POWER) { char *end_p; end_p=convert_real_to_string (real_string,&r); e_print_text_without_newlines (real_string,end_p-real_string); } #else sprintf (real_string,"%.15g",r); { int string_length; char *p; string_length=0; for (p=real_string; *p; ++p) ++string_length; e_print_text_without_newlines (real_string,string_length); } #endif #ifndef MACOSX if (port!=NULL) #endif SetPort (port); } static FontInfo font_info; static short font_id,font_size; long stack_size,heap_size,flags; #ifdef WRITE_HEAP long min_write_heap_size=0; #endif; #ifdef G_POWER long heap_size_multiple; long initial_heap_size; #endif static int init_terminal() { int n; int screen_top,screen_left,screen_bottom,screen_right; int screen_width,screen_height,left_right_free,top_bottom_free; int three,ten; #ifndef NO_INIT # ifdef MAYBE_USE_STDIO if (use_stdio){ FlushEvents (everyEvent,0); InitCursor(); error_window_visible=0; console_window_visible=0; return 1; } # endif # ifndef MACOSX InitGraf (&qd.thePort); InitFonts(); # endif FlushEvents (everyEvent,0); # ifndef MACOSX InitWindows(); # endif InitCursor(); # ifndef MACOSX InitMenus(); # endif #endif three=3; ten=10; /* to get a divw instead of a divl */ #ifdef MACOSX { BitMap bit_map; GetQDGlobalsScreenBits (&bit_map); screen_top=bit_map.bounds.top; screen_left=bit_map.bounds.left; screen_bottom=bit_map.bounds.bottom; screen_right=bit_map.bounds.right; } #else screen_top=qd.thePort->portRect.top; screen_left=qd.thePort->portRect.left; screen_bottom=qd.thePort->portRect.bottom; screen_right=qd.thePort->portRect.right; #endif screen_top+=15; /* menu bar height */ screen_width=screen_right-screen_left+1; screen_height=screen_bottom-screen_top+1; left_right_free=UDIVW (screen_width>>2,three); /* /12 */ top_bottom_free=12; c_window_rect.left=screen_left+left_right_free; c_window_rect.right=screen_right-left_right_free; c_window_rect.top=screen_top+20+top_bottom_free; c_window_rect.bottom=screen_top+UDIVW (screen_height*7,ten)-6; c_local_window_rect.left=0; c_local_window_rect.right=c_window_rect.right-c_window_rect.left; c_local_window_rect.top=0; c_local_window_rect.bottom=c_window_rect.bottom-c_window_rect.top; e_window_rect.left=screen_left+left_right_free; e_window_rect.right=screen_right-left_right_free; e_window_rect.top=screen_top+20+UDIVW (screen_height*7,ten)+6; e_window_rect.bottom=screen_bottom-top_bottom_free; e_local_window_rect.left=0; e_local_window_rect.right=e_window_rect.right-e_window_rect.left; e_local_window_rect.top=0; e_local_window_rect.bottom=e_window_rect.bottom-e_window_rect.top; c_window_width=c_window_rect.right-c_window_rect.left+1; c_window_height=c_window_rect.bottom-c_window_rect.top+1; e_window_width=c_window_rect.right-e_window_rect.left+1; e_window_height=e_window_rect.bottom-e_window_rect.top+1; error_window_visible=0; console_window_visible=flags & 16 ? 0 : 1; c_window=NewWindow (NULL,&c_window_rect,"\pConsole",console_window_visible,0,(WindowPtr)-1,0,CONSOLE_WINDOW_ID); if (c_window==NULL) return 0; e_window=NewWindow (NULL,&e_window_rect,"\pMessages",0,0,(WindowPtr)-1,0,ERROR_WINDOW_ID); if (e_window==NULL) return 0; #ifdef MACOSX SetPort (GetWindowPort (e_window)); #else SetPort (e_window); #endif TextFont (font_id); TextSize (font_size); GetFontInfo (&font_info); char_ascent=font_info.ascent; char_descent=font_info.descent; char_leading=font_info.leading; char_asc_lead=char_ascent+char_leading; char_height=char_asc_lead+char_descent; e_cur_y=0; e_cur_x=0; e_g_cur_x=0; n_e_screen_lines=UDIVW (e_window_height,char_height); MoveTo (0,char_asc_lead); #ifdef MACOSX SetPort (GetWindowPort (c_window)); #else SetPort (c_window); #endif TextFont (font_id); TextSize (font_size); cur_y=0; cur_x=0; g_cur_x=0; n_screen_lines=UDIVW (c_window_height,char_height); MoveTo (0,char_asc_lead); if (console_window_visible){ SelectWindow (c_window); #ifdef MACOSX ValidWindowRect (c_window,&c_local_window_rect); #else ValidRect (&c_local_window_rect); #endif } screen_chars=(SCREEN_LINE_CHARS*) NewPtr (n_screen_lines * (MAX_N_COLUMNS+1)); if (screen_chars==NULL) return 0; for (n=0; n #ifndef MACOSX SysEnvRec system_environment; # ifndef powerc #pragma parameter __D0 MySysEnvirons (__D0, __A0) extern pascal OSErr MySysEnvirons(short versionRequested, SysEnvRec *theWorld) ONEWORDINLINE(0xA090); # else #define MySysEnvirons SysEnvirons # endif #endif #define MINIMUM_HEAP_SIZE_MULTIPLE ((2*256)+128) #define MAXIMUM_HEAP_SIZE_MULTIPLE (100*256) void (*exit_tcpip_function) (void); #ifndef MACHO extern void my_pointer_glue (void (*function) (void)); #endif int execution_aborted; #ifdef STACK_OVERFLOW_EXCEPTION_HANDLER int *a_stack_guard_page,*b_stack_guard_page; void *allocate_a_stack (int size) { int alloc_size; char *p,*end_p; alloc_size=(size+4096+4095) & -4096; # ifdef MACHO p=malloc (alloc_size); # else p=NewPtr (alloc_size); # endif if (p==NULL) return NULL; end_p=(char*)(((int)p+size+4095) & -4096); vm_protect (mach_task_self(),(int)end_p,4096,0,0); a_stack_guard_page=(int*)end_p; return (void*)((int)end_p-size); } extern int *halt_sp; extern void stack_overflow (void); #ifndef MACHO_EXCEPTIONS struct sigaction old_BUS_sa,old_SEGV_sa; static void clean_exception_handler (int sig,void *sip,struct sigcontext *scp) { struct sigaction *old_sa_p; unsigned int instruction; int *registers,a; instruction=*(unsigned int*)(scp->sc_ir); registers = &((int *)scp->sc_regs)[2]; switch (instruction>>26){ case 36: /* stw */ case 37: /* stwu */ case 38: /* stb */ case 39: /* stbu */ case 44: /* sth */ case 45: /* sthu */ case 47: /* stmw */ case 54: /* stfd */ case 55: /* stfdu */ { int reg_a,a_aligned_4k; reg_a=(instruction>>16) & 31; a=(short)instruction; if (reg_a) a+=registers[reg_a]; a_aligned_4k = (int)a & -4096; if (a_aligned_4k==(int)b_stack_guard_page || a_aligned_4k==(int)a_stack_guard_page){ scp->sc_ir = (int)&stack_overflow; registers[1]=(int)halt_sp; return; } } } old_sa_p = sig==SIGBUS ? &old_BUS_sa : &old_SEGV_sa; if (old_sa_p->sa_handler==SIG_DFL || old_sa_p->sa_handler==SIG_IGN) sigaction (sig,old_sa_p,NULL); else # ifdef MACHO old_sa_p->sa_handler (sig,sip,scp); # else call_function_3 (sig,sip,scp,old_sa_p->sa_handler); # endif } #else # define N_OLD_EXCEPTION_PORTS 64 static mach_msg_type_number_t n_ports; static exception_mask_t old_exception_masks[N_OLD_EXCEPTION_PORTS]; static exception_handler_t old_exception_handlers[N_OLD_EXCEPTION_PORTS]; static exception_behavior_t old_exception_behaviors[N_OLD_EXCEPTION_PORTS]; static thread_state_flavor_t old_thread_state_flavors[N_OLD_EXCEPTION_PORTS]; static mach_port_t exception_port; static kern_return_t forward_exception (mach_port_t thread,mach_port_t task,exception_type_t exception,exception_data_t code,mach_msg_type_number_t code_count) { exception_mask_t exception_mask; exception_behavior_t behavior; int port_n; exception_mask=1<msgh_size,0,msg->msgh_local_port,0,MACH_PORT_NULL)!=KERN_SUCCESS){ /* printf ("mach_msg failed\n"); */ exit (1); } } } #endif # ifndef MACHO extern int *get_TOC (void); # endif static void install_clean_exception_handler (void) { { struct vm_region_basic_info vm_region_info; # ifdef MACHO vm_address_t vm_address,previous_address; mach_msg_type_number_t info_count; memory_object_name_t object_name; vm_size_t vm_size; # else int vm_address,previous_address; int info_count; int object_name; int vm_size; int *stack_top; # endif int r,var_on_stack; vm_address=(int)&var_on_stack; info_count=sizeof (vm_region_info); # ifdef MACHO r=vm_region (mach_task_self(),&vm_address,&vm_size,VM_REGION_BASIC_INFO,(vm_region_info_t)&vm_region_info,&info_count,&object_name); # else r=vm_region (mach_task_self(),&vm_address,&vm_size,10,(void*)&vm_region_info,&info_count,&object_name); # endif if (r!=0) return; # ifndef MACHO stack_top=(int*)(vm_address+vm_size); # endif do { previous_address=vm_address; vm_address=vm_address-1; info_count=sizeof (vm_region_info); # ifdef MACHO r=vm_region (mach_task_self(),&vm_address,&vm_size,VM_REGION_BASIC_INFO,(vm_region_info_t)&vm_region_info,&info_count,&object_name); # else r=vm_region (mach_task_self(),&vm_address,&vm_size,10,(void*)&vm_region_info,&info_count,&object_name); # endif } while (vm_address!=previous_address && r==0); b_stack_guard_page=(int*)((int)previous_address-4096); # ifndef MACHO { int stack_size_aligned_4k; stack_size_aligned_4k = (stack_size+4095) & -4096; if ((unsigned int)b_stack_guard_page < (unsigned int)((int)stack_top-stack_size_aligned_4k-4096)){ b_stack_guard_page=(int*)((int)stack_top-stack_size_aligned_4k-4096); vm_protect (mach_task_self(),(int)b_stack_guard_page,4096,0,0); } } # endif } # ifndef MACHO_EXCEPTIONS { struct sigaltstack sa_stack; void *signal_stack; struct sigaction sa; # ifdef MACHO signal_stack=(int*)malloc (MINSIGSTKSZ); # else signal_stack=(int*)NewPtr (8192); # endif if (signal_stack!=NULL){ # ifndef MACHO int *handler_trampoline; # endif sa_stack.ss_sp=signal_stack; # ifdef MACHO sa_stack.ss_size=MINSIGSTKSZ; # else sa_stack.ss_size=8192; # endif sa_stack.ss_flags=0; sigaltstack (&sa_stack,NULL); # ifdef MACHO sa.sa_handler=&clean_exception_handler; sigemptyset (&sa.sa_mask); sa.sa_flags=SA_ONSTACK;//SA_SIGINFO; # else handler_trampoline = (int*) NewPtr (24); if (handler_trampoline!=NULL){ int *handler_address,*toc_register; handler_address=*(int**)&clean_exception_handler; toc_register=get_TOC(); # define i_dai_i(i,rd,ra,si)((i<<26)|((rd)<<21)|((ra)<<16)|((unsigned short)(si))) # define addis_i(rd,ra,si) i_dai_i (15,rd,ra,si) # define addi_i(rd,ra,si) i_dai_i (14,rd,ra,si) # define lis_i(rd,si) addis_i (rd,0,si) # define bctr_i() ((19<<26)|(20<<21)|(528<<1)) # define mtspr_i(spr,rs) ((31<<26)|((rs)<<21)|(spr<<16)|(467<<1)) # define mtctr_i(rs) mtspr_i (9,rs) handler_trampoline[0]=lis_i (6,((int)handler_address-(short)handler_address)>>16); handler_trampoline[1]=addi_i (6,6,(short)handler_address); handler_trampoline[2]=mtctr_i (6); handler_trampoline[3]=lis_i (2,((int)toc_register-(short)toc_register)>>16); handler_trampoline[4]=addi_i (2,2,(short)toc_register); handler_trampoline[5]=bctr_i(); __icbi (handler_trampoline,0); __icbi (handler_trampoline,20); sa.sa_handler=(void(*)())handler_trampoline; sa.sa_mask=0; sa.sa_flags=1; } # endif sigaction (SIGSEGV,&sa,&old_SEGV_sa); sigaction (SIGBUS,&sa,&old_BUS_sa); } } #else { mach_port_t my_mach_task; pthread_attr_t attr; pthread_t pthread; my_mach_task=mach_task_self(); if (mach_port_allocate (my_mach_task,MACH_PORT_RIGHT_RECEIVE,&exception_port)!=KERN_SUCCESS){ /* printf ("mach_port_allocate failed\n"); */ return; } if (mach_port_insert_right (my_mach_task,exception_port,exception_port,MACH_MSG_TYPE_MAKE_SEND)!=KERN_SUCCESS){ /* printf ("mach_port_insert_right failed\n"); */ return; } if (task_get_exception_ports (my_mach_task,EXC_MASK_BAD_ACCESS,old_exception_masks,&n_ports,old_exception_handlers,old_exception_behaviors,old_thread_state_flavors)!=KERN_SUCCESS){ /* printf ("task_get_exception_ports failed\n"); */ return; } if (task_set_exception_ports (my_mach_task,EXC_MASK_BAD_ACCESS,exception_port,EXCEPTION_DEFAULT,MACHINE_THREAD_STATE)!=KERN_SUCCESS){ /* printf ("task_get_exception_ports failed\n"); */ return; } if (pthread_attr_init (&attr)!=0){ /* printf ("pthread_attr_init failed\n"); */ return; } if (pthread_attr_setdetachstate (&attr,PTHREAD_CREATE_DETACHED)!=0){ /* printf ("pthread_attr_setdetach_state failed\n"); */ return; } if (pthread_create (&pthread,&attr,my_pthread,NULL)!=0){ /* printf ("pthread_create failed\n"); */ return; } if (pthread_attr_destroy (&attr)!=0){ /* printf ("pthread_attr_destroy failed\n"); */ return; } } # endif } #endif #ifdef MACHO int global_argc; char **global_argv; int return_code; int main (int argc, char **argv) #else int main (void) #endif { Handle stack_handle,font_handle; #ifdef WRITE_HEAP Handle profile_handle; #endif long *stack_p; #ifdef MACHO global_argc = argc; global_argv = argv; return_code=0; #endif #ifdef MAYBE_USE_STDIO { int i; use_stdio=1; for (i=1; i1024) n_processors=1024; #else # ifdef G_POWER heap_size_multiple=stack_p[1]; if (heap_size_multipleMAXIMUM_HEAP_SIZE_MULTIPLE) heap_size_multiple=MAXIMUM_HEAP_SIZE_MULTIPLE; initial_heap_size=(stack_p[4]+7) & ~7; # endif #endif #ifndef MACOSX # ifndef PARALLEL SetApplLimit (GetApplLimit()-stack_size-1024); # else SetApplLimit (GetApplLimit()-heap_size-stack_size-1024); # endif if (MemError()!=0) return 0; #endif #ifdef PARALLEL load_code_segments(); #endif font_id=-1; font_handle=GetResource ('Font',128); if (font_handle!=NULL){ get_font_number ((char*)((*(short **)font_handle)+1)); font_size=**(short**)font_handle; } if (font_id==-1){ #ifdef NEW_HEADERS font_id=kFontIDMonaco; #else font_id=monaco; #endif font_size=9; } if (!init_terminal()) return 1; #ifdef G_POWER wait_next_event_available=1; #else # ifdef powerc if (NGetTrapAddress (0xA860,ToolTrap)!=GetTrapAddress (0xA89F)) # else if (GetToolTrapAddress (0xA860)!=GetTrapAddress (0xA89F)) # endif wait_next_event_available=-1; else wait_next_event_available=0; #endif #ifndef MACOSX if (MySysEnvirons (1,&system_environment)==noErr){ # ifndef G_POWER switch (target_processor){ case 2: if (system_environment.processor==env68000 || system_environment.processor==env68010 || system_environment.hasFPU==0) { ew_print_string ("This program requires a MC68020 processor with MC68881 coprocessor or better\n"); wait_for_key_press(); exit_terminal(); return 0; } break; case 1: if (system_environment.processor==env68000 || system_environment.processor==env68010) { ew_print_string ("This program requires a MC68020 processor or better\n"); wait_for_key_press(); exit_terminal(); return 0; } } # endif } #endif #ifdef SIMULATE processor_table_size=n_processors*64; processor_table=(int) NewPtr (processor_table_size); end_processor_table=processor_table+processor_table_size; #endif #ifdef COMMUNICATION if (init_communication()) #endif abc_main(); #ifdef COMMUNICATION exit_communication(); #endif if (exit_tcpip_function!=NULL) #ifdef MACHO exit_tcpip_function(); #else my_pointer_glue (exit_tcpip_function); #endif if (!(flags & 16) || (flags & 8) || execution_aborted!=0){ #ifdef COMMUNICATION if (my_processor_id==0) #endif wait_for_key_press(); } exit_terminal(); #ifdef G_POWER first_function(); #endif #ifdef MACHO if (return_code==0 && execution_aborted!=0) return_code= -1; return return_code; #else return 0; #endif } #if defined (TIME_PROFILE) || defined (MACHO) void create_profile_file_name (unsigned char *profile_file_name) { unsigned char *cur_ap_name,*end_profile_file_name; int cur_ap_name_length,profile_file_name_length,n; cur_ap_name=(unsigned char *)LMGetCurApName(); cur_ap_name_length=cur_ap_name[0]; ++cur_ap_name; for (n=0; n31) profile_file_name_length=31; *((unsigned int*)&profile_file_name[4])=profile_file_name_length; end_profile_file_name=&profile_file_name[8+profile_file_name_length]; end_profile_file_name[-13]=' '; end_profile_file_name[-12]='T'; end_profile_file_name[-11]='i'; end_profile_file_name[-10]='m'; end_profile_file_name[-9]='e'; end_profile_file_name[-8]=' '; end_profile_file_name[-7]='P'; end_profile_file_name[-6]='r'; end_profile_file_name[-5]='o'; end_profile_file_name[-4]='f'; end_profile_file_name[-3]='i'; end_profile_file_name[-2]='l'; end_profile_file_name[-1]='e'; } #endif #if defined(G_POWER) static void my_user_item_proc (DialogPtr dialog_p,int the_item) { short item_type; Handle item_handle; Rect item_rect; PenState pen_state; GetDialogItem (dialog_p,the_item,&item_type,&item_handle,&item_rect); GetPenState (&pen_state); PenNormal(); PenSize (3,3); InsetRect (&item_rect,-4,-4); FrameRoundRect (&item_rect,16,16); SetPenState (&pen_state); } #if defined (MACOSX) && !defined (NEW_HEADERS) extern UserItemUPP NewUserItemUPP (ProcPtr); #endif #ifdef NEW_HEADERS int #else UserItemUPP #endif myoutlinebuttonfunction (void) { #ifdef MACOSX return NewUserItemUPP (my_user_item_proc); #else return NewUserItemProc (my_user_item_proc); #endif } #ifndef NEW_HEADERS QDGlobals *qdglobals (void) { return &qd; } #endif #endif