Index: amicommon/athreads.pp
===================================================================
--- amicommon/athreads.pp	(revision 45847)
+++ amicommon/athreads.pp	(working copy)
@@ -981,107 +981,25 @@
 end;
 
 // Timer stuff
-procedure NewList(List: PList); inline;
-begin
-  with List^ do
-  begin
-    lh_Head := PNode(@lh_Tail);
-    lh_Tail := nil;
-    lh_TailPred := PNode(@lh_Head)
-  end;
-end;
 
-function CreatePort(Name: PChar; Pri: LongInt): PMsgPort;
-var
-  SigBit: ShortInt;
-  Port: PMsgPort;
-begin
-  Sigbit := AllocSignal(-1);
-  if sigbit = -1 then
-    CreatePort := nil;
-  Port := ExecAllocMem(SizeOf(TMsgPort), MEMF_CLEAR);
-  if Port = nil then
-  begin
-    FreeSignal(SigBit);
-    CreatePort := nil;
-  end;
-  with port^ do
-  begin
-    if Assigned(Name) then
-      mp_Node.ln_Name := Name
-    else
-      mp_Node.ln_Name := nil;
-    mp_Node.ln_Pri := pri;
-    mp_Node.ln_Type := 4;
-    mp_Flags := 0;
-    mp_SigBit := SigBit;
-    mp_SigTask := FindTask(nil);
-  end;
-  if Assigned(Name) then
-    AddPort(Port)
-  else
-    NewList(Addr(Port^.mp_MsgList));
-  CreatePort := Port;
-end;
-
-procedure DeletePort(Port: PMsgPort);
-begin
-  if port <> nil then
-  begin
-    if Port^.mp_Node.ln_Name <> nil then
-      RemPort(Port);
-
-    Port^.mp_Node.ln_Type := $FF;
-    Port^.mp_MsgList.lh_Head := PNode(-1);
-    FreeSignal(Port^.mp_SigBit);
-    ExecFreeMem(Port, SizeOf(TMsgPort));
-  end;
-end;
-
-function CreateExtIO(Port: PMsgPort; Size: LongInt): PIORequest;
-begin
-  Result := nil;
-  if Port <> nil then
-  begin
-    Result := ExecAllocMem(Size, MEMF_CLEAR);
-    if Result <> nil then
-    begin
-      Result^.io_Message.mn_Node.ln_Type := 7;
-      Result^.io_Message.mn_Length := Size;
-      Result^.io_Message.mn_ReplyPort := Port;
-    end;
-  end;
-end;
-
-procedure DeleteExtIO (IoReq: PIORequest);
-begin
-  if IoReq <> nil then
-  begin
-    IoReq^.io_Message.mn_Node.ln_Type := $FF;
-    IoReq^.io_Message.mn_ReplyPort := PMsgPort(-1);
-    IoReq^.io_Device := PDevice(-1);
-    ExecFreeMem(IoReq, IoReq^.io_Message.mn_Length);
-  end
-end;
-
 function Create_Timer(TheUnit: LongInt): PTimeRequest;
 var
   TimerPort: PMsgPort;
 begin
   Result := nil;
-  TimerPort := CreatePort(nil, 0);
+  TimerPort := CreateMsgPort;
   if TimerPort = nil then
     Exit;
-  Result := PTimeRequest(CreateExtIO(TimerPort, SizeOf(TTimeRequest)));
+  Result := PTimeRequest(CreateIORequest(TimerPort, SizeOf(TTimeRequest)));
   if Result = Nil then
   begin
-    DeletePort(TimerPort);
+    DeleteMsgPort(TimerPort);
     Exit;
   end;
   if OpenDevice(TIMERNAME, TheUnit, PIORequest(Result), 0) <> 0 then
   begin
-    DeleteExtIO(PIORequest(Result));
-    DeletePort(TimerPort);
+    DeleteIORequest(PIORequest(Result));
+    DeleteMsgPort(TimerPort);
     Result := nil;
   end;
 end;
@@ -1094,12 +1012,13 @@
   if assigned(WhichTimer) then
   begin
     CloseDevice(PIORequest(WhichTimer));
-    DeleteExtIO(PIORequest(WhichTimer));
+    DeleteIORequest(PIORequest(WhichTimer));
   end;
   if Assigned(WhichPort) then
-    DeletePort(WhichPort);
+    DeleteMsgPort(WhichPort);
 end;
 
+
 function GetEventTime(TR: PTimeRequest): Int64;
 begin
   Result := -1;
Index: amicommon/dos.pp
===================================================================
--- amicommon/dos.pp	(revision 45847)
+++ amicommon/dos.pp	(working copy)
@@ -67,11 +67,16 @@
 {$I dos.inc}
 
 
+var
+  TimerBase: Pointer; {* needed to use timerf.inc *}
+
 { * include OS specific functions & definitions * }
 
+
 {$include execd.inc}
 {$include execf.inc}
 {$include timerd.inc}
+{$include timerf.inc}
 {$include doslibd.inc}
 {$include doslibf.inc}
 {$include utilf.inc}
@@ -262,223 +267,140 @@
 { Here are a lot of stuff just for setdate and settime }
 
 var
-  TimerBase : Pointer;
+  TimerMsgPort: PMsgPort;
+  TimerRequest: PTimeRequest;
 
-
-procedure NewList (list: pList);
+procedure CreateTimeRequest;
 begin
-  with list^ do begin
-    lh_Head     := pNode(@lh_Tail);
-    lh_Tail     := NIL;
-    lh_TailPred := pNode(@lh_Head)
-  end;
-end;
-
-function CreateExtIO (port: pMsgPort; size: Longint): pIORequest;
-var
-   IOReq: pIORequest;
-begin
-    IOReq := NIL;
-    if port <> NIL then
+  TimerMsgPort:=CreateMsgPort;
+  if assigned(TimerMsgPort) then
+  begin
+    TimerRequest:=PTimeRequest(CreateIORequest(TimerMsgPort,sizeof(TTimeRequest)));
+    if assigned(TimerRequest) then
     begin
-        IOReq := execAllocMem(size, MEMF_CLEAR);
-        if IOReq <> NIL then
-        begin
-            IOReq^.io_Message.mn_Node.ln_Type   := 7;
-            IOReq^.io_Message.mn_Length    := size;
-            IOReq^.io_Message.mn_ReplyPort := port;
-        end;
+      if OpenDevice(TIMERNAME,UNIT_MICROHZ,PIORequest(TimerRequest),0) = 0 then
+        TimerBase:=pointer(TimerRequest^.tr_Node.io_Device);
     end;
-    CreateExtIO := IOReq;
+  end;
 end;
 
-procedure DeleteExtIO (ioReq: pIORequest);
+procedure DeleteTimeRequest;
 begin
-    if ioReq <> NIL then
-    begin
-        ioReq^.io_Message.mn_Node.ln_Type := $FF;
-        ioReq^.io_Message.mn_ReplyPort    := pMsgPort(-1);
-        ioReq^.io_Device                  := pDevice(-1);
-        execFreeMem(ioReq, ioReq^.io_Message.mn_Length);
-    end
-end;
+  if assigned(TimerBase) then
+    CloseDevice(PIORequest(TimerRequest));
 
-function Createport(name : PChar; pri : longint): pMsgPort;
-var
-   sigbit : ShortInt;
-   port    : pMsgPort;
-begin
-   sigbit := AllocSignal(-1);
-   if sigbit = -1 then CreatePort := nil;
-   port := execAllocMem(sizeof(tMsgPort),MEMF_CLEAR);
-   if port = nil then begin
-      FreeSignal(sigbit);
-      CreatePort := nil;
-   end;
-   with port^ do begin
-       if assigned(name) then
-       mp_Node.ln_Name := name
-       else mp_Node.ln_Name := nil;
-       mp_Node.ln_Pri := pri;
-       mp_Node.ln_Type := 4;
-       mp_Flags := 0;
-       mp_SigBit := sigbit;
-       mp_SigTask := FindTask(nil);
-   end;
-   if assigned(name) then AddPort(port)
-   else NewList(addr(port^.mp_MsgList));
-   CreatePort := port;
-end;
+  TimerBase:=nil;
 
-procedure DeletePort (port: pMsgPort);
-begin
-    if port <> NIL then
-    begin
-        if port^.mp_Node.ln_Name <> NIL then
-            RemPort(port);
-
-        port^.mp_Node.ln_Type     := $FF;
-        port^.mp_MsgList.lh_Head  := pNode(-1);
-        FreeSignal(port^.mp_SigBit);
-        execFreeMem(port, sizeof(tMsgPort));
-    end;
+  if assigned(TimerRequest) then
+    DeleteIORequest(PIORequest(TimerRequest));
+  if assigned(TimerMsgPort) then
+    DeleteMsgPort(TimerMsgPort);
 end;
 
 
-function Create_Timer(theUnit : longint) : pTimeRequest;
-var
-  Error : longint;
-  TimerPort : pMsgPort;
-  TimeReq : pTimeRequest;
-begin
-  TimerPort := CreatePort(Nil, 0);
-  if TimerPort = Nil then
-    Create_Timer := Nil;
-  TimeReq := pTimeRequest(CreateExtIO(TimerPort,sizeof(tTimeRequest)));
-  if TimeReq = Nil then begin
-    DeletePort(TimerPort);
-    Create_Timer := Nil;
-  end;
-  Error := OpenDevice(TIMERNAME, theUnit, pIORequest(TimeReq), 0);
-  if Error <> 0 then begin
-    DeleteExtIO(pIORequest(TimeReq));
-    DeletePort(TimerPort);
-    Create_Timer := Nil;
-  end;
-  TimerBase := pointer(TimeReq^.tr_Node.io_Device);
-  Create_Timer := pTimeRequest(TimeReq);
-end;
-
-Procedure Delete_Timer(WhichTimer : pTimeRequest);
-var
-    WhichPort : pMsgPort;
-begin
-
-    WhichPort := WhichTimer^.tr_Node.io_Message.mn_ReplyPort;
-    if assigned(WhichTimer) then begin
-        CloseDevice(pIORequest(WhichTimer));
-        DeleteExtIO(pIORequest(WhichTimer));
-    end;
-    if assigned(WhichPort) then
-        DeletePort(WhichPort);
-end;
-
 function set_new_time(secs, micro : longint): longint;
 var
     tr : ptimerequest;
 begin
-    tr := create_timer(UNIT_MICROHZ);
-
-    { non zero return says error }
-    if tr = nil then set_new_time := -1;
-
-    tr^.tr_time.tv_secs := secs;
-    tr^.tr_time.tv_micro := micro;
-    tr^.tr_node.io_Command := TR_SETSYSTIME;
-    DoIO(pIORequest(tr));
-
-    delete_timer(tr);
-    set_new_time := 0;
+  if assigned(TimerBase) then
+  begin
+    with TimerRequest^ do
+    begin
+      tr_time.tv_secs:=secs;
+      tr_time.tv_micro:=micro;
+      tr_node.io_Command:=TR_SETSYSTIME;
+    end;
+    set_new_time:=DoIO(PIORequest(TimerRequest));
+  end
+  else
+    set_new_time:=-1;
 end;
 
-function get_sys_time(tv : ptimeval): longint;
+function get_sys_time(tv : ptimeval): longint; public name '_fpc_amiga_get_sys_time';
 var
-    tr : ptimerequest;
+  tr : ptimerequest;
 begin
-    tr := create_timer( UNIT_MICROHZ );
-
-    { non zero return says error }
-    if tr = nil then get_sys_time := -1;
-
-    tr^.tr_node.io_Command := TR_GETSYSTIME;
-    DoIO(pIORequest(tr));
-
-    { structure assignment }
-    tv^ := tr^.tr_time;
-
-    delete_timer(tr);
-    get_sys_time := 0;
+  if assigned(TimerBase) then
+  begin
+{$if not defined(AMIGA_V1_0_ONLY) and not defined(AMIGA_V1_2_ONLY)}
+    GetSysTime(tv);
+    get_sys_time:=0;
+{$else}
+    with TimerRequest^ do
+    begin
+      tr_node.io_Command:=TR_GETSYSTIME;
+    end;
+    DoIO(PIORequest(TimerRequest));
+    get_sys_time:=0;
+{$endif}
+  end
+  else
+    get_sys_time:=-1;
 end;
 
 procedure GetDate(Var Year, Month, MDay, WDay: Word);
 var
-  cd    : pClockData;
+  cd : TClockData;
   oldtime : ttimeval;
 begin
-  new(cd);
-  get_sys_time(@oldtime);
-  Amiga2Date(oldtime.tv_secs,cd);
-  Year  := cd^.year;
-  Month := cd^.month;
-  MDay  := cd^.mday;
-  WDay  := cd^.wday;
-  dispose(cd);
+  if assigned(TimerBase) then
+  begin
+    get_sys_time(@oldtime);
+    Amiga2Date(oldtime.tv_secs,@cd);
+    Year  := cd.year;
+    Month := cd.month;
+    MDay  := cd.mday;
+    WDay  := cd.wday;
+  end;
 end;
 
 procedure SetDate(Year, Month, Day: Word);
 var
-  cd : pClockData;
+  cd : TClockData;
   oldtime : ttimeval;
 begin
-  new(cd);
-  get_sys_time(@oldtime);
-  Amiga2Date(oldtime.tv_secs,cd);
-  cd^.year := Year;
-  cd^.month := Month;
-  cd^.mday := Day;
-  set_new_time(Date2Amiga(cd),0);
-  dispose(cd);
+  if assigned(TimerBase) then
+  begin
+    get_sys_time(@oldtime);
+    Amiga2Date(oldtime.tv_secs,@cd);
+    cd.year := Year;
+    cd.month := Month;
+    cd.mday := Day;
+    set_new_time(Date2Amiga(@cd),0);
+  end;
 end;
 
 procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
 var
-  cd      : pClockData;
+  cd      : TClockData;
   oldtime : ttimeval;
 begin
-  new(cd);
-  get_sys_time(@oldtime);
-  Amiga2Date(oldtime.tv_secs,cd);
-  Hour   := cd^.hour;
-  Minute := cd^.min;
-  Second := cd^.sec;
-  Sec100 := oldtime.tv_micro div 10000;
-  dispose(cd);
+  if assigned(TimerBase) then
+  begin
+    get_sys_time(@oldtime);
+    Amiga2Date(oldtime.tv_secs,@cd);
+    Hour   := cd.hour;
+    Minute := cd.min;
+    Second := cd.sec;
+    Sec100 := oldtime.tv_micro div 10000;
+  end;
 end;
 
 
 Procedure SetTime(Hour, Minute, Second, Sec100: Word);
 var
-  cd : pClockData;
+  cd : TClockData;
   oldtime : ttimeval;
 begin
-  new(cd);
-  get_sys_time(@oldtime);
-  Amiga2Date(oldtime.tv_secs,cd);
-  cd^.hour := Hour;
-  cd^.min := Minute;
-  cd^.sec := Second;
-  set_new_time(Date2Amiga(cd), Sec100 * 10000);
-  dispose(cd);
+  if assigned(TimerBase) then
+  begin
+    get_sys_time(@oldtime);
+    Amiga2Date(oldtime.tv_secs,@cd);
+    cd.hour := Hour;
+    cd.min := Minute;
+    cd.sec := Second;
+    set_new_time(Date2Amiga(@cd),0);
+  end;
 end;
 
 
@@ -486,7 +408,7 @@
 var
   TV: TTimeVal;
 begin
-  Get_Sys_Time (@TV);
+  get_sys_time(@TV);
   GetMsCount := int64 (TV.TV_Secs) * 1000 + TV.TV_Micro div 1000;
 end;
 
@@ -1209,8 +1131,13 @@
   end;
 end;
 
-begin
+initialization
   DosError:=0;
   StrOfPaths := '';
+  CreateTimeRequest;
   RefreshDeviceList;
+
+finalization
+  DeleteTimeRequest;
+
 end.
Index: amicommon/sysutils.pp
===================================================================
--- amicommon/sysutils.pp	(revision 45847)
+++ amicommon/sysutils.pp	(working copy)
@@ -34,7 +34,9 @@
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_OSERROR}
 {$DEFINE HAS_TEMPDIR}
+{$DEFINE HAS_GETTICKCOUNT64}
 
+
 {OS has only 1 byte version for ExecuteProcess}
 {$define executeprocuni}
 
@@ -739,22 +741,57 @@
 end;
 
 
-
 {****************************************************************************
-                              Locale Functions
+                              Time Functions
 ****************************************************************************}
 
+{* declared in DOS unit *}
+function get_sys_time(tv : ptimeval): longint; external name '_fpc_amiga_get_sys_time';
+
+
+{$IFDEF HAS_GETTICKCOUNT64}
+function GetTickCount64: QWord;
+var
+  currenttime : ttimeval;
+begin
+  if get_sys_time(@currenttime) = 0 then
+    Result:=qword(currenttime.tv_secs) * 1000 + currenttime.tv_micro div 1000
+  else
+    Result:=0;
+end;
+{$ENDIF}
+
+
 Procedure GetLocalTime(var SystemTime: TSystemTime);
 var
- dayOfWeek: word;
- Sec100: Word;
+  cd : TClockData;
+  currenttime : ttimeval;
 begin
-  dos.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second, Sec100);
-  SystemTime.Millisecond := Sec100 * 10;
-  dos.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day, DayOfWeek);
+  {* this function is used in the Now() call, which is often used for *}
+  {* periodic timing and by default also GetTickCount64() wraps to it *}
+  if get_sys_time(@currenttime) = 0 then
+    begin
+      Amiga2Date(currenttime.tv_secs,@cd);
+      with SystemTime do
+      begin
+        Year:=cd.Year;
+        Month:=cd.Month;
+        Day:=cd.MDay;
+        Hour:=cd.Hour;
+        Minute:=cd.Min;
+        Second:=cd.Sec;
+        Millisecond:=currenttime.tv_micro div 1000;
+      end;
+    end
+  else
+    FillChar(SystemTime,sizeof(SystemTime),0);
 end;
 
 
+{****************************************************************************
+                              Locale Functions
+****************************************************************************}
+
 Procedure InitAnsi;
 Var
   i : longint;
