Browse Source

+ support for djgpp v2.03 (added some new functions that are in v2.03 ofdpmiexcp.c)
+ code to integrate exception support inside the system unit

pierre 25 years ago
parent
commit
991b0d8b09
3 changed files with 996 additions and 364 deletions
  1. 630 50
      rtl/go32v2/dpmiexcp.pp
  2. 360 312
      rtl/go32v2/exceptn.as
  3. 6 2
      rtl/go32v2/system.pp

+ 630 - 50
rtl/go32v2/dpmiexcp.pp

@@ -13,10 +13,10 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
  **********************************************************************}
-
+{$ifndef IN_SYSTEM}
 {$GOTO ON}
-
-Unit DPMIExcp;
+{$define IN_DPMIEXCP_UNIT}
+Unit DpmiExcp;
 
 { If linking to C code we must avoid loading of the dpmiexcp.o
   in libc.a from the equivalent C code
@@ -24,17 +24,29 @@ Unit DPMIExcp;
 
   Problem this is only valid for DJGPP v2.01 }
 
+
 interface
 
 uses
   go32;
 
+{$endif ndef IN_SYSTEM}
 { No stack checking ! }
 {$S-}
 
 
+{$ifdef EXCEPTIONS_IN_SYSTEM}
+{$ifdef IN_DPMIEXCP_UNIT}
+{$undef CREATE_C_FUNCTIONS}
+{$else not IN_DPMIEXCP_UNIT}
+{$define CREATE_C_FUNCTIONS}
+{$endif ndef IN_DPMIEXCP_UNIT}
+{$else not EXCEPTIONS_IN_SYSTEM}
+{$define CREATE_C_FUNCTIONS}
+{$endif not EXCEPTIONS_IN_SYSTEM}
 { Error Messages }
-function do_faulting_finish_message : integer;
+function do_faulting_finish_message(fake : boolean) : integer;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 
 { SetJmp/LongJmp }
 type
@@ -48,7 +60,9 @@ type
       exception_ptr : pdpmi_jmp_buf;  { pointer to previous exception if exists }
   end;
 function dpmi_setjmp(var rec : dpmi_jmp_buf) : longint;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 procedure dpmi_longjmp(var rec : dpmi_jmp_buf;return_value : longint);
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 
 { Signals }
 const
@@ -76,15 +90,20 @@ const
   SIG_UNBLOCK = 3;
 
 function SIG_DFL( x: longint) : longint;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 function SIG_ERR( x: longint) : longint;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 function SIG_IGN( x: longint) : longint;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 
 type
   SignalHandler  = function (v : longint) : longint;
   PSignalHandler = ^SignalHandler; { to be compatible with linux.pp }
 
 function signal(sig : longint;func : SignalHandler) : SignalHandler;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 function _raise(sig : longint) : longint;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 
 { Exceptions }
 type
@@ -100,22 +119,50 @@ type
   end;
 
 procedure djgpp_exception_toggle;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 procedure djgpp_exception_setup;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 function  djgpp_exception_state : pexception_state;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 function  djgpp_set_ctrl_c(enable : boolean) : boolean;
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
 
 { Other }
 function dpmi_set_coprocessor_emulation(flag : longint) : longint;
-
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
+function __djgpp_set_sigint_key(new_key : longint) : longint;
+{$ifdef CREATE_C_FUNCTIONS}cdecl;{$endif CREATE_C_FUNCTIONS}
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
+function __djgpp_set_sigquit_key(new_key : longint) : longint;
+{$ifdef CREATE_C_FUNCTIONS}cdecl;{$endif CREATE_C_FUNCTIONS}
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
+function __djgpp__traceback_exit(sig : longint) : longint;
+{$ifdef CREATE_C_FUNCTIONS}cdecl;{$endif CREATE_C_FUNCTIONS}
+{$ifdef IN_SYSTEM}forward;{$endif IN_SYSTEM}
+
+{$ifndef IN_SYSTEM}
 implementation
+{$endif IN_SYSTEM}
 
 {$asmmode ATT}
 
+{$ifdef CREATE_C_FUNCTIONS}
 {$L exceptn.o}
+{$endif CREATE_C_FUNCTIONS}
 
+{$ifndef CREATE_C_FUNCTIONS}
+procedure djgpp_exception_toggle;
+external name '___djgpp_exception_toggle';
+procedure djgpp_exception_setup;
+external name '___djgpp_exception_setup';
+function __djgpp_set_sigint_key(new_key : longint) : longint;
+external name '___djgpp_set_sigint_key';
+function __djgpp_set_sigquit_key(new_key : longint) : longint;
+external name '___djgpp_set_sigquit_key';
+{$endif CREATE_C_FUNCTIONS}
 var
-  v2prt0_ds_alias : pointer;external name '___v2prt0_ds_alias';
-  djgpp_ds_alias  : pointer;external name '___djgpp_ds_alias';
+  v2prt0_ds_alias : word;external name '___v2prt0_ds_alias';
+  djgpp_ds_alias  : word;external name '___djgpp_ds_alias';
   djgpp_exception_state_ptr : pexception_state;external name '___djgpp_exception_state_ptr';
   endtext        : longint;external name '_etext';
   starttext       : longint;external name 'start';
@@ -125,6 +172,7 @@ var
   djgpp_hwint_flags : longint;external name '___djgpp_hwint_flags';
   djgpp_dos_sel : word;external name '___djgpp_dos_sel';
   djgpp_exception_table : array[0..0] of pointer;external name '___djgpp_exception_table';
+  dosmemselector : word;external name '_core_selector';
 
 procedure djgpp_i24;external name '___djgpp_i24';
 procedure djgpp_iret;external name '___djgpp_iret';
@@ -144,6 +192,226 @@ const
   exception_level : longint = 0;
 
 
+{$ifndef IN_DPMIEXCP_UNIT}
+{****************************************************************************
+          DPMI functions copied from go32 unit
+****************************************************************************}
+
+const
+  int31error : word = 0;
+
+    procedure test_int31(flag : longint);
+      begin
+         asm
+            pushl %ebx
+            movw  $0,INT31ERROR
+            movl  flag,%ebx
+            testb $1,%bl
+            jz    .Lti31_1
+            movw  %ax,INT31ERROR
+            xorl  %eax,%eax
+            jmp   .Lti31_2
+            .Lti31_1:
+            movl  $1,%eax
+            .Lti31_2:
+            popl  %ebx
+         end;
+      end;
+
+    function set_pm_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
+
+      begin
+         asm
+            movl intaddr,%eax
+            movl (%eax),%edx
+            movw 4(%eax),%cx
+            movl $0x212,%eax
+            movb e,%bl
+            int $0x31
+            pushf
+            call test_int31
+            movb %al,__RESULT
+         end;
+      end;
+
+    function set_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
+
+      begin
+         asm
+            movl intaddr,%eax
+            movl (%eax),%edx
+            movw 4(%eax),%cx
+            movl $0x203,%eax
+            movb e,%bl
+            int $0x31
+            pushf
+            call test_int31
+            movb %al,__RESULT
+         end;
+      end;
+
+    function get_pm_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
+
+      begin
+         asm
+            movl $0x210,%eax
+            movb e,%bl
+            int $0x31
+            pushf
+            call test_int31
+            movb %al,__RESULT
+            movl intaddr,%eax
+            movl %edx,(%eax)
+            movw %cx,4(%eax)
+         end;
+      end;
+
+    function get_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
+
+      begin
+         asm
+            movl $0x202,%eax
+            movb e,%bl
+            int $0x31
+            pushf
+            call test_int31
+            movb %al,__RESULT
+            movl intaddr,%eax
+            movl %edx,(%eax)
+            movw %cx,4(%eax)
+         end;
+      end;
+
+    function get_segment_base_address(d : word) : longint;
+
+      begin
+         asm
+            movw d,%bx
+            movl $6,%eax
+            int $0x31
+            xorl %eax,%eax
+            movw %dx,%ax
+            shll $16,%ecx
+            orl %ecx,%eax
+            movl %eax,__RESULT
+         end;
+      end;
+
+    function get_segment_limit(d : word) : longint;
+
+      begin
+         asm
+            movzwl d,%eax
+            lsl %eax,%eax
+            jz .L_ok2
+            xorl %eax,%eax
+         .L_ok2:
+            movl %eax,__RESULT
+         end;
+      end;
+
+    function set_rm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
+
+      begin
+         asm
+            movl intaddr,%eax
+            movw (%eax),%dx
+            movw 4(%eax),%cx
+            movl $0x201,%eax
+            movb vector,%bl
+            int $0x31
+            pushf
+            call test_int31
+            movb %al,__RESULT
+         end;
+      end;
+
+    function get_rm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
+
+      begin
+         asm
+            movb vector,%bl
+            movl $0x200,%eax
+            int $0x31
+            pushf
+            call test_int31
+            movb %al,__RESULT
+            movl intaddr,%eax
+            movzwl %dx,%edx
+            movl %edx,(%eax)
+            movw %cx,4(%eax)
+         end;
+      end;
+
+
+    function free_rm_callback(var intaddr : tseginfo) : boolean;
+      begin
+         asm
+            movl intaddr,%eax
+            movw (%eax),%dx
+            movw 4(%eax),%cx
+            movl $0x304,%eax
+            int $0x31
+            pushf
+            call test_int31
+            movb %al,__RESULT
+         end;
+      end;
+
+    function get_rm_callback(pm_func : pointer;const reg : trealregs;var rmcb : tseginfo) : boolean;
+      begin
+         asm
+            movl  pm_func,%esi
+            movl  reg,%edi
+            pushw %es
+            movw  v2prt0_ds_alias,%ax
+            movw  %ax,%es
+            pushw %ds
+            movw  %cs,%ax
+            movw  %ax,%ds
+            movl  $0x303,%eax
+            int   $0x31
+            popw  %ds
+            popw  %es
+            pushf
+            call test_int31
+            movb %al,__RESULT
+            movl  rmcb,%eax
+            movzwl %dx,%edx
+            movl  %edx,(%eax)
+            movw  %cx,4(%eax)
+         end;
+      end;
+
+    function lock_linear_region(linearaddr, size : longint) : boolean;
+
+      begin
+          asm
+            movl  $0x600,%eax
+            movl  linearaddr,%ecx
+            movl  %ecx,%ebx
+            shrl  $16,%ebx
+            movl  size,%esi
+            movl  %esi,%edi
+            shrl  $16,%esi
+            int   $0x31
+            pushf
+            call test_int31
+            movb %al,__RESULT
+          end;
+      end;
+
+    function lock_code(functionaddr : pointer;size : longint) : boolean;
+
+      var
+         linearaddr : longint;
+
+      begin
+         linearaddr:=longint(functionaddr)+get_segment_base_address(get_cs);
+         lock_code:=lock_linear_region(linearaddr,size);
+      end;
+{$endif ndef IN_DPMIEXCP_UNIT}
+
 {****************************************************************************
                                   Helpers
 ****************************************************************************}
@@ -172,7 +440,8 @@ end;
                               SetJmp/LongJmp
 ****************************************************************************}
 
- function c_setjmp(var rec : dpmi_jmp_buf) : longint;[public, alias : '_setjmp'];
+{$ifdef CREATE_C_FUNCTIONS}
+function c_setjmp(var rec : dpmi_jmp_buf) : longint;[public, alias : '_setjmp'];
   begin
   { here we need to be subtle :
     - we need to return with the arg still on the stack
@@ -194,7 +463,7 @@ end;
         jmp     dpmi_setjmp
      end;
   end;
-
+{$endif CREATE_C_FUNCTIONS}
 
 function dpmi_setjmp(var rec : dpmi_jmp_buf) : longint;
 begin
@@ -246,11 +515,13 @@ begin
 end;
 
 
+{$ifdef CREATE_C_FUNCTIONS}
 procedure c_longjmp(var  rec : dpmi_jmp_buf;return_value : longint);[public, alias : '_longjmp'];
   begin
      dpmi_longjmp(rec,return_value);
      { never gets here !! so pascal stack convention is no problem }
   end;
+{$endif CREATE_C_FUNCTIONS}
 
 procedure dpmi_longjmp(var  rec : dpmi_jmp_buf;return_value : longint);[alias : 'FPC_longjmp'];
 begin
@@ -309,41 +580,49 @@ end;
 ****************************************************************************}
 
 var
-  signal_list : Array[0..SIGMAX] of SignalHandler;
+  signal_list : Array[0..SIGMAX] of SignalHandler;cvar;
+  {$ifndef CREATE_C_FUNCTIONS}external;{$endif}
 
-function SIG_ERR(x:longint):longint;
+{$ifdef CREATE_C_FUNCTIONS}
+function SIG_ERR(x:longint):longint;[public,alias : '___djgpp_SIG_ERR'];
 begin
   SIG_ERR:=-1;
 end;
 
 
-function SIG_IGN(x:longint):longint;
+function SIG_IGN(x:longint):longint;[public,alias : '___djgpp_SIG_IGN'];
 begin
   SIG_IGN:=-1;
 end;
 
 
-function SIG_DFL(x:longint):longint;
+function SIG_DFL(x:longint):longint;[public,alias : '___djgpp_SIG_DFL'];
 begin
   SIG_DFL:=0;
 end;
 
+{$else CREATE_C_FUNCTIONS}
+function SIG_ERR(x:longint):longint;external name '___djgpp_SIG_ERR';
+function SIG_IGN(x:longint):longint;external name '___djgpp_SIG_IGN';
+function SIG_DFL(x:longint):longint;external name '___djgpp_SIG_DFL';
+{$endif CREATE_C_FUNCTIONS}
 
 function signal(sig : longint;func : SignalHandler) : SignalHandler;
 var
   temp : SignalHandler;
 begin
-  if ((sig <= 0) or (sig > SIGMAX) or (sig = SIGKILL)) then
+  if ((sig < 0) or (sig > SIGMAX) or (sig = SIGKILL)) then
    begin
      signal:=@SIG_ERR;
      runerror(201);
    end;
-  temp := signal_list[sig - 1];
-  signal_list[sig - 1] := func;
+  temp := signal_list[sig];
+  signal_list[sig] := func;
   signal:=temp;
 end;
 
 
+{$ifdef CREATE_C_FUNCTIONS}
 { C counter part }
 function c_signal(sig : longint;func : SignalHandler) : SignalHandler;cdecl;[public,alias : '_signal'];
 var
@@ -352,6 +631,7 @@ begin
   temp:=signal(sig,func);
   c_signal:=temp;
 end;
+{$endif CREATE_C_FUNCTIONS}
 
 
 const
@@ -359,20 +639,8 @@ const
     'ABRT','FPE ','ILL ','SEGV','TERM','ALRM','HUP ',
     'INT ','KILL','PIPE','QUIT','USR1','USR2','NOFP','TRAP');
 
-function _raise(sig : longint) : longint;
-var
-  temp : SignalHandler;
-label
-  traceback_exit;
+procedure print_signal_name(sig : longint);
 begin
-  if(sig <= 0) or (sig > SIGMAX) then
-   exit(-1);
-  temp:=signal_list[sig - 1];
-  if (temp = SignalHandler(@SIG_IGN)) then
-   exit(0);
-  if (temp = SignalHandler(@SIG_DFL)) then
-   begin
-traceback_exit:
      if ((sig >= SIGABRT) and (sig <= SIGTRAP)) then
       begin
         err('Exiting due to signal SIG');
@@ -384,7 +652,21 @@ traceback_exit:
         itox(sig, 4);
       end;
      errln('');
-     do_faulting_finish_message();   { Exits, does not return }
+end;
+
+function _raise(sig : longint) : longint;
+var
+  temp : SignalHandler;
+begin
+  if(sig < 0) or (sig > SIGMAX) then
+   exit(-1);
+  temp:=signal_list[sig];
+  if (temp = SignalHandler(@SIG_IGN)) then
+   exit(0);
+  if (temp = SignalHandler(@SIG_DFL)) then
+   begin
+     print_signal_name(sig);
+     do_faulting_finish_message(djgpp_exception_state<>nil);   { Exits, does not return }
      exit(-1);
    end;
   { this is incompatible with dxegen-dxeload stuff PM }
@@ -392,17 +674,24 @@ traceback_exit:
       (cardinal(temp) > cardinal(@endtext))) then
    begin
      errln('Bad signal handler, ');
-     goto traceback_exit;
+     print_signal_name(sig);
+     do_faulting_finish_message(djgpp_exception_state<>nil);   { Exits, does not return }
+     exit(-1);
    end;
+  { WARNING !!! temp can be a pascal or a C
+    function... thus %esp can be modified here !!!
+    This might be dangerous for some optimizations ?? PM }
   temp(sig);
   exit(0);
 end;
 
 
+{$ifdef CREATE_C_FUNCTIONS}
 function c_raise(sig : longint) : longint;cdecl;[public,alias : '_raise'];
 begin
   c_raise:=_raise(sig);
 end;
+{$endif CREATE_C_FUNCTIONS}
 
 
 {****************************************************************************
@@ -423,6 +712,7 @@ begin
         $78 : exit(SIGTIMR);
         $1b,
         $79 : exit(SIGINT);
+        $7a : exit(SIGQUIT);
       else
         exit(SIGILL);
       end;
@@ -490,16 +780,20 @@ function farpeekb(sel : word;offset : longint) : byte;
 var
   b : byte;
 begin
+{$ifdef IN_DPMIEXCP_UNIT}
   seg_move(sel,offset,get_ds,longint(@b),1);
+{$else not IN_DPMIEXCP_UNIT}
+  sysseg_move(sel,offset,get_ds,longint(@b),1);
+{$endif IN_DPMIEXCP_UNIT}
   farpeekb:=b;
 end;
 
 
 const message_level : byte = 0;
 
-procedure ___exit(c:byte);cdecl;external name '___exit';
+procedure ___exit(c:longint);cdecl;external name '___exit';
 
-function do_faulting_finish_message : integer;
+function do_faulting_finish_message(fake : boolean) : integer;
 var
   en : pchar;
   signum,i : longint;
@@ -541,7 +835,10 @@ begin
 
   if (en = nil) then
     begin
-       err('Exception ');
+       if fake then
+         err('Raised ')
+       else
+         err('Exception ');
        itox(signum, 2);
        err(' at eip=');
        itox(djgpp_exception_state_ptr^.__eip, 8);
@@ -605,7 +902,7 @@ begin
     begin
        errln('First exception occured in another context');
        djgpp_exception_state_ptr:=djgpp_exception_state_ptr^.__exception_ptr;
-       do_faulting_finish_message();
+       do_faulting_finish_message(false);
     end;
 {$endif def DPMIEXCP_DEBUG}
    ;
@@ -613,7 +910,7 @@ begin
 simple_exit:
   if exceptions_on then
     djgpp_exception_toggle;
-  ___exit(1);
+  ___exit(-1);
 end;
 
 
@@ -623,6 +920,7 @@ asm
 end;
 
 
+{$ifdef CREATE_C_FUNCTIONS}
 procedure djgpp_exception_processor;[public,alias : '___djgpp_exception_processor'];
 var
   sig : longint;
@@ -637,7 +935,11 @@ begin
   if (exception_level=1) or (sig=$78) then
     begin
        sig := except_to_sig(sig);
-       _raise(sig);
+       if signal_list[djgpp_exception_state_ptr^.__signum]
+          <>SignalHandler(@SIG_DFL) then
+         _raise(djgpp_exception_state_ptr^.__signum)
+       else
+         _raise(sig);
        if (djgpp_exception_state_ptr^.__signum >= EXCEPTIONCOUNT) then
          {  Not exception so continue OK }
          dpmi_longjmp(pdpmi_jmp_buf(djgpp_exception_state_ptr)^, djgpp_exception_state_ptr^.__eax);
@@ -653,17 +955,15 @@ begin
             errln('FPC triple exception, exiting !!! ');
             if (exceptions_on) then
               djgpp_exception_toggle;
-            asm
-               pushw $1
-               call  ___exit
-            end;
+            ___exit(1);
          end;
        err('FPC double exception, exiting due to signal ');
        itox(sig, 4);
        errln('');
     end;
-  do_faulting_finish_message;
+  do_faulting_finish_message(djgpp_exception_state<>nil);
 end;
+{$endif CREATE_C_FUNCTIONS}
 
 
 type
@@ -678,11 +978,13 @@ var
   npx_ori    : tseginfo;
   cbrk_ori,
   cbrk_rmcb  : trealseginfo;
-  cbrk_regs  : registers;
+  cbrk_regs  : trealregs;
   v2prt0_exceptions_on : longbool;external name '_v2prt0_exceptions_on';
 
 
-procedure djgpp_exception_toggle;[alias : '___djgpp_exception_toggle'];
+{$ifdef CREATE_C_FUNCTIONS}
+procedure djgpp_exception_toggle;
+[public,alias : '___djgpp_exception_toggle'];
 var
   _except : tseginfo;
   i : longint;
@@ -750,7 +1052,7 @@ begin
      cbrk_hooked := true;
    end;
 end;
-
+{$endif CREATE_C_FUNCTIONS}
 
 function dpmi_set_coprocessor_emulation(flag : longint) : longint;
 var
@@ -774,6 +1076,7 @@ var
   _swap_out : pointer;external name '_swap_out';
   _exception_exit : pointer;external name '_exception_exit';
 
+{$ifdef CREATE_C_FUNCTIONS}
 procedure dpmiexcp_exit{(status : longint)};[public,alias : 'excep_exit'];
 { We need to restore hardware interrupt handlers even if somebody calls
   `_exit' directly, or else we crash the machine in nested programs.
@@ -806,12 +1109,127 @@ begin
    djgpp_exception_toggle;
 end;
 
+{$else CREATE_C_FUNCTIONS}
+procedure dpmiexcp_exit;external name 'excep_exit';
+procedure dpmi_swap_in;external name 'swap_in';
+procedure dpmi_swap_out;external name 'swap_out';
+{$endif CREATE_C_FUNCTIONS}
 
 var
   ___djgpp_app_DS : word;external name '___djgpp_app_DS';
   ___djgpp_our_DS : word;external name '___djgpp_our_DS';
 
-procedure djgpp_exception_setup;[alias : '___djgpp_exception_setup'];
+  __djgpp_sigint_mask : word;external name '___djgpp_sigint_mask';
+  __djgpp_sigint_key  : word;external name '___djgpp_sigint_key';
+  __djgpp_sigquit_mask : word;external name '___djgpp_sigquit_mask';
+  __djgpp_sigquit_key  : word;external name '___djgpp_sigquit_key';
+{ to avoid loading of C lib version of dpmiexcp
+  I need to have all exported assembler labels
+  of dpmiexcp.c in this unit.
+  DJGPP v2.03 add to new functions:
+  __djgpp_set_sigint_key
+  __djgpp_set_sigquit_key
+  that I implement here simply translating C code PM }
+Const
+  LSHIFT = 1;
+  RSHIFT = 2;
+  CTRL   = 4;
+  ALT    = 8;
+  DEFAULT_SIGINT  = $042e; { Ctrl-C: scan code 2Eh, kb status 04h }
+  DEFAULT_SIGQUIT = $042b; { Ctrl-\: scan code 2Bh, kb status 04h }
+  DEFAULT_SIGINT_98  = $042b; { Ctrl-C: scan code 2Bh, kb status 04h }
+  DEFAULT_SIGQUIT_98 = $040d; { Ctrl-\: scan code 0Dh, kb status 04h }
+
+{ Make it so the key NEW_KEY will generate the signal SIG.
+   NEW_KEY must include the keyboard status byte in bits 8-15 and the
+   scan code in bits 0-7.  }
+function set_signal_key(sig,new_key : longint) : longint;
+  type
+    pword = ^word;
+  var
+    old_key : longint;
+    mask,key : pword;
+    kb_status : word;
+
+  begin
+    if (sig = SIGINT) then
+      begin
+        mask := @__djgpp_sigint_mask;
+        key  := @__djgpp_sigint_key;
+      end
+    else if (sig = SIGQUIT) then
+      begin
+        mask := @__djgpp_sigquit_mask;
+        key  := @__djgpp_sigquit_key;
+      end
+    else
+      exit(-1);
+
+    old_key := key^;
+    key^ := new_key and $ffff;
+    kb_status := key^ shr 8;
+    mask^ := $f;      { Alt, Ctrl and Shift bits only }
+    {  Mask off the RShift bit unless they explicitly asked for it.
+       Our keyboard handler pretends that LShift is pressed when they
+       press RShift.  }
+    if ((kb_status and RSHIFT) = 0) then
+      mask^ :=mask^ and not RSHIFT;
+    {  Mask off the LShift bit if any of the Ctrl or Alt are set
+       since Shift doesn't matter when Ctrl and/or Alt are pressed.  }
+    if (kb_status and (CTRL or ALT))<>0 then
+      mask^:= mask^ and not LSHIFT;
+
+    exit(old_key);
+  end;
+
+{$ifdef CREATE_C_FUNCTIONS}
+function __djgpp_set_sigint_key(new_key : longint) : longint;cdecl;
+begin
+  __djgpp_set_sigint_key:=set_signal_key(SIGINT, new_key);
+end;
+
+function __djgpp_set_sigquit_key(new_key : longint) : longint;cdecl;
+begin
+  __djgpp_set_sigquit_key:=set_signal_key(SIGQUIT, new_key);
+end;
+{$endif CREATE_C_FUNCTIONS}
+
+function __djgpp__traceback_exit(sig : longint) : longint;
+{$ifdef CREATE_C_FUNCTIONS}cdecl;{$endif CREATE_C_FUNCTIONS}
+var
+  fake_exception : texception_state;
+begin
+  if (sig >= SIGABRT) and (sig <= SIGTRAP) then
+    begin
+      if djgpp_exception_state_ptr=nil then
+        begin
+        { This is a software signal, like SIGABRT or SIGKILL.
+           Fill the exception structure, so we get the traceback.  }
+          djgpp_exception_state_ptr:=@fake_exception;
+          if (dpmi_setjmp(pdpmi_jmp_buf(djgpp_exception_state_ptr)^)<>0) then
+            begin
+              errln('Bad longjmp to __djgpp_exception_state--aborting');
+              do_faulting_finish_message(true); { does not return }
+            end
+          else
+            { Fake the exception number.  7Ah is the last one hardwired
+              inside exceptn.S, for SIGQUIT.  }
+            djgpp_exception_state_ptr^.__signum:=$7a + 1 + sig - SIGABRT;
+        end;
+    end;
+  print_signal_name(sig);
+  if assigned(djgpp_exception_state_ptr) then
+    { This exits, does not return.  }
+    do_faulting_finish_message(djgpp_exception_state_ptr=@fake_exception);
+  ___exit(-1);
+end;
+
+
+
+
+{$ifdef CREATE_C_FUNCTIONS}
+procedure djgpp_exception_setup;
+[alias : '___djgpp_exception_setup'];
 var
   temp_kbd,
   temp_npx    : pointer;
@@ -822,11 +1240,21 @@ var
 begin
   if assigned(_exception_exit) then
    exit;
+  if (go32_info_block.linear_address_of_primary_screen <> $a0000) then
+    begin
+      __djgpp_set_sigint_key(DEFAULT_SIGINT);
+      __djgpp_set_sigquit_key(DEFAULT_SIGQUIT);
+    end
+  else
+    begin  { for PC98 }
+      __djgpp_set_sigint_key(DEFAULT_SIGINT_98);
+      __djgpp_set_sigquit_key(DEFAULT_SIGQUIT_98);
+    end;
   _exception_exit:=@dpmiexcp_exit;
   _swap_in:=@dpmi_swap_in;
   _swap_out:=@dpmi_swap_out;
 { reset signals }
-  for i := 0 to  SIGMAX-1 do
+  for i := 0 to  SIGMAX do
    signal_list[i] := SignalHandler(@SIG_DFL);
 { app_DS only used when converting HW interrupts to exceptions }
   asm
@@ -862,6 +1290,7 @@ begin
 { get original video mode and save }
   old_video_mode := farpeekb(dosmemselector, $449);
 end;
+{$endif CREATE_C_FUNCTIONS}
 
 
 function djgpp_set_ctrl_c(enable : boolean) : boolean;
@@ -874,27 +1303,114 @@ begin
 end;
 
 
+{$ifdef CREATE_C_FUNCTIONS}
 function c_djgpp_set_ctrl_c(enable : longint) : boolean;cdecl;[public,alias : '___djgpp_set_ctrl_c'];
 begin
   c_djgpp_set_ctrl_c:=djgpp_set_ctrl_c(boolean(enable));
 end;
+{$endif def CREATE_C_FUNCTIONS}
 
 
+{$ifdef IN_DPMIEXCP_UNIT}
+procedure ResetDefaultHandlers;
+begin
+  Signal(SIGSEGV,@SIG_DFL);
+  Signal(SIGFPE,@SIG_DFL);
+  Signal(SIGNOFP,@SIG_DFL);
+  Signal(SIGTRAP,@SIG_DFL);
+  Signal(SIGTIMR,@SIG_DFL);
+  Signal(SIGINT,@SIG_DFL);
+  Signal(SIGQUIT,@SIG_DFL);
+  Signal(SIGILL,@SIG_DFL);
+end;
+{$endif IN_DPMIEXCP_UNIT}
 
 procedure InitDPMIExcp;
 begin
+{$ifdef CREATE_C_FUNCTIONS}
   djgpp_ds_alias:=v2prt0_ds_alias;
   djgpp_exception_setup;
+{$endif CREATE_C_FUNCTIONS}
 end;
 
+{$ifndef IN_SYSTEM}
 
 begin
+{$ifdef CREATE_C_FUNCTIONS}
   InitDPMIExcp;
+{$else not CREATE_C_FUNCTIONS}
+  ResetDefaultHandlers;
+{$endif CREATE_C_FUNCTIONS}
 end.
+{$else IN_SYSTEM}
+
+function HandleException(sig : longint) : longint;
+var
+  truesig : longint;
+  ErrorOfSig : longint;
+begin
+  if assigned(djgpp_exception_state_ptr) then
+    truesig:=djgpp_exception_state_ptr^.__signum
+  else
+    truesig:=sig;
+  ErrorOfSig:=0;
+  case truesig of
+   {exception_names : array[0..EXCEPTIONCOUNT-1] of pchar = (}
+   0 : ErrorOfSig:=200;    {'Division by Zero'}
+   5 : ErrorOfSig:=201;    {'Bounds Check'}
+   12 : ErrorOfSig:=202;   {'Stack Fault'}
+   7,                      {'Coprocessor not available'}
+   9,                      {'Coprocessor overrun'}
+   SIGFPE,SIGNOFP : ErrorOfSig:=207;
+   16 : begin
+         { This needs special handling }
+         { to discriminate between 205,206 and 207 }
+         ErrorOfSig:=207;  {'Coprocessor Error'}
+        end;
+   4 : ErrorOfSig:=215;    {'Overflow'}
+   1,                      {'Debug'}
+   2,                      {'NMI'}
+   3,                      {'Breakpoint'}
+   6,                      {'Invalid Opcode'}
+   8,                      {'Double Fault'}
+   10,                     {'Invalid TSS'}
+   11,                     {'Segment Not Present'}
+   13,                     {'General Protection Fault'}
+   14,                     {'Page fault'}
+   15,                     {' ',}
+   17,                     {'Alignment Check');}
+   SIGSEGV,SIGTRAP,SIGTIMR,SIGINT,SIGQUIT
+    : ErrorOfSig:=216;
+  end;
+  if assigned(djgpp_exception_state_ptr) then
+    Begin
+      HandleErrorAddrFrame(ErrorOfSig,
+        djgpp_exception_state_ptr^.__eip,
+        djgpp_exception_state_ptr^.__ebp);
+    End
+  else
+    { probably higher level is required }
+    HandleErrorFrame(ErrorOfSig,get_caller_frame(get_frame));
+  HandleException:=0;
+end;
+
+procedure InstallDefaultHandlers;
+begin
+  Signal(SIGSEGV,@HandleException);
+  Signal(SIGFPE,@HandleException);
+  Signal(SIGNOFP,@HandleException);
+  Signal(SIGTRAP,@HandleException);
+  Signal(SIGTIMR,@HandleException);
+  Signal(SIGINT,@HandleException);
+  Signal(SIGQUIT,@HandleException);
+  Signal(SIGILL,@HandleException);
+end;
+{$endif IN_SYSTEM}
 {
   $Log$
-  Revision 1.11  2000-02-09 16:59:28  peter
-    * truncated log
+  Revision 1.12  2000-03-09 09:15:10  pierre
+    + support for djgpp v2.03 (added some new functions that are in v2.03 ofdpmiexcp.c)
+    + code to integrate exception support inside the system unit
 
   Revision 1.10  2000/01/10 12:14:57  pierre
    * add $goto on to avoid problems
@@ -905,4 +1421,68 @@ end.
   Revision 1.8  2000/01/07 16:32:23  daniel
     * copyright 2000 added
 
-}
+  Revision 1.7  1999/03/01 15:40:49  peter
+    * use external names
+    * removed all direct assembler modes
+
+  Revision 1.6  1999/02/05 12:49:25  pierre
+   <> debug conditionnal renamed DPMIEXCP_DEBUG
+
+  Revision 1.5  1999/01/22 15:46:33  pierre
+   * PsignalHandler is now a pointer as changed in linux.pp
+
+  Revision 1.4  1999/01/22 12:39:19  pierre
+   + added text arg for dump_stack
+
+  Revision 1.3  1999/01/18 09:14:20  pierre
+   * exception_level counting was wrong if dpmi_jmp_buf was copied
+
+  Revision 1.2  1998/12/21 14:23:12  pierre
+  dpmiexcp.pp
+
+  Revision 1.1  1998/12/21 13:07:02  peter
+    * use -FE
+
+  Revision 1.11  1998/11/17 09:42:50  pierre
+   * position check of signal handler was wrong
+
+  Revision 1.10  1998/10/13 21:42:42  peter
+    * cleanup and use of external var
+    * fixed ctrl-break crashes
+
+  Revision 1.9  1998/08/20 08:08:36  pierre
+    * dpmiexcp did not compile with older versions
+      due to the proc to procvar bug
+    * makefile separator problem fixed
+
+  Revision 1.8  1998/08/19 10:56:33  pierre
+    + added some special code for C interface
+      to avoid loading of crt1.o or dpmiexcp.o from the libc.a
+
+  Revision 1.7  1998/08/15 17:01:13  peter
+    * smartlinking the units works now
+    * setjmp/longjmp -> dmpi_setjmp/dpmi_longjmp to solve systemunit
+      conflict
+
+  Revision 1.6  1998/08/04 13:31:32  pierre
+    * changed all FPK into FPC
+
+  Revision 1.5  1998/07/08 12:02:19  carl
+    * make it compiler under fpc v0995
+
+  Revision 1.4  1998/06/26 08:19:08  pierre
+    + all debug in ifdef SYSTEMDEBUG
+    + added local arrays :
+      opennames names of opened files
+      fileopen boolean array to know if still open
+      usefull with gdb if you get problems about too
+      many open files !!
+
+  Revision 1.3  1998/05/31 14:18:23  peter
+    * force att or direct assembling
+    * cleanup of some files
+
+  Revision 1.2  1998/04/21 14:46:33  pierre
+    + debug info better output
+      no normal code changed
+}

+ 360 - 312
rtl/go32v2/exceptn.as

@@ -1,8 +1,7 @@
 /* Copyright (C) 1994, 1995 Charles Sandmann ([email protected])
  * This file maybe freely distributed and modified as long as copyright remains.
  */
-/* Simply rewritten to be compiled directly by GNU as by Pierre Muller
-   for use in FPC the free pascal compiler */
+
   EAX = 0
   EBX = 4
   ECX = 8
@@ -22,20 +21,19 @@
   ERRCODE = 52
   EXCEPNO = 56
   PREVEXC = 60
+/* Length 64 bytes plus non-used FPU */
+	.data
+	.balign 8
+	.comm	exception_stack, 8000
 
-  /* Length 64 bytes plus non-used FPU */
-        .data
-        .align 4
-        .lcomm  exception_stack, 8000
-
-        .text
-        .align  4
+	.text
+	.balign	16,,7
    .macro EXCEPTION_ENTRY number
         pushl   \number
         jmp     exception_handler
    .endm
 
-        .global ___djgpp_exception_table
+	.global	___djgpp_exception_table
 ___djgpp_exception_table:
 EXCEPTION_ENTRY $0
 EXCEPTION_ENTRY $1
@@ -56,339 +54,389 @@ EXCEPTION_ENTRY $15
 EXCEPTION_ENTRY $16
 EXCEPTION_ENTRY $17
 
-/*      This code is called any time an exception occurs in the 32 bit protected
-;*      mode code.  The exception number is pushed on the stack.  This is called
-;*      on a locked stack with interrupts disabled.  Don't try to terminate.
+/*	This code is called any time an exception occurs in the 32 bit protected
+;*	mode code.  The exception number is pushed on the stack.  This is called
+;*	on a locked stack with interrupts disabled.  Don't try to terminate.
 ;*
-;*      [   *   |   SS  ]       * Don't modify
-;*      [      ESP      ]
-;*      [    EFLAGS     ]
-;*      [   *   |   CS  ]       * Don't modify
-;*      [      EIP      ]
-;*      [   ERR CODE    ]
-;*      [   *   |RET CS*]       * Don't modify
-;*      [   RET EIP*    ]       * Don't modify
-;*      [  EXCEPTION #  ]       (And later EBP)
+;*	[   *	|   SS  ]	* Don't modify
+;*	[      ESP      ]
+;*	[    EFLAGS	]
+;*	[   *   |   CS	]	* Don't modify
+;*	[      EIP	]
+;*	[   ERR CODE	]
+;*	[   *   |RET CS*]	* Don't modify
+;*	[   RET EIP*	]	* Don't modify
+;*	[  EXCEPTION #	]	(And later EBP)
 ;*/
+/* ;WARNING WARNING WARNING
+   ;The mechanism for passing signals between the debugger
+   ;and the debuggee relies on the *exact* instructions between
+   ;EXCEPTION_ENTRY($13) above and "cmpb $0, forced" instruction
+   ;below!  These instructions are stored in forced_test[] buffer
+   ;in src/debug/common/dbgcom.c.  Do NOT change anything between
+   ;these two instructions, or you will break signal support in
+   ;the debuggers!!  */
 exception_handler:
-        pushl   %ebx
-        pushl   %ds
-        .byte   0x2e                            /* CS: */
-        cmpb    $0, forced
-        je      not_forced
-        call    limitFix
-        .byte   0x2e                            /* CS: */
-        movzbl  forced,%ebx
-        movl    %ebx,8(%esp)                    /* replace EXCEPNO */
+	pushl	%ebx
+	pushl	%ds
+   	.byte	0x2e				/* CS: */
+	cmpb	$0, forced
+	je	not_forced
+	call	limitFix
+   	.byte	0x2e				/* CS: */
+	movzbl	forced,%ebx
+	movl	%ebx,8(%esp)			/* replace EXCEPNO */
 not_forced:
-        movw    %cs:___djgpp_our_DS, %ds
-        movl    $0x10000, forced                /* its zero now, flag inuse */
-        movl    $exception_state, %ebx
-        popl    DS(%ebx)
-        popl    EBX(%ebx)
-        popl    EXCEPNO(%ebx)
-        movl    %esi, ESI(%ebx)
-        movl    %edi, EDI(%ebx)
-        movl    %ebp, EBP(%ebx)
-        movl    %eax, EAX(%ebx)
-        movl    %ecx, ECX(%ebx)
-        movl    %edx, EDX(%ebx)
-        movw    %es, ES(%ebx)
-        movw    %fs, FS(%ebx)
-        movw    %gs, GS(%ebx)
-        movl    ___djgpp_exception_state_ptr, %eax
-        movl    %eax, PREVEXC(%ebx)
+	movw	%cs:___djgpp_our_DS, %ds
+	movl	$0x10000, forced		/* its zero now, flag inuse */
+	movl	$exception_state, %ebx
+	popl	DS(%ebx)
+	popl	EBX(%ebx)
+	popl	EXCEPNO(%ebx)
+	movl	%esi, ESI(%ebx)
+	movl	%edi, EDI(%ebx)
+	movl	%ebp, EBP(%ebx)
+	movl	%eax, EAX(%ebx)
+	movl	%ecx, ECX(%ebx)
+	movl	%edx, EDX(%ebx)
+	movw	%es, ES(%ebx)
+	movw	%fs, FS(%ebx)
+	movw	%gs, GS(%ebx)
+	movl	___djgpp_exception_state_ptr, %eax
+	movl	%eax, PREVEXC(%ebx)
 
 /* Stack clean at this point, DS:[EBX] points to exception_state, all
    register information saved.  Now get the info on stack. */
 
-        pushl   %ebp
-        movl    %esp, %ebp      /* load ebp with stack for easy access */
+	pushl	%ebp
+	movl	%esp, %ebp	/* load ebp with stack for easy access */
+	
+	movl	12(%ebp), %eax
+	movl	%eax, ERRCODE(%ebx)
+	movl	16(%ebp), %eax
+	movl	%eax, EIP(%ebx)
+	movl	20(%ebp), %eax
+	movw	%ax, CS(%ebx)
+	movl	24(%ebp), %eax
+	movl	%eax, EFLAGS(%ebx)
+	andb	$0xfe, %ah			/* Clear trace flag */
+	movl	%eax, 24(%ebp)			/* and restore on stack */
 
-        movl    12(%ebp), %eax
-        movl    %eax, ERRCODE(%ebx)
-        movl    16(%ebp), %eax
-        movl    %eax, EIP(%ebx)
-        movl    20(%ebp), %eax
-        movw    %ax, CS(%ebx)
-        movl    24(%ebp), %eax
-        movl    %eax, EFLAGS(%ebx)
-        andb    $0xfe, %ah                      /* Clear trace flag */
-        movl    %eax, 24(%ebp)                  /* and restore on stack */
+	movl	28(%ebp), %eax
+	movl	%eax, ESP(%ebx)
+	movl	32(%ebp), %eax
+	movw	%ax, SS(%ebx)
 
-        movl    28(%ebp), %eax
-        movl    %eax, ESP(%ebx)
-        movl    32(%ebp), %eax
-        movw    %ax, SS(%ebx)
-
-        movl    $dpmi_exception_proc1, 16(%ebp)         /* where to return */
-        movw    %cs, 20(%ebp)
+	movl	$dpmi_exception_proc1, 16(%ebp)		/* where to return */
+	movw	%cs, 20(%ebp)
 
 /* Change to our local stack on return from exception (maybe stack exception) */
-        movw    %ds, %ax
-        cmpb    $12,EXCEPNO(%ebx)               /* Stack fault ? */
-        je      1f
-        cmpw    %ax,32(%ebp)
-        je      stack_ok
-1:      movl    $exception_stack+8000, 28(%ebp)
-        movw    %ax, 32(%ebp)
+	movw	%ds, %ax
+	cmpb	$12,EXCEPNO(%ebx)		/* Stack fault ? */
+	je	1f
+	cmpw	%ax,32(%ebp)
+	je	stack_ok
+	.byte	0x2e				/* CS: */
+	movw	___djgpp_ds_alias,%di
+	cmpw	%di,32(%ebp)	/* if it's DS alias, switch to normal DS */
+	jne	1f
+	movw	%ax,32(%ebp)
+	jmp	stack_ok
+1:	movl	$exception_stack+8000, 28(%ebp)
+	movw	%ax, 32(%ebp)
 stack_ok:
 /* Now copy the exception structure to the new stack before returning */
-        movw    %ax, %es
-        movl    %ebx,%esi
-        movl    28(%ebp), %edi
-        subl    $92, %edi                       /* 64 plus extra for longjmp */
-        movl    %edi, 28(%ebp)
-        movl    %edi, ___djgpp_exception_state_ptr
-        movl    $16, %ecx
-        cld
-        rep
-        movsl
+	movw	%ax, %es
+	movl	%ebx,%esi
+	movl	28(%ebp), %edi
+	subl	$92, %edi			/* 64 plus extra for longjmp */
+	movl	%edi, 28(%ebp)
+	movl	%edi, ___djgpp_exception_state_ptr
+	movl	$16, %ecx
+	cld
+	rep
+	movsl
 
-        movl    EAX(%ebx), %eax                         /* restore regs */
-        movl    ESI(%ebx), %esi
-        movl    EDI(%ebx), %edi
-        movl    ECX(%ebx), %ecx
-        movw    ES(%ebx), %es
-        popl    %ebp
-        pushl   EBX(%ebx)
-        pushl   DS(%ebx)
-        movb    $0, forced+2                            /* flag non-use */
-        popl    %ds
-        popl    %ebx
-        lret
+	movl	EAX(%ebx), %eax				/* restore regs */
+	movl	ESI(%ebx), %esi
+	movl	EDI(%ebx), %edi
+	movl	ECX(%ebx), %ecx
+	movw	ES(%ebx), %es
+	popl	%ebp
+	pushl	EBX(%ebx)
+	pushl	DS(%ebx)
+	movb	$0, forced+2				/* flag non-use */
+	popl	%ds
+	popl	%ebx
+	lret
 
 /* Code to fix fake exception, EBX destroyed.  Note, app_DS may == our_DS! */
-        .align 4
+	.balign 16,,7
 limitFix:
-        pushl   %eax
-        pushl   %ecx
-        pushl   %edx
-        .byte   0x2e                            /* CS: */
-        movl    ___djgpp_app_DS, %ebx           /* avoid size prefix */
-        .byte   0x2e                            /* CS: */
-        movl    ds_limit, %edx
-        movl    %edx, %ecx
-        shrl    $16, %ecx
-        movw    $0x0008, %ax
-        int     $0x31                           /* Set segment limit */
-        popl    %edx
-        popl    %ecx
-        popl    %eax
-        ret
+	pushl	%eax
+	pushl	%ecx
+	pushl	%edx
+   	.byte	0x2e				/* CS: */
+	movl	___djgpp_app_DS, %ebx		/* avoid size prefix */
+   	.byte	0x2e				/* CS: */
+	movl	ds_limit, %edx
+	movl	%edx, %ecx
+	shrl	$16, %ecx
+	movw	$0x0008, %ax
+	int	$0x31				/* Set segment limit */
+	popl	%edx
+	popl	%ecx
+	popl	%eax
+	ret
 
 /* This local routine preprocesses a return request to the C code.  It checks
    to make sure the DS & SS are set OK for C code.  If not, it sets them up */
-        .align  4
+	.balign	16,,7
 dpmi_exception_proc1:
-        cld
-        .byte   0x2e                            /* CS: !!! */
-        movw    ___djgpp_our_DS, %bx            /* to be sure */
-        movw    %bx, %ds
-        movw    %bx, %es
-        /* Note: SS:ESP should be set properly by exception routine */
-        jmp     ___djgpp_exception_processor
+	cld
+   	.byte	0x2e				/* CS: !!! */
+	movw	___djgpp_our_DS, %bx		/* to be sure */
+	movw	%bx, %ds
+	movw	%bx, %es
+	/* Note: SS:ESP should be set properly by exception routine */
+	jmp	___djgpp_exception_processor
 
-/*      This code is called by a user routine wishing to save an interrupt
-;*      state.  It will return with a clean stack, our DS,ES,SS.
+/*	This code is called by a user routine wishing to save an interrupt
+;*	state.  It will return with a clean stack, our DS,ES,SS.
 ;*      Minor bug: uses static exception_state for a short window without
 ;*      interrupts guaranteed disabled.
 ;*
-;*      [    EFLAGS     ]
-;*      [   *   |   CS  ]
-;*      [      EIP      ]
-;*      [  CALLING EIP  ]
+;*	[    EFLAGS	]
+;*	[   *   |   CS	]
+;*	[      EIP	]
+;*	[  CALLING EIP  ]
 ;*/
 
-        .align  4
-        .globl  ___djgpp_save_interrupt_regs
+	.balign	16,,7
+	.globl	___djgpp_save_interrupt_regs
 ___djgpp_save_interrupt_regs:
-        pushl   %esi
-        pushl   %ds
-        movw    %cs:___djgpp_our_DS, %ds
-        movl    $exception_state, %esi
-        popl    DS(%esi)                /* Trashes ES but OK */
-        popl    ESI(%esi)
-        movl    %edi, EDI(%esi)
-        movl    %ebp, EBP(%esi)
-        movl    %eax, EAX(%esi)
-        movl    %ebx, EBX(%esi)
-        movl    %ecx, ECX(%esi)
-        movl    %edx, EDX(%esi)
-        popl    %edx                    /* Save calling EIP */
-        popl    EIP(%esi)
-        popl    %eax
-        movw    %ax,CS(%esi)            /* Don't pop, nukes DS */
-        popl    EFLAGS(%esi)
-        movl    %esp, ESP(%esi)
-        movw    %es, ES(%esi)
-        movw    %fs, FS(%esi)
-        movw    %gs, GS(%esi)
-        movw    %ss, SS(%esi)
-        movl    ___djgpp_exception_state_ptr, %eax
-        movl    %eax, PREVEXC(%esi)
-        cld
-        movw    %ds, %ax
-        movw    %ax, %es
-        movw    %ss, %bx
-        cmpw    %ax, %bx                        /* is SS = DS ? */
-        je      Lss_ok
-        movw    %ax, %ss                        /* set new SS:ESP */
-        movl    $exception_stack+8000, %esp
-Lss_ok: subl    $92, %esp               /* 64 plus extra for longjmp */
-        movl    %esp, %edi
-        movl    $16, %ecx
-        movl    %edi, ___djgpp_exception_state_ptr
-        rep
-        movsl                                   /* Copy structure to stack */
-        jmp     *%edx                           /* A "return" */
+	pushl	%esi
+	pushl	%ds
+	movw	%cs:___djgpp_our_DS, %ds
+	movl	$exception_state, %esi
+	popl	DS(%esi)		/* Trashes ES but OK */
+	popl	ESI(%esi)
+	movl	%edi, EDI(%esi)
+	movl	%ebp, EBP(%esi)
+	movl	%eax, EAX(%esi)
+	movl	%ebx, EBX(%esi)
+	movl	%ecx, ECX(%esi)
+	movl	%edx, EDX(%esi)
+	popl	%edx			/* Save calling EIP */
+	popl	EIP(%esi)
+	popl	%eax
+	movw	%ax,CS(%esi)		/* Don't pop, nukes DS */
+	popl	EFLAGS(%esi)
+	movl	%esp, ESP(%esi)
+	movw	%es, ES(%esi)
+	movw	%fs, FS(%esi)
+	movw	%gs, GS(%esi)
+	movw	%ss, SS(%esi)
+	movl	___djgpp_exception_state_ptr, %eax
+	movl	%eax, PREVEXC(%esi)
+	cld
+	movw	%ds, %ax
+	movw	%ax, %es
+	movw	%ss, %bx
+	cmpw	%ax, %bx			/* is SS = DS ? */
+	je	Lss_ok
+	movw	%ax, %ss			/* set new SS:ESP */
+	movl	$exception_stack+8000, %esp
+Lss_ok:	subl	$92, %esp		/* 64 plus extra for longjmp */
+	movl	%esp, %edi
+	movl	$16, %ecx
+	movl	%edi, ___djgpp_exception_state_ptr
+	rep
+	movsl					/* Copy structure to stack */
+	jmp	*%edx				/* A "return" */
 
-        .align  4               /* We will touch this; it must be locked */
-        .global ___djgpp_hw_lock_start
+	.balign	8		/* We will touch this; it must be locked */
+	.global ___djgpp_hw_lock_start
 ___djgpp_hw_lock_start:
-ds_limit:                       .long   0
-forced:                         .long   0
-        .global ___djgpp_cbrk_count
-___djgpp_cbrk_count:            .long   0
-        .global ___djgpp_timer_countdown
-___djgpp_timer_countdown:       .long   0
-        .global ___djgpp_our_DS
-___djgpp_our_DS:                .word   0
-        .global ___djgpp_app_DS
-___djgpp_app_DS:                .word   0
-        .global ___djgpp_dos_sel
-___djgpp_dos_sel:               .word   0
-        .global ___djgpp_hwint_flags
-___djgpp_hwint_flags:           .word   0
-        .global ___djgpp_old_kbd
-___djgpp_old_kbd:               .long   0,0
-        .global ___djgpp_old_timer
-___djgpp_old_timer:             .long   0,0
-        .global ___djgpp_exception_state_ptr
-___djgpp_exception_state_ptr:   .long   0
-exception_state:                .space  64
-        .global ___djgpp_ds_alias
-___djgpp_ds_alias:              .word   0       /* used in dpmi/api/d0303.s (alloc rmcb) */
+	/* src/debug/common/dbgcom.c knows that `ds_limit' is stored
+	   4 bytes before `forced' and relies on that.  Do NOT change that! */
+ds_limit:			.long	0
+forced:				.long	0
+	.global	___djgpp_cbrk_count
+___djgpp_cbrk_count:		.long	0
+	.global	___djgpp_timer_countdown
+___djgpp_timer_countdown:	.long	0
+	.global	___djgpp_our_DS
+___djgpp_our_DS:		.word	0
+	.global	___djgpp_app_DS
+___djgpp_app_DS:		.word	0
+	.global	___djgpp_dos_sel
+___djgpp_dos_sel:		.word	0
+	.global	___djgpp_hwint_flags
+___djgpp_hwint_flags:		.word	0
+	.global ___djgpp_sigint_key
+___djgpp_sigint_key:		.word	0	/* scan code and kb status */
+	.global ___djgpp_sigint_mask
+___djgpp_sigint_mask:		.word	0	/* kb status mask */
+	.global ___djgpp_sigquit_key
+___djgpp_sigquit_key:		.word	0
+	.global ___djgpp_sigquit_mask
+___djgpp_sigquit_mask:		.word	0
+	.global	___djgpp_old_kbd
+___djgpp_old_kbd:		.long	0,0
+	.global	___djgpp_old_timer
+___djgpp_old_timer:		.long	0,0
+	.global	___djgpp_exception_state_ptr
+___djgpp_exception_state_ptr:	.long	0
+exception_state:		.space	64
+	.global	___djgpp_ds_alias
+___djgpp_ds_alias:		.word	0	/* used in dpmi/api/d0303.s (alloc rmcb) */
 
-        .align 4
-        .global ___djgpp_npx_hdlr
+	.balign 16,,7
+	.global	___djgpp_npx_hdlr
 ___djgpp_npx_hdlr:
-        pushl   %eax
-        xorl    %eax,%eax
-        outb    %al,$0x0f0
-        movb    $0x20,%al
-        outb    %al,$0x0a0
-        outb    %al,$0x020
-        movb    $0x75,%al
+	pushl	%eax
+	xorl	%eax,%eax
+	outb	%al,$0x0f0
+	movb	$0x20,%al
+	outb	%al,$0x0a0
+	outb	%al,$0x020
+	movb	$0x75,%al
 hw_to_excp:
-        call    ___djgpp_hw_exception
-        popl    %eax
-        sti
-        iret
+	call	___djgpp_hw_exception
+	popl	%eax
+	sti
+	iret
 
-        .align 4
-        .global ___djgpp_kbd_hdlr
+	.balign 16,,7
+	.global	___djgpp_kbd_hdlr
 ___djgpp_kbd_hdlr:
-        pushl   %eax
-        pushl   %ds
-        .byte   0x2e                            /* CS: */
-        testb   $1, ___djgpp_hwint_flags        /* Disable? */
-        jne     Lkbd_chain
-/* Check CTRL state */
-        movw    %cs:___djgpp_dos_sel, %ds       /* Conventional mem selector */
-/*      movw    $0x7021,0xb0f00         */      /* Test code - write to mono */
-        testb   $4,0x417                        /* Test KB flags: CTRL down? */
-        je      Lkbd_chain
-        testb   $8,0x417                        /* Test KB flags: ALT down? */
-        jne     Lkbd_chain                      /* Don't capture ALT-CTRL-C */
-/* Check port for scan code */
-        inb     $0x60,%al
-        cmpb    $0x2e,%al
-        jne     Lkbd_chain
+	pushl	%eax
+	pushl	%ebx
+	pushl	%ds
+   	.byte	0x2e				/* CS: */
+	testb	$1, ___djgpp_hwint_flags	/* Disable? */
+	jne	Lkbd_chain
+	movw	%cs:___djgpp_dos_sel, %ds	/* Conventional mem selector */
+/*	movw	$0x7021,0xb0f00		*/	/* Test code - write to mono */
+/* Check Keyboard status bits */
+	movb	0x417,%ah			/* Get KB status byte */
+	testb	$1,%ah
+	je	6f
+	orb	$2,%ah	/* If RShift is set, set LShift as well */
+6:
+	inb	$0x60,%al			/* Read the scan code */
+99:
+	movb	%ah,%bh				/* Save KB status */
+	andb	%cs:___djgpp_sigint_mask, %ah	/* Mask off irrelevant bits */
+	cmpw	%cs:___djgpp_sigint_key, %ax	/* Test for SIGINT */
+	jne	7f
+	movb	$0x79,%bh			/* SIGINT */
+	jmp	98f
+7:
+	movb	%bh,%ah				/* Restore KB status */
+	andb	%cs:___djgpp_sigquit_mask, %ah	/* Mask off irrelevant bits */
+	cmpw	%cs:___djgpp_sigquit_key, %ax	/* Test for SIGQUIT*/
+	jne	Lkbd_chain
+	movb	$0x7a,%bh			/* SIGQUIT */
 /* Clear interrupt, (later: remove byte from controller?)
-        movb    $0x20,%al
-        outb    %al,$0x020      */
+	movb	$0x20,%al
+	outb	%al,$0x020	*/
 98:
-        movb    $0x79,%al
-        call    ___djgpp_hw_exception
+	movb	%bh,%al
+	call	___djgpp_hw_exception
 Lkbd_chain:
-        popl    %ds
-        popl    %eax
-        ljmp    %cs:___djgpp_old_kbd
+	popl	%ds
+	popl	%ebx
+	popl	%eax
+	ljmp	%cs:___djgpp_old_kbd
 
-        .align 4
-        .global ___djgpp_kbd_hdlr_pc98
+	.balign 16,,7
+	.global	___djgpp_kbd_hdlr_pc98
 ___djgpp_kbd_hdlr_pc98:
-        pushl   %eax
-        pushl   %ds
-        .byte   0x2e                            /* CS: */
-        testb   $1, ___djgpp_hwint_flags        /* Disable? */
-        jne     Lkbd_chain
+	pushl	%eax
+	pushl	%ebx
+	pushl	%ds
+   	.byte	0x2e				/* CS: */
+	testb	$1, ___djgpp_hwint_flags	/* Disable? */
+	jne	Lkbd_chain
 /* Check CTRL state */
-        movw    %cs:___djgpp_dos_sel, %ds       /* Conventional mem selector */
-        testb   $0x10,0x053a                    /* Test KB flags: CTRL down? */
-        jz      Lkbd_chain
-/* Check for scan code */
-        testb   $0x08,0x052f                    /* test KB "C" down for PC98 */
-        jz      Lkbd_chain
-        jmp     98b
+	movw	%cs:___djgpp_dos_sel, %ds	/* Conventional mem selector */
+	movb	0x053a,%al			/* Get KB status byte */
+	/* Convert PC98 style status byte to PC/AT style */
+	movb	%al,%ah
+	andb	$0x09,%ah	/* GRPH(=ALT), SHIFT(=R-Shift) */
+	testb	$0x02,%al
+	je	981f
+	orb	$0x40,%ah	/* CAPS(=Caps Lock) */
+981:	testb	$0x10,%al
+	je	982f
+	orb	$0x04,%ah	/* CTRL(=Ctrl) */
+982:	testb	$0x01,%al
+	je	983f
+	orb	$0x02,%ah	/* SHIFT(=L-Shift) */
+983:	testb	$0x04,%al
+	je	984f
+	orb	$0x20,%ah	/* KANA(=NUM Lock) */
+984:	inb	$0x41,%al			/* Read the scan code */
+	jmp	99b
 
-        .align 4
-        .global ___djgpp_timer_hdlr
+	.balign 16,,7
+	.global	___djgpp_timer_hdlr
 ___djgpp_timer_hdlr:
-        .byte   0x2e                            /* CS: */
-        cmpl    $0,___djgpp_timer_countdown
-        je      4f
-        pushl   %ds
-        movw    %cs:___djgpp_ds_alias, %ds
-        decl    ___djgpp_timer_countdown
-        popl    %ds
-        jmp     3f
+   	.byte	0x2e				/* CS: */
+	cmpl	$0,___djgpp_timer_countdown
+	je	4f
+	pushl	%ds
+	movw	%cs:___djgpp_ds_alias, %ds
+	decl	___djgpp_timer_countdown
+	popl	%ds
+	jmp	3f
 4:
-        pushl   %eax
-        movb    $0x78,%al
-        call    ___djgpp_hw_exception
-        popl    %eax
+	pushl	%eax
+	movb	$0x78,%al
+	call	___djgpp_hw_exception
+	popl	%eax
 3:
-        .byte   0x2e                            /* CS: */
-        testb   $4, ___djgpp_hwint_flags        /* IRET or chain? */
-        jne     2f
-        ljmp    %cs:___djgpp_old_timer
+   	.byte	0x2e				/* CS: */
+	testb	$4, ___djgpp_hwint_flags	/* IRET or chain? */
+	jne	2f
+	ljmp	%cs:___djgpp_old_timer
 2:
-        pushl   %eax
-        movb    $0x20,%al                       /* EOI the interrupt */
-        outb    %al,$0x020
-        popl    %eax
-        iret
+	pushl	%eax
+	movb	$0x20,%al			/* EOI the interrupt */
+	outb	%al,$0x020
+	popl	%eax
+	iret
 
-        /* On entry ES is the DS alias selector */
-        .align 4
-        .global ___djgpp_cbrk_hdlr              /* A RMCB handler for 0x1b */
+	/* On entry ES is the DS alias selector */
+	.balign 16,,7
+	.global	___djgpp_cbrk_hdlr		/* A RMCB handler for 0x1b */
 ___djgpp_cbrk_hdlr:
-        cld
-        lodsl                                   /* EAX = DS:[esi] CS:IP */
-        movl    %eax, %es:0x2a(%edi)            /* store in structure */
-        lodsl                                   /* AX = FLAGS */
-        movw    %ax, %es:0x20(%edi)
-        addw    $6, %es:0x2e(%edi)              /* Adjust RM SP */
-        movb    $0x1b,%al
+	cld
+	lodsl					/* EAX = DS:[esi] CS:IP */
+	movl	%eax, %es:0x2a(%edi)		/* store in structure */
+	lodsl					/* AX = FLAGS */
+	movw	%ax, %es:0x20(%edi)
+	addw	$6, %es:0x2e(%edi)		/* Adjust RM SP */
+	movb	$0x1b,%al
 
-        .byte   0x2e                            /* CS: */
-        testb   $2, ___djgpp_hwint_flags        /* Count, don't kill */
-        jne     1f
+   	.byte	0x2e				/* CS: */
+	testb	$2, ___djgpp_hwint_flags	/* Count, don't kill */
+	jne	1f
 
-        call    ___djgpp_hw_exception
-        iret
+	call	___djgpp_hw_exception
+	iret
 1:
-        incl    %es:___djgpp_cbrk_count
-        iret
+	incl	%es:___djgpp_cbrk_count
+	iret
 
-        .global ___djgpp_i24                    /* Int 24 handler if needed */
-        .global ___djgpp_iret                   /* Int 23 handler if needed */
+	.global	___djgpp_i24			/* Int 24 handler if needed */
+	.global	___djgpp_iret			/* Int 23 handler if needed */
 ___djgpp_i24:
-        movb    $3,%al
+	movb	$3,%al
 ___djgpp_iret:
-        iret
+	iret
 
 /* Code to stop execution ASAP, EAX destroyed.  Make DS/ES/SS invalid.
    Fake exception value is passed in AL and moved into the "forced" variable.
@@ -396,32 +444,32 @@ ___djgpp_iret:
    control away from via longjmp or exit(), common with SIGINT, SIGFPE, or
    if we want EIP information on timers. */
 
-        .align 4
-        .global ___djgpp_hw_exception
+	.balign 16,,7
+	.global	___djgpp_hw_exception
 ___djgpp_hw_exception:
-        .byte   0x2e                            /* CS: */
-        cmpl    $0, forced                      /* Already flagged? */
-        jne     already_forced
-        pushl   %ebx
-        pushl   %ecx
-        pushl   %edx
-        pushl   %ds
-        movw    %cs:___djgpp_our_DS, %ds
-        movl    ___djgpp_app_DS, %ebx           /* avoid size prefix */
-        lsl     %ebx, %ecx
-        movl    %ecx, ds_limit                  /* Save current limit */
-        movb    %al, forced                     /* Indicate a fake exception */
-        xorl    %ecx, %ecx
-        movw    $0xfff, %dx                     /* 4K limit is null page ! */
-        movw    $0x0008, %ax
-        int     $0x31                           /* Set segment limit */
-5:      popl    %ds
-        popl    %edx
-        popl    %ecx
-        popl    %ebx
+   	.byte	0x2e				/* CS: */
+	cmpl	$0, forced			/* Already flagged? */
+	jne	already_forced
+	pushl	%ebx
+	pushl	%ecx
+	pushl	%edx
+	pushl	%ds
+	movw	%cs:___djgpp_our_DS, %ds
+	movl	___djgpp_app_DS, %ebx		/* avoid size prefix */
+	lsl	%ebx, %ecx
+	movl	%ecx, ds_limit			/* Save current limit */
+	movb	%al, forced			/* Indicate a fake exception */
+	xorl	%ecx, %ecx
+	movw	$0xfff, %dx			/* 4K limit is null page ! */
+	movw	$0x0008, %ax
+	int	$0x31				/* Set segment limit */
+5:	popl	%ds
+	popl	%edx
+	popl	%ecx
+	popl	%ebx
 already_forced:
-        ret
+	ret
 
-        .global ___djgpp_hw_lock_end
+	.global ___djgpp_hw_lock_end
 ___djgpp_hw_lock_end:
         ret                                     /* LD does weird things */

+ 6 - 2
rtl/go32v2/system.pp

@@ -1354,7 +1354,7 @@ end;
 {$ifndef RTLLITE}
 {$ifdef  EXCEPTIONS_IN_SYSTEM}
 {$define IN_SYSTEM}
-{$i ndpmi.pp}
+{$i dpmiexcp.pp}
 {$endif  EXCEPTIONS_IN_SYSTEM}
 {$endif RTLLITE}
 
@@ -1403,7 +1403,11 @@ Begin
 End.
 {
   $Log$
-  Revision 1.34  2000-03-07 11:05:58  pierre
+  Revision 1.35  2000-03-09 09:15:10  pierre
+    + support for djgpp v2.03 (added some new functions that are in v2.03 ofdpmiexcp.c)
+    + code to integrate exception support inside the system unit
+
+  Revision 1.34  2000/03/07 11:05:58  pierre
     * fix for the problem of backslashes at and of directory
     + some code for exception support (far from working :()
     + debug variable accept_sbrk