2
0
Эх сурвалжийг харах

+ added currency and widestring support to TWriter and TReader

florian 21 жил өмнө
parent
commit
cd81fa77ea
1 өөрчлөгдсөн 262 нэмэгдсэн , 629 устгасан
  1. 262 629
      rtl/m68k/m68k.inc

+ 262 - 629
rtl/m68k/m68k.inc

@@ -31,668 +31,302 @@
 
 
 procedure fpc_cpuinit;
-begin
-end;
+  begin
+  end;
 
-    { Don't call the following routines directly. }
- Procedure Hlt;[public,alias: 'FPC_HALT_ERROR'];
- { called by code generator on run-time errors. }
- { on entry contains d0 = error code.           }
- var
-  b:byte; { only byte is used... }
- begin
+{$define FPC_SYSTEM_HAS_GET_FRAME}
+function get_frame : pointer; assembler;
   asm
-     move.b d0,b
+    move.l a6,d0
   end;
-     HandleError(b);
- end;
-
-
 
 
-   Procedure FillChar(var x;count:longint;value:byte);[public,alias: 'FPC_FILL_OBJECT'];
-   begin
+{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
+function get_caller_addr(framebp : pointer) : pointer;
+  begin
      asm
-      move.l 8(a6), a0      { destination                   }
-      move.l 12(a6), d1     { number of bytes to fill       }
-      move.b 16(a6),d0      { fill data                     }
-      cmpi.l #65535, d1     { check, if this is a word move }
-      ble    @LMEMSET3      { use fast dbra mode            }
-      bra @LMEMSET2
-    @LMEMSET1:
-      move.b d0,(a0)+
-    @LMEMSET2:
-      subq.l #1,d1
-      cmp.l #-1,d1
-      bne  @LMEMSET1
-      bra @LMEMSET5        { finished slow mode , exit     }
-
-    @LMEMSET4:             { fast loop mode section 68010+ }
-      move.b d0,(a0)+
-    @LMEMSET3:
-      dbra d1,@LMEMSET4
-
-    @LMEMSET5:
-     end ['d0','d1','a0'];
-   end;
-
-   Procedure FillObject(var x; count: longint; value: byte);
-   begin
-     asm
-      move.l 8(a6), a0      { destination                   }
-      move.l 12(a6), d1     { number of bytes to fill       }
-      move.w 16(a6),d0      { fill data                     }
-      cmp.l  #65535, d1     { check, if this is a word move }
-      ble    @LMEMSET3      { use fast dbra mode            }
-      bra @LMEMSET2
-    @LMEMSET1:
-      move.b d0,(a0)+
-    @LMEMSET2:
-      subq.l #1,d1
-      cmp.l #-1,d1
-      bne  @LMEMSET1
-      bra @LMEMSET5        { finished slow mode , exit     }
-
-    @LMEMSET4:             { fast loop mode section 68010+ }
-      move.b d0,(a0)+
-    @LMEMSET3:
-      dbra d1,@LMEMSET4
-
-    @LMEMSET5:
-     end ['d0','d1','a0'];
-   end;
-
-    procedure int_help_constructor;[public,alias:'FPC_HELP_CONSTRUCTOR'];
-
-      begin
-         asm
-            { Entry without preamble, since we need the ESP of the
-              constructor }
-            { Stack (relative to %ebp):
-                12 Self
-                8 VMT-Address
-                4 main programm-Addr
-                0 %ebp
-            }
-            { do we have to initialize self  }
-            { we just need to check for zero }
-            move.l    a5,d0
-            tst.l     d0      { set flags }
-            bne       @LHC_4
-
-            { get memory, but save register first }
-            { temporary variable }
-            subq.l #4,sp
-            move.l sp,a5
-            { Save Registers }
-            movem.l d0-a7,-(sp)
-            { Memory size }
-            move.l 8(a6),a0
-            move.l (a0),-(sp)
-            { push method pointer }
-            move.l a5,-(sp)
-            jsr FPC_GETMEM
-            { Restore all registers in the correct order }
-            movem.l (sp)+,d0-a7
-            { Memory position to a5 }
-            move.l (a5),a5
-            addq.l  #4,sp
-            { If no memory available : fail() }
-            move.l a5,d0
-            tst.l  d0         { set flags for a5 }
-            beq    @LHC_5
-            { init self for the constructor }
-            move.l a5,12(a6)
-         @LHC_4:
-            { is there a VMT address ? }
-            move.l 8(a6),d0
-            or.l   d0,d0
-            bne @LHC_7
-            { In case the constructor doesn't do anything, the Zero-Flag }
-            { can't be put, because this calls Fail() }
-            add.l  #1,d0
-            rts
-         @LHC_7:
-            { set zero inside the object }
-            { Save Registers }
-            movem.l d0-a7,-(sp)
-            move.w  #0,-(sp)
-
-            move.l  8(a6),a0
-            move.l  (a0),-(sp)
-            move.l  a5,-(sp)
-            {                }
-            jsr  FPC_FILLOBJECT
-            { Restore all registers in the correct order }
-            movem.l (sp)+,d0-a7
-            { set the VMT address for the new created object }
-{$ifdef OBJECTVMTOFFSET}
-      { the offset is in %edi since the calling and has not been changed !! }
-            move.l 8(a6),d1
-            move.l d1,(a5,d0.l)
-{$else OBJECTVMTOFFSET}
-            move.l 8(a6),d0
-            move.l d0,(a5)
-{$endif OBJECTVMTOFFSET}
-            or.l d0,d0
-         @LHC_5:
-            rts
-         end;
-      end;
-
-    procedure help_fail;
-
-      begin
-         asm
-         end;
-      end;
-
-    procedure int_help_destructor;[public,alias:'FPC_HELP_DESTRUCTOR'];
-
-      begin
-         asm
-            { Stack (relative to %ebp):
-                12 Self
-                8 VMT-Address
-                4 Main program-Addr
-                0 %ebp
-                d0 contains vmt_offset
-            }
-            { temporary Variable }
-            subq.l #4,sp
-            move.l sp,d6
-            { Save Registers }
-            movem.l d0-a7,-(sp)
-
-            move.l 8(a6),d1         { Get the address of the vmt }
-            or.l   d1,d1            { Check if there is a vmt    }
-            beq    @LHD_3
-            { Yes, get size from SELF! }
-            move.l 12(a6),a0
-            { get VMT-pointer (from Self) to %ebx }
-{$ifdef OBJECTVMTOFFSET}
-      { the offset is in d0 since the calling and has not been changed !! }
-            move.l (a0,d0.l),a1
-{$else OBJECTVMTOFFSET}
-            move.l (a0),a1
-{$endif OBJECTVMTOFFSET}
-            { And put size on the Stack }
-            move.l (a1),-(sp)
-            { SELF }
-            { I think for precaution }
-            { that we should clear the VMT here }
-            clr.l (a0)
-            { get address of local variable into  }
-            { address register                    }
-            move.l d6,a1
-            move.l a0,(a1)
-            move.l a1,-(sp)
-            jsr    FPC_FREEMEM
-         @LHD_3:
-            { Restore all registers in the correct order }
-            movem.l (sp)+,d0-a7
-            add.l #4,sp
-            rts
-         end;
-      end;
-
-  procedure new_class;assembler;[public,alias:'FPC_NEW_CLASS'];
-
-  asm
-     { create class ? }
-     move.l 8(a6), d0
-     tst.l  d0
-     { check for nil... }
-     beq    @NEW_CLASS1
-
-     { a5 contains vmt }
-     move.l a5,-(sp)
-     { call newinstance (class method!) }
-     jsr 16(a5)
-     { new instance returns a pointer to the new created }
-     { instance in d0                                    }
-     { load a5  and insert self                          }
-     move.l d0,8(a6)
-     move.l d0,a5
-     bra    @end
-  @NEW_CLASS1:
-     move.l a5,8(a6)
-  @end:
+        move.l FRAMEBP,a0
+        cmp.l #0,a0
+        beq @Lnul_address
+        move.l 4(a0),a0
+     @Lnul_address:
+        move.l a0,@RESULT
+     end ['a0'];
   end;
 
 
+{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
+function get_caller_frame(framebp : pointer) : pointer;
+  begin
+     asm
+        move.l FRAMEBP,a0
+        cmp.l  #0,a0
+        beq    @Lnul_frame
+        move.l (a0),a0
+     @Lnul_frame:
+        move.l a0,@RESULT
+     end ['a0'];
+  end;
 
-  procedure dispose_class;assembler;[public,alias:'FPC_DISPOSE_CLASS'];
 
-  asm
-     { destroy class ? }
-     move.l 8(a6),d0
-     { save self }
-     move.l a5,8(a6)
-     tst.l  d0
-     beq    @DISPOSE_CLASS
-     { no inherited call }
-     move.l (a5),d0
-     { push self }
-     move.l a5,-(sp)
-     { call freeinstance }
-     move.l d0,a0
-     jsr    20(a0)
-  @DISPOSE_CLASS:
-     { load self }
-     move.l 8(a6),a5
+{$define FPC_SYSTEM_HAS_SPTR}
+function Sptr : Longint;
+  begin
+    asm
+      move.l sp,d0
+      add.l  #8,d0
+      move.l d0,@RESULT
+    end ['d0'];
   end;
 
-  { checks for a correct vmt pointer }
-  procedure int_check_object;assembler;[public,alias:'FPC_CHECK_OBJECT'];
-  { ON ENTRY: a0 -> Pointer to the VMT                  }
-  {   Nota: All registers must be preserved including   }
-  {   A0 itself!                                        }
-  asm
-     move.l   d0,-(sp)
-     tst.l    a0
-     { z flag set if zero }
-     beq      @co_re
-
-     move.l   (a0),d0
-     add.l    4(a0),d0
-     bne      @co_re
-     bra      @end
-@co_re:
-     move.l   (sp)+,d0
-     move.b   #210,d0
-     jsr      FPC_HALT_ERROR
-@end:
-     move.l   (sp)+,d0
-  end;
 
+{$define FPC_SYSTEM_HAS_FILLCHAR}
+procedure FillChar(var x;count:longint;value:byte);[public,alias: 'FPC_FILL_OBJECT'];
+  begin
+    asm
+     move.l 8(a6), a0      { destination                   }
+     move.l 12(a6), d1     { number of bytes to fill       }
+     move.b 16(a6),d0      { fill data                     }
+     cmpi.l #65535, d1     { check, if this is a word move }
+     ble    @LMEMSET3      { use fast dbra mode            }
+     bra @LMEMSET2
+   @LMEMSET1:
+     move.b d0,(a0)+
+   @LMEMSET2:
+     subq.l #1,d1
+     cmp.l #-1,d1
+     bne  @LMEMSET1
+     bra @LMEMSET5        { finished slow mode , exit     }
+
+   @LMEMSET4:             { fast loop mode section 68010+ }
+     move.b d0,(a0)+
+   @LMEMSET3:
+     dbra d1,@LMEMSET4
+
+   @LMEMSET5:
+    end ['d0','d1','a0'];
+  end;
 
-    function get_frame : longint; assembler;
-      asm
-              move.l a6,d0
-      end;
-
-
-    function get_caller_addr(framebp:longint):longint;
-      begin
-         asm
-            move.l FRAMEBP,a0
-            cmp.l #0,a0
-            beq @Lnul_address
-            move.l 4(a0),a0
-         @Lnul_address:
-            move.l a0,@RESULT
-         end ['a0'];
-      end;
-
-    function get_caller_frame(framebp:longint):longint;
-
-      begin
-         asm
-            move.l FRAMEBP,a0
-            cmp.l  #0,a0
-            beq    @Lnul_frame
-            move.l (a0),a0
-         @Lnul_frame:
-            move.l a0,@RESULT
-         end ['a0'];
-      end;
 
+{$ifdef dummy}
 {    procedure strcopy(dstr,sstr : pointer;len : longint);[public,alias: 'STRCOPY'];}
-     procedure strcopy; assembler;[public,alias: 'FPC_STRCOPY'];
-    {---------------------------------------------------}
-    { Low-level routine to copy a string to another     }
-    { string with maximum length. Never call directly!  }
-    { On Entry:                                         }
-    {     a1.l = string to copy to                      }
-    {     a0.l = source string                          }
-    {     d0.l = maximum length of copy                 }
-    { registers destroyed: a0,a1,d0,d1                  }
-    {---------------------------------------------------}
-         asm
+procedure strcopy; assembler;[public,alias: 'FPC_STRCOPY'];
+{---------------------------------------------------}
+{ Low-level routine to copy a string to another     }
+{ string with maximum length. Never call directly!  }
+{ On Entry:                                         }
+{     a1.l = string to copy to                      }
+{     a0.l = source string                          }
+{     d0.l = maximum length of copy                 }
+{ registers destroyed: a0,a1,d0,d1                  }
+{---------------------------------------------------}
+asm
 {            move.l 12(a6),a0
-            move.l 16(a6),a1
-            move.l 8(a6),d1 }
-            move.l d0,d1
-
-            move.b (a0)+,d0     { Get source length }
-            and.w  #$ff,d0
-            cmp.w  d1,d0        { This is a signed comparison! }
-            ble    @LM4
-            move.b d1,d0        { If longer than maximum size of target, cut
-                                  source length }
-         @LM4:
-            andi.l #$ff,d0     { zero extend d0-byte }
-            move.l d0,d1       { save length to copy }
-            move.b d0,(a1)+    { save new length     }
-            { Check if copying length is zero - if so then }
-            { exit without copying anything.               }
-            tst.b  d1
-            beq    @Lend
-            bra    @LMSTRCOPY55
-         @LMSTRCOPY56:         { 68010 Fast loop mode }
-            move.b (a0)+,(a1)+
-         @LMSTRCOPY55:
-            dbra  d1,@LMSTRCOPY56
-         @Lend:
-      end;
-
-    { Concatenate Strings }
-    { PARAMETERS ARE REVERSED COMPARED TO NORMAL! }
-    { therefore online assembler may not parse the params as normal }
-    procedure strconcat(s1,s2 : pointer);[public,alias: 'STRCONCAT'];
-
-      begin
-         asm
-          move.b  #255,d0
-          move.l  s1,a0                { a0 = destination }
-          move.l  s2,a1                { a1 = source      }
-          sub.b   (a0),d0              {  copyl:= 255 -length(s1)    }
-          move.b  (a1),d6
-          and.w   #$ff,d0              { Sign flags are checked!     }
-          and.w   #$ff,d6
-          cmp.w   d6,d0                { if copyl > length(s2) then  }
-          ble     @Lcontinue
-          move.b  (a1),d0              {  copyl:=length(s2)          }
-    @Lcontinue:
-          move.b  (a0),d6
-          and.l   #$ff,d6
-          lea     1(a0,d6),a0          { s1[length(s1)+1]            }
-          add.l   #1,a1                { s2[1]                       }
-          move.b  d0,d6
-          { Check if copying length is zero - if so then }
-          { exit without copying anything.               }
-          tst.b  d6
-          beq    @Lend
-          bra    @ALoop
-    @Loop:
-          move.b  (a1)+,(a0)+          { s1[i] := s2[i];             }
-    @ALoop:
-          dbra    d6,@Loop
-          move.l  s1,a0
-          add.b   d0,(a0)              { change to new string length }
-    @Lend:
-         end ['d0','d1','a0','a1','d6'];
-      end;
-
-    { Compares strings }
-    { DO NOT CALL directly.                                 }
-    {   a0 = pointer to first string to compare             }
-    {   a1 = pointer to second string to compare            }
-    {   ALL FLAGS are set appropriately.                    }
-    {    ZF = strings are equal                             }
-    { REGISTERS DESTROYED: a0, a1, d0, d1, d6               }
-    procedure strcmp; assembler;[public,alias:'FPC_STRCMP'];
+   move.l 16(a6),a1
+   move.l 8(a6),d1 }
+   move.l d0,d1
+
+   move.b (a0)+,d0     { Get source length }
+   and.w  #$ff,d0
+   cmp.w  d1,d0        { This is a signed comparison! }
+   ble    @LM4
+   move.b d1,d0        { If longer than maximum size of target, cut
+                         source length }
+@LM4:
+   andi.l #$ff,d0     { zero extend d0-byte }
+   move.l d0,d1       { save length to copy }
+   move.b d0,(a1)+    { save new length     }
+   { Check if copying length is zero - if so then }
+   { exit without copying anything.               }
+   tst.b  d1
+   beq    @Lend
+   bra    @LMSTRCOPY55
+@LMSTRCOPY56:         { 68010 Fast loop mode }
+   move.b (a0)+,(a1)+
+@LMSTRCOPY55:
+   dbra  d1,@LMSTRCOPY56
+@Lend:
+end;
+
+
+{ Concatenate Strings }
+{ PARAMETERS ARE REVERSED COMPARED TO NORMAL! }
+{ therefore online assembler may not parse the params as normal }
+procedure strconcat(s1,s2 : pointer);[public,alias: 'STRCONCAT'];
+  begin
      asm
-            move.b (a0)+,d0     { Get length of first string  }
-            move.b (a1)+,d6     { Get length of 2nd string    }
-
-            move.b  d6,d1      { Save length of string for final compare   }
-
-            cmp.b  d0,d6        { Get shortest string length   }
-            ble    @LSTRCONCAT1
-            move.b d0,d6       { Set length to shortest string }
-
-         @LSTRCONCAT1:
-            tst.b  d6          { Both strings have a length of zero, exit }
-            beq    @LSTRCONCAT2
-
-            andi.l  #$ff,d6
-
-
-            subq.l  #1,d6      { subtract first attempt                    }
-            { if value is -1 then don't loop and just compare lengths of   }
-            { both strings before exiting.                                 }
-            bmi     @LSTRCONCAT2
-            or.l    d0,d0      { Make sure to set Zerfo flag to 0          }
-         @LSTRCONCAT5:
-            { Workaroung for GAS v.134 bug }
-            {  old: cmp.b (a1)+,(a0)+      }
-            cmpm.b  (a1)+,(a0)+
-         @LSTRCONCAT4:
-            dbne    d6,@LSTRCONCAT5   { Repeat until not equal }
-            bne     @LSTRCONCAT3
-          @LSTRCONCAT2:
-            { If length of both string are equal }
-            { Then set zero flag                 }
-            cmp.b   d1,d0   { Compare length - set flag if equal length strings }
-         @LSTRCONCAT3:
-     end;
-
-
-  Function strpas(p: pchar): string;
-  { only 255 first characters are actually copied. }
-   var
-    counter : byte;
-    str: string;
-  Begin
-     counter := 0;
-     str := '';
-     while (ord(p[counter]) <> 0) and (counter < 255) do
-     begin
-        counter:=counter+1;
-        str[counter] := char(p[counter-1]);
-     end;
-     str[0] := char(counter);
-     strpas := str;
+      move.b  #255,d0
+      move.l  s1,a0                { a0 = destination }
+      move.l  s2,a1                { a1 = source      }
+      sub.b   (a0),d0              {  copyl:= 255 -length(s1)    }
+      move.b  (a1),d6
+      and.w   #$ff,d0              { Sign flags are checked!     }
+      and.w   #$ff,d6
+      cmp.w   d6,d0                { if copyl > length(s2) then  }
+      ble     @Lcontinue
+      move.b  (a1),d0              {  copyl:=length(s2)          }
+@Lcontinue:
+      move.b  (a0),d6
+      and.l   #$ff,d6
+      lea     1(a0,d6),a0          { s1[length(s1)+1]            }
+      add.l   #1,a1                { s2[1]                       }
+      move.b  d0,d6
+      { Check if copying length is zero - if so then }
+      { exit without copying anything.               }
+      tst.b  d6
+      beq    @Lend
+      bra    @ALoop
+@Loop:
+      move.b  (a1)+,(a0)+          { s1[i] := s2[i];             }
+@ALoop:
+      dbra    d6,@Loop
+      move.l  s1,a0
+      add.b   d0,(a0)              { change to new string length }
+@Lend:
+     end ['d0','d1','a0','a1','d6'];
   end;
 
-  function strlen(p : pchar) : longint;
-  var
-     counter : longint;
-  Begin
-       counter := 0;
-       repeat
-          counter:=counter+1;
-       until ord(p[counter]) = 0;
-       strlen := counter;
-  end;
+{ Compares strings }
+{ DO NOT CALL directly.                                 }
+{   a0 = pointer to first string to compare             }
+{   a1 = pointer to second string to compare            }
+{   ALL FLAGS are set appropriately.                    }
+{    ZF = strings are equal                             }
+{ REGISTERS DESTROYED: a0, a1, d0, d1, d6               }
+procedure strcmp; assembler;[public,alias:'FPC_STRCMP'];
+asm
+       move.b (a0)+,d0     { Get length of first string  }
+       move.b (a1)+,d6     { Get length of 2nd string    }
+
+       move.b  d6,d1      { Save length of string for final compare   }
+
+       cmp.b  d0,d6        { Get shortest string length   }
+       ble    @LSTRCONCAT1
+       move.b d0,d6       { Set length to shortest string }
+
+    @LSTRCONCAT1:
+       tst.b  d6          { Both strings have a length of zero, exit }
+       beq    @LSTRCONCAT2
+
+       andi.l  #$ff,d6
+
+
+       subq.l  #1,d6      { subtract first attempt                    }
+       { if value is -1 then don't loop and just compare lengths of   }
+       { both strings before exiting.                                 }
+       bmi     @LSTRCONCAT2
+       or.l    d0,d0      { Make sure to set Zerfo flag to 0          }
+    @LSTRCONCAT5:
+       { Workaroung for GAS v.134 bug }
+       {  old: cmp.b (a1)+,(a0)+      }
+       cmpm.b  (a1)+,(a0)+
+    @LSTRCONCAT4:
+       dbne    d6,@LSTRCONCAT5   { Repeat until not equal }
+       bne     @LSTRCONCAT3
+     @LSTRCONCAT2:
+       { If length of both string are equal }
+       { Then set zero flag                 }
+       cmp.b   d1,d0   { Compare length - set flag if equal length strings }
+    @LSTRCONCAT3:
+end;
+{$endif dummy}
 
 
-   procedure move(var source;var dest;count : longint);
-   { base pointer+8 = source                  }
-   { base pointer+12 = destination            }
-   { base pointer+16 = number of bytes to move}
-   begin
-     asm
-      clr.l      d0
-      move.l   16(a6),d0   {  number of bytes }
-    @LMOVE0:
-      move.l   12(a6),a1   {  destination          }
-      move.l   8(a6),a0      {  source               }
-
-      cmpi.l #65535, d0     { check, if this is a word move }
-      ble    @LMEMSET00     { use fast dbra mode 68010+     }
-
-      cmp.l      a0,a1         {  check copy direction }
-      bls      @LMOVE4
-      add.l      d0,a0         { move pointers to end  }
-      add.l      d0,a1
-      bra     @LMOVE2
-    @LMOVE1:
-      move.b   -(a0),-(a1)   {  (s < d) copy loop }
-    @LMOVE2:
-      subq.l    #1,d0
-      cmpi.l    #-1,d0
-      bne       @LMOVE1
-      bra       @LMOVE5
-    @LMOVE3:
-      move.b  (a0)+,(a1)+  { (s >= d) copy loop }
-    @LMOVE4:
-      subq.l    #1,d0
-      cmpi.l    #-1,d0
-      bne       @LMOVE3
-      bra       @LMOVE5
-
-    @LMEMSET00:            { use fast loop mode 68010+ }
-      cmp.l      a0,a1         {  check copy direction }
-      bls      @LMOVE04
-      add.l      d0,a0         { move pointers to end  }
-      add.l      d0,a1
-      bra     @LMOVE02
-    @LMOVE01:
-      move.b   -(a0),-(a1)   {  (s < d) copy loop }
-    @LMOVE02:
-      dbra      d0,@LMOVE01
-      bra       @LMOVE5
-    @LMOVE03:
-      move.b  (a0)+,(a1)+  { (s >= d) copy loop }
-    @LMOVE04:
-      dbra      d0,@LMOVE03
-    { end fast loop mode }
-    @LMOVE5:
-    end ['d0','a0','a1'];
-   end;
-
-
-    procedure fillword(var x;count : longint;value : word);
-
-      begin
-     asm
-      move.l 8(a6), a0      { destination             }
-      move.l 12(a6), d1     { number of bytes to fill }
-      move.w 16(a6),d0      { fill data               }
-      bra @LMEMSET21
-    @LMEMSET11:
-      move.w d0,(a0)+
-    @LMEMSET21:
-      subq.l #1,d1
-      cmp.b #-1,d1
-      bne  @LMEMSET11
-     end ['d0','d1','a0'];
-   end;
-
-
-    function abs(l : longint) : longint;
-
-      begin
-         asm
-            move.l 8(a6),d0
-            tst.l  d0
-            bpl @LMABS1
-            neg.l d0
-         @LMABS1:
-            move.l d0,@RESULT
-         end ['d0'];
-      end;
-
-    function odd(l : longint) : boolean;
-
-      begin
-        if (l and $01) = $01 then
-          odd := TRUE
-        else
-          odd := FALSE;
-      end;
-
-    function sqr(l : longint) : longint;
-
-      begin
-         sqr := l*l;
-      end;
-
-    procedure int_str(l : longint;var s : string);
-
-      var
-        value: longint;
-        negative: boolean;
-
-      begin
-         negative := false;
-         s:='';
-         { Workaround: }
-         if l=$80000000 then
-           begin
-              s:='-2147483648';
-              exit;
-           end;
-        { handle case where l = 0 }
-         if l = 0 then
-         begin
-           s:='0';
-           exit;
-         end;
-         If l < 0 then
-         begin
-             negative := true;
-             value:=abs(l);
-         end
-         else
-             value:=l;
-       { handle non-zero case }
-       while value>0 do
-         begin
-            s:=char((value mod 10)+ord('0'))+s;
-            value := value div 10;
-         end;
-         if negative then
-           s := '-' + s;
-      end;
-
-
-Function Sptr : Longint;
+{$define FPC_SYSTEM_HAS_MOVE}
+procedure move(var source;var dest;count : longint);
+{ base pointer+8 = source                  }
+{ base pointer+12 = destination            }
+{ base pointer+16 = number of bytes to move}
 begin
   asm
-    move.l sp,d0
-    add.l  #8,d0
-    move.l d0,@RESULT
-  end ['d0'];
+    clr.l      d0
+    move.l   16(a6),d0   {  number of bytes }
+  @LMOVE0:
+    move.l   12(a6),a1   {  destination          }
+    move.l   8(a6),a0      {  source               }
+
+    cmpi.l #65535, d0     { check, if this is a word move }
+    ble    @LMEMSET00     { use fast dbra mode 68010+     }
+
+    cmp.l      a0,a1         {  check copy direction }
+    bls      @LMOVE4
+    add.l      d0,a0         { move pointers to end  }
+    add.l      d0,a1
+    bra     @LMOVE2
+  @LMOVE1:
+    move.b   -(a0),-(a1)   {  (s < d) copy loop }
+  @LMOVE2:
+    subq.l    #1,d0
+    cmpi.l    #-1,d0
+    bne       @LMOVE1
+    bra       @LMOVE5
+  @LMOVE3:
+    move.b  (a0)+,(a1)+  { (s >= d) copy loop }
+  @LMOVE4:
+    subq.l    #1,d0
+    cmpi.l    #-1,d0
+    bne       @LMOVE3
+    bra       @LMOVE5
+
+  @LMEMSET00:            { use fast loop mode 68010+ }
+    cmp.l      a0,a1         {  check copy direction }
+    bls      @LMOVE04
+    add.l      d0,a0         { move pointers to end  }
+    add.l      d0,a1
+    bra     @LMOVE02
+  @LMOVE01:
+    move.b   -(a0),-(a1)   {  (s < d) copy loop }
+  @LMOVE02:
+    dbra      d0,@LMOVE01
+    bra       @LMOVE5
+  @LMOVE03:
+    move.b  (a0)+,(a1)+  { (s >= d) copy loop }
+  @LMOVE04:
+    dbra      d0,@LMOVE03
+  { end fast loop mode }
+  @LMOVE5:
+  end ['d0','a0','a1'];
 end;
 
 
+{$define FPC_SYSTEM_HAS_FILLWORD}
+procedure fillword(var x;count : longint;value : word);
+  begin
+    asm
+     move.l 8(a6), a0      { destination             }
+     move.l 12(a6), d1     { number of bytes to fill }
+     move.w 16(a6),d0      { fill data               }
+     bra @LMEMSET21
+   @LMEMSET11:
+     move.w d0,(a0)+
+   @LMEMSET21:
+     subq.l #1,d1
+     cmp.b #-1,d1
+     bne  @LMEMSET11
+    end ['d0','d1','a0'];
+  end;
 
 
- Procedure BoundsCheck;assembler;[public,alias:'FPC_RE_BOUNDS_CHECK'];
- { called by code generator with R+ state to    }
- { determine if a range check occured.          }
- { Only in 68000 mode, in 68020 mode this is    }
- { inline.                                      }
- { On Entry:                                    }
- {   A1 = address contaning min and max indexes }
- {   D0 = value of current index to check.      }
- asm
-  cmp.l   (A1),D0        { lower bound ...    }
-  bmi     @rebounderr    { is index lower ... }
-  add.l   #4,A1
-  cmp.l   (A1),D0
-  bmi     @reboundend
-  beq     @reboundend
-@rebounderr:
-  move.l  #201,d0
-  jsr     FPC_HALT_ERROR
-@reboundend:
- end;
-
-{****************************************************************************
-                                 IoCheck
-****************************************************************************}
-
-procedure int_iocheck(addr : longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'IOCHECK'];
-var
-  l : longint;
-begin
-  asm
-        movem.l d0-a7,-(sp)
-  end;
-  if InOutRes<>0 then
-   begin
-     l:=InOutRes;
-     InOutRes:=0;
-     If ErrorProc<>Nil then
-       TErrorProc(Errorproc)(l,pointer(addr));
-{$ifndef RTLLITE}
-     writeln('IO-Error ',l,' at 0x',HexStr(addr,8));
-{$endif}
-     Halt(byte(l));
-   end;
-  asm
-        movem.l (sp)+,d0-a7
+{$define FPC_SYSTEM_HAS_ABS_LONGINT}
+function abs(l : longint) : longint;
+  begin
+     asm
+        move.l 8(a6),d0
+        tst.l  d0
+        bpl @LMABS1
+        neg.l d0
+     @LMABS1:
+        move.l d0,@RESULT
+     end ['d0'];
   end;
-end;
+
 
 {
   $Log$
-  Revision 1.4  2004-01-02 17:22:14  jonas
+  Revision 1.5  2004-05-23 12:42:42  florian
+    + added currency and widestring support to TWriter and TReader
+
+  Revision 1.4  2004/01/02 17:22:14  jonas
     + fpc_cpuinit procedure to allow cpu/fpu initialisation before any unit
       initialises
     + fpu exceptions for invalid operations and division by zero enabled for
@@ -700,5 +334,4 @@ end;
 
   Revision 1.3  2002/09/07 16:01:20  peter
     * old logs removed and tabs fixed
-
 }