Browse Source

+ int 0 for divide by zero

peter 27 years ago
parent
commit
b15f3bb518
1 changed files with 276 additions and 184 deletions
  1. 276 184
      rtl/dos/go32v2/system.pp

+ 276 - 184
rtl/dos/go32v2/system.pp

@@ -126,61 +126,23 @@ implementation
 const
   carryflag = 1;
 
-var
-  doscmd : string[128];  { Dos commandline copied from PSP, max is 128 chars }
-
-{$ASMMODE DIRECT}
-
-procedure halt(errnum : byte);
-begin
-  do_exit;
-  asm
-        movzbw  errnum,%ax
-        pushw   %ax
-        call    ___exit         {frees all dpmi memory !!}
+type
+  tseginfo=packed record
+    offset  : pointer;
+    segment : word;
   end;
-end;
 
+var
+  doscmd    : string[128];  { Dos commandline copied from PSP, max is 128 chars }
+  old_int00,
+  old_int75 : tseginfo;
 
-procedure int_stackcheck(stack_size:longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'STACKCHECK'];
-{
-  called when trying to get local stack if the compiler directive $S
-  is set this function must preserve esi !!!! because esi is set by
-  the calling proc for methods it must preserve all registers !!
 
-  With a 2048 byte safe area used to write to StdIo without crossing
-  the stack boundary
-}
-begin
-  asm
-        pushl   %eax
-        pushl   %ebx
-        movl    stack_size,%ebx
-        addl    $2048,%ebx
-        movl    %esp,%eax
-        subl    %ebx,%eax
-{$ifdef SYSTEMDEBUG}
-        movl    U_SYSTEM_LOWESTSTACK,%ebx
-        cmpl    %eax,%ebx
-        jb      .L_is_not_lowest
-        movl    %eax,U_SYSTEM_LOWESTSTACK
-.L_is_not_lowest:
-{$endif SYSTEMDEBUG}
-        movl    __stkbottom,%ebx
-        cmpl    %eax,%ebx
-        jae     .L__short_on_stack
-        popl    %ebx
-        popl    %eax
-        leave
-        ret     $4
-.L__short_on_stack:
-        { can be usefull for error recovery !! }
-        popl    %ebx
-        popl    %eax
-  end['EAX','EBX'];
-  HandleError(202);
-end;
+{$ASMMODE DIRECT}
 
+{*****************************************************************************
+                              Go32 Helpers
+*****************************************************************************}
 
 function far_strlen(selector : word;linear_address : longint) : longint;
 begin
@@ -240,91 +202,99 @@ asm
 end;
 
 
-    procedure sysseg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
+function get_cs : word;assembler;
+asm
+        movw    %cs,%ax
+end;
+
 
-      begin
-         if count=0 then
-           exit;
-         if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
-           asm
-              pushw %es
-              pushw %ds
-              cld
-              movl count,%ecx
-              movl source,%esi
-              movl dest,%edi
-              movw dseg,%ax
-              movw %ax,%es
-              movw sseg,%ax
-              movw %ax,%ds
-              movl %ecx,%eax
-              shrl $2,%ecx
-              rep
-              movsl
-              movl %eax,%ecx
-              andl $3,%ecx
-              rep
-              movsb
-              popw %ds
-              popw %es
-           end ['ESI','EDI','ECX','EAX']
-         else if (source<dest) then
-           { copy backward for overlapping }
-           asm
-              pushw %es
-              pushw %ds
-              std
-              movl count,%ecx
-              movl source,%esi
-              movl dest,%edi
-              movw dseg,%ax
-              movw %ax,%es
-              movw sseg,%ax
-              movw %ax,%ds
-              addl %ecx,%esi
-              addl %ecx,%edi
-              movl %ecx,%eax
-              andl $3,%ecx
-              orl %ecx,%ecx
-              jz .LSEG_MOVE1
-
-              { calculate esi and edi}
-              decl %esi
-              decl %edi
-              rep
-              movsb
-              incl %esi
-              incl %edi
-           .LSEG_MOVE1:
-              subl $4,%esi
-              subl $4,%edi
-              movl %eax,%ecx
-              shrl $2,%ecx
-              rep
-              movsl
-              cld
-              popw %ds
-              popw %es
-           end ['ESI','EDI','ECX'];
-      end;
+procedure sysseg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
+begin
+   if count=0 then
+     exit;
+   if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
+     asm
+        pushw %es
+        pushw %ds
+        cld
+        movl count,%ecx
+        movl source,%esi
+        movl dest,%edi
+        movw dseg,%ax
+        movw %ax,%es
+        movw sseg,%ax
+        movw %ax,%ds
+        movl %ecx,%eax
+        shrl $2,%ecx
+        rep
+        movsl
+        movl %eax,%ecx
+        andl $3,%ecx
+        rep
+        movsb
+        popw %ds
+        popw %es
+     end ['ESI','EDI','ECX','EAX']
+   else if (source<dest) then
+     { copy backward for overlapping }
+     asm
+        pushw %es
+        pushw %ds
+        std
+        movl count,%ecx
+        movl source,%esi
+        movl dest,%edi
+        movw dseg,%ax
+        movw %ax,%es
+        movw sseg,%ax
+        movw %ax,%ds
+        addl %ecx,%esi
+        addl %ecx,%edi
+        movl %ecx,%eax
+        andl $3,%ecx
+        orl %ecx,%ecx
+        jz .LSEG_MOVE1
+
+        { calculate esi and edi}
+        decl %esi
+        decl %edi
+        rep
+        movsb
+        incl %esi
+        incl %edi
+     .LSEG_MOVE1:
+        subl $4,%esi
+        subl $4,%edi
+        movl %eax,%ecx
+        shrl $2,%ecx
+        rep
+        movsl
+        cld
+        popw %ds
+        popw %es
+     end ['ESI','EDI','ECX'];
+end;
 
 
 function atohex(s : pchar) : longint;
-var rv : longint;
-    v : byte;
+var
+  rv : longint;
+  v  : byte;
 begin
-rv := 0;
-while (s^ <>#0) do
-  begin
-  v := byte(s^) - byte('0');
-  if (v > 9) then v := v - 7;
-  v := v and 15; { in case it's lower case }
-  rv := rv*16 + v;
-  inc(longint(s));
-  end;
-atohex := rv;
+  rv:=0;
+  while (s^ <>#0) do
+   begin
+     v:=byte(s^)-byte('0');
+     if (v > 9) then
+       dec(v,7);
+     v:=v and 15; { in case it's lower case }
+     rv:=(rv shl 4) or v;
+     inc(longint(s));
+   end;
+  atohex:=rv;
 end;
 
+
 procedure setup_arguments;
 type  arrayword = array [0..0] of word;
 var psp : word;
@@ -423,31 +393,30 @@ end;
 
 
 function strcopy(dest,source : pchar) : pchar;
-
-      begin
-         asm
-            cld
-            movl 12(%ebp),%edi
-            movl $0xffffffff,%ecx
-            xorb %al,%al
-            repne
-            scasb
-            not %ecx
-            movl 8(%ebp),%edi
-            movl 12(%ebp),%esi
-            movl %ecx,%eax
-            shrl $2,%ecx
-            rep
-            movsl
-            movl %eax,%ecx
-            andl $3,%ecx
-            rep
-            movsb
-            movl 8(%ebp),%eax
-            leave
-            ret $8
-         end;
-      end;
+begin
+  asm
+        cld
+        movl 12(%ebp),%edi
+        movl $0xffffffff,%ecx
+        xorb %al,%al
+        repne
+        scasb
+        not %ecx
+        movl 8(%ebp),%edi
+        movl 12(%ebp),%esi
+        movl %ecx,%eax
+        shrl $2,%ecx
+        rep
+        movsl
+        movl %eax,%ecx
+        andl $3,%ecx
+        rep
+        movsb
+        movl 8(%ebp),%eax
+        leave
+        ret $8
+  end;
+end;
 
 
 procedure setup_environment;
@@ -479,16 +448,17 @@ begin
   cp:=dos_env;
   env_count:=0;
   while cp^ <> #0 do
-    begin
-    getmem(envp[env_count],strlen(cp)+1);
-    strcopy(envp[env_count], cp);
+   begin
+     getmem(envp[env_count],strlen(cp)+1);
+     strcopy(envp[env_count], cp);
 {$IfDef SYSTEMDEBUG}
-      Writeln('env ',env_count,' = "',envp[env_count],'"');
+     Writeln('env ',env_count,' = "',envp[env_count],'"');
 {$EndIf SYSTEMDEBUG}
-    inc(env_count);
-    while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
-    inc(longint(cp)); { skip to next character }
-    end;
+     inc(env_count);
+     while (cp^ <> #0) do
+      inc(longint(cp)); { skip to NUL }
+     inc(longint(cp)); { skip to next character }
+   end;
   envp[env_count]:=nil;
   longint(cp):=longint(cp)+3;
   getmem(dos_argv0,strlen(cp)+1);
@@ -503,31 +473,140 @@ begin
 {$ASMMODE ATT}
 end;
 
-     procedure syscopytodos(addr : longint; len : longint);
-     begin
-        if len > tb_size then HandleError(217);
-        sysseg_move(get_ds,addr,dos_selector,tb,len);
-     end;
 
-     procedure syscopyfromdos(addr : longint; len : longint);
-     begin
-        if len > tb_size then HandleError(217);
-        sysseg_move(dos_selector,tb,get_ds,addr,len);
-     end;
+procedure syscopytodos(addr : longint; len : longint);
+begin
+   if len > tb_size then
+     HandleError(217);
+   sysseg_move(get_ds,addr,dos_selector,tb,len);
+end;
 
-    procedure sysrealintr(intnr : word;var regs : trealregs);
 
-      begin
-         regs.realsp:=0;
-         regs.realss:=0;
-         asm
-            movw  intnr,%bx
-            xorl  %ecx,%ecx
-            movl  regs,%edi
-            movw  $0x300,%ax
-            int   $0x31
-         end;
-      end;
+procedure syscopyfromdos(addr : longint; len : longint);
+begin
+   if len > tb_size then
+     HandleError(217);
+   sysseg_move(dos_selector,tb,get_ds,addr,len);
+end;
+
+
+procedure sysrealintr(intnr : word;var regs : trealregs);
+begin
+   regs.realsp:=0;
+   regs.realss:=0;
+   asm
+      movw  intnr,%bx
+      xorl  %ecx,%ecx
+      movl  regs,%edi
+      movw  $0x300,%ax
+      int   $0x31
+   end;
+end;
+
+
+procedure set_pm_interrupt(vector : byte;const intaddr : tseginfo);
+begin
+  asm
+        movl intaddr,%eax
+        movl (%eax),%edx
+        movw 4(%eax),%cx
+        movl $0x205,%eax
+        movb vector,%bl
+        int $0x31
+  end;
+end;
+
+
+procedure get_pm_interrupt(vector : byte;var intaddr : tseginfo);
+begin
+  asm
+        movb    vector,%bl
+        movl    $0x204,%eax
+        int     $0x31
+        movl    intaddr,%eax
+        movl    %edx,(%eax)
+        movw    %cx,4(%eax)
+  end;
+end;
+
+
+{*****************************************************************************
+                              ParamStr/Randomize
+*****************************************************************************}
+
+{$ASMMODE DIRECT}
+procedure halt(errnum : byte);
+begin
+  do_exit;
+  set_pm_interrupt($00,old_int00);
+  set_pm_interrupt($75,old_int75);
+  asm
+        movzbw  errnum,%ax
+        pushw   %ax
+        call    ___exit         {frees all dpmi memory !!}
+  end;
+end;
+
+
+procedure new_int00;
+begin
+  HandleError(200);
+end;
+
+
+procedure new_int75;
+begin
+  asm
+        xorl    %eax,%eax
+        outb    %al,$0x0f0
+        movb    $0x20,%al
+        outb    %al,$0x0a0
+        outb    %al,$0x020
+  end;
+  HandleError(200);
+end;
+
+
+procedure int_stackcheck(stack_size:longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'STACKCHECK'];
+{
+  called when trying to get local stack if the compiler directive $S
+  is set this function must preserve esi !!!! because esi is set by
+  the calling proc for methods it must preserve all registers !!
+
+  With a 2048 byte safe area used to write to StdIo without crossing
+  the stack boundary
+}
+begin
+  asm
+        pushl   %eax
+        pushl   %ebx
+        movl    stack_size,%ebx
+        addl    $2048,%ebx
+        movl    %esp,%eax
+        subl    %ebx,%eax
+{$ifdef SYSTEMDEBUG}
+        movl    U_SYSTEM_LOWESTSTACK,%ebx
+        cmpl    %eax,%ebx
+        jb      .L_is_not_lowest
+        movl    %eax,U_SYSTEM_LOWESTSTACK
+.L_is_not_lowest:
+{$endif SYSTEMDEBUG}
+        movl    __stkbottom,%ebx
+        cmpl    %eax,%ebx
+        jae     .L__short_on_stack
+        popl    %ebx
+        popl    %eax
+        leave
+        ret     $4
+.L__short_on_stack:
+        { can be usefull for error recovery !! }
+        popl    %ebx
+        popl    %eax
+  end['EAX','EBX'];
+  HandleError(202);
+end;
+{$ASMMODE ATT}
+
 
 
 function paramcount : longint;
@@ -1098,7 +1177,17 @@ end;
 {$endif RTLLITE}
 
 
+var
+  temp_int : tseginfo;
 Begin
+{ save old int 0 and 75 }
+  get_pm_interrupt($00,old_int00);
+  get_pm_interrupt($75,old_int75);
+  temp_int.segment:=get_cs;
+  temp_int.offset:=@new_int00;
+  set_pm_interrupt($00,temp_int);
+{  temp_int.offset:=@new_int75;
+  set_pm_interrupt($75,temp_int); }
 { to test stack depth }
   loweststack:=maxlongint;
 { Setup heap }
@@ -1117,7 +1206,10 @@ Begin
 End.
 {
   $Log$
-  Revision 1.19  1998-09-14 10:48:05  peter
+  Revision 1.20  1998-10-13 21:41:06  peter
+    + int 0 for divide by zero
+
+  Revision 1.19  1998/09/14 10:48:05  peter
     * FPC_ names
     * Heap manager is now system independent