瀏覽代碼

+ add intrinsics for Z80 port IN/OUT

git-svn-id: trunk@45607 -
svenbarth 5 年之前
父節點
當前提交
c793f42271
共有 6 個文件被更改,包括 215 次插入0 次删除
  1. 3 0
      .gitattributes
  2. 17 0
      compiler/z80/ccpuinnr.inc
  3. 1 0
      compiler/z80/cpunode.pas
  4. 170 0
      compiler/z80/nz80inl.pas
  5. 7 0
      rtl/z80/cpuh.inc
  6. 17 0
      rtl/z80/cpuinnr.inc

+ 3 - 0
.gitattributes

@@ -1071,6 +1071,7 @@ compiler/z80/agz80vasm.pas svneol=native#text/plain
 compiler/z80/aoptcpu.pas svneol=native#text/plain
 compiler/z80/aoptcpub.pas svneol=native#text/plain
 compiler/z80/aoptcpud.pas svneol=native#text/plain
+compiler/z80/ccpuinnr.inc svneol=native#text/plain
 compiler/z80/cgcpu.pas svneol=native#text/plain
 compiler/z80/cpubase.pas svneol=native#text/plain
 compiler/z80/cpuinfo.pas svneol=native#text/plain
@@ -1081,6 +1082,7 @@ compiler/z80/cputarg.pas svneol=native#text/plain
 compiler/z80/hlcgcpu.pas svneol=native#text/plain
 compiler/z80/nz80add.pas svneol=native#text/plain
 compiler/z80/nz80cal.pas svneol=native#text/plain
+compiler/z80/nz80inl.pas svneol=native#text/pascal
 compiler/z80/nz80mat.pas svneol=native#text/plain
 compiler/z80/nz80mem.pas svneol=native#text/plain
 compiler/z80/raz80.pas svneol=native#text/plain
@@ -12208,6 +12210,7 @@ rtl/xtensa/strings.inc svneol=native#text/plain
 rtl/xtensa/stringss.inc svneol=native#text/plain
 rtl/xtensa/xtensa.inc svneol=native#text/plain
 rtl/z80/cpuh.inc svneol=native#text/plain
+rtl/z80/cpuinnr.inc svneol=native#text/plain
 rtl/z80/int64p.inc svneol=native#text/plain
 rtl/z80/makefile.cpu svneol=native#text/plain
 rtl/z80/math.inc svneol=native#text/plain

+ 17 - 0
compiler/z80/ccpuinnr.inc

@@ -0,0 +1,17 @@
+{
+
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2020 by the Free Pascal development team.
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+  in_z80_inport  = in_cpu_first,
+  in_z80_outport = in_cpu_first+1
+

+ 1 - 0
compiler/z80/cpunode.pas

@@ -38,6 +38,7 @@ unit cpunode;
        ,nz80cal
        ,nz80mat
        ,nz80mem
+       ,nz80inl
 //       ,nz80cnv
 //       ,nz80util,
        { these are not really nodes }

+ 170 - 0
compiler/z80/nz80inl.pas

@@ -0,0 +1,170 @@
+{
+    Copyright (c) 2020 by Sven Barth
+
+    Generates Z80 inline nodes
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit nz80inl;
+
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+      node,ninl,ncginl, aasmbase;
+
+    type
+      tz80inlinenode = class(tcginlinenode)
+        function pass_typecheck_cpu:tnode;override;
+        function first_cpu : tnode;override;
+        procedure pass_generate_code_cpu;override;
+      end;
+
+  implementation
+
+    uses
+      compinnr,
+      aasmdata,
+      aasmcpu,
+      symdef,
+      defutil,
+      hlcgobj,
+      pass_2,
+      ncal,
+      cgbase, cgobj, cgutils,
+      cpubase;
+
+
+    function tz80inlinenode.pass_typecheck_cpu : tnode;
+      begin
+        Result:=nil;
+        case inlinenumber of
+          in_z80_inport:
+            begin
+              CheckParameters(1);
+              resultdef:=u8inttype;
+            end;
+          in_z80_outport:
+            begin
+              CheckParameters(2);
+              resultdef:=voidtype;
+            end;
+          else
+            Result:=inherited pass_typecheck_cpu;
+        end;
+      end;
+
+
+    function tz80inlinenode.first_cpu : tnode;
+      begin
+        Result:=nil;
+        case inlinenumber of
+          in_z80_inport:
+            expectloc:=LOC_REGISTER;
+          in_z80_outport:
+            expectloc:=LOC_VOID;
+          else
+            Result:=inherited first_cpu;
+        end;
+      end;
+
+
+    procedure tz80inlinenode.pass_generate_code_cpu;
+
+      procedure inport;
+        var
+          portnumber : tnode;
+          dreg : tregister;
+          ref : treference;
+        begin
+          portnumber:=left;
+          secondpass(portnumber);
+          if (portnumber.location.loc=LOC_CONSTANT) and
+              (portnumber.location.value>=0) and
+              (portnumber.location.value<=$ff) then
+            begin
+              { data needs to be put into A }
+              dreg:=NR_A;
+              reference_reset_base(ref,NR_NO,portnumber.location.value,ctempposinvalid,1,[]);
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref(A_IN,dreg,ref));
+            end
+          else
+            begin
+              { data can be put anywhere, but port number must be in C }
+              hlcg.getcpuregister(current_asmdata.CurrAsmList,NR_C);
+              dreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
+              hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,portnumber.resultdef,u8inttype,portnumber.location,NR_C);
+              reference_reset_base(ref,NR_C,0,ctempposinvalid,1,[]);
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref(A_IN,dreg,ref));
+              hlcg.ungetcpuregister(current_asmdata.CurrAsmList,NR_C);
+            end;
+            location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+            location.register:=dreg;
+        end;
+
+      procedure outport;
+        var
+          portnumber,
+          portdata : tnode;
+          dreg : tregister;
+          ref : treference;
+        begin
+          portnumber:=tcallparanode(tcallparanode(left).right).left;
+          portdata:=tcallparanode(left).left;
+          secondpass(portdata);
+          secondpass(portnumber);
+          if (portnumber.location.loc=LOC_CONSTANT) and
+              (portnumber.location.value>=0) and
+              (portnumber.location.value<=$ff) then
+            begin
+              { data needs to reside in A }
+              dreg:=NR_A;
+              hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,portdata.resultdef,u8inttype,portdata.location,dreg);
+              hlcg.getcpuregister(current_asmdata.CurrAsmList,dreg);
+              reference_reset_base(ref,NR_NO,portnumber.location.value,ctempposinvalid,1,[]);
+              current_asmdata.currasmlist.concat(taicpu.op_ref_reg(A_OUT,ref,dreg));
+              hlcg.ungetcpuregister(current_asmdata.CurrAsmList,dreg);
+            end
+          else
+            begin
+              { data can reside anywhere, but port number must be in C }
+              hlcg.getcpuregister(current_asmdata.CurrAsmList,NR_C);
+              dreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
+              hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,portdata.resultdef,u8inttype,portdata.location,dreg);
+              hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,portnumber.resultdef,u8inttype,portnumber.location,NR_C);
+              reference_reset_base(ref,NR_C,0,ctempposinvalid,1,[]);
+              current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_OUT,ref,dreg));
+              hlcg.ungetcpuregister(current_asmdata.CurrAsmList,NR_C);
+            end;
+        end;
+
+      begin
+        case inlinenumber of
+          in_z80_inport:
+            inport;
+          in_z80_outport:
+            outport;
+          else
+            inherited pass_generate_code_cpu;
+        end;
+      end;
+
+
+begin
+  cinlinenode:=tz80inlinenode;
+end.

+ 7 - 0
rtl/z80/cpuh.inc

@@ -13,3 +13,10 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
  **********************************************************************}
+
+const
+  {$I cpuinnr.inc}
+
+function fpc_z80_inport(port : byte) : byte;[internproc:fpc_in_z80_inport];
+procedure fpc_z80_outport(port : byte;data : byte);[internproc:fpc_in_z80_outport];
+

+ 17 - 0
rtl/z80/cpuinnr.inc

@@ -0,0 +1,17 @@
+{
+
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2020 by the Free Pascal development team.
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+  fpc_in_z80_inport  = fpc_in_cpu_first;
+  fpc_in_z80_outport = fpc_in_cpu_first+1;
+