From c793f4227167b5f2bdb8e27396ae58ff2bad2f70 Mon Sep 17 00:00:00 2001 From: svenbarth Date: Sun, 7 Jun 2020 12:24:59 +0000 Subject: [PATCH] + add intrinsics for Z80 port IN/OUT git-svn-id: trunk@45607 - --- .gitattributes | 3 + compiler/z80/ccpuinnr.inc | 17 ++++ compiler/z80/cpunode.pas | 1 + compiler/z80/nz80inl.pas | 170 ++++++++++++++++++++++++++++++++++++++ rtl/z80/cpuh.inc | 7 ++ rtl/z80/cpuinnr.inc | 17 ++++ 6 files changed, 215 insertions(+) create mode 100644 compiler/z80/ccpuinnr.inc create mode 100644 compiler/z80/nz80inl.pas create mode 100644 rtl/z80/cpuinnr.inc diff --git a/.gitattributes b/.gitattributes index a56bb6c526..a12a11ffef 100644 --- a/.gitattributes +++ b/.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 diff --git a/compiler/z80/ccpuinnr.inc b/compiler/z80/ccpuinnr.inc new file mode 100644 index 0000000000..82c07db683 --- /dev/null +++ b/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 + diff --git a/compiler/z80/cpunode.pas b/compiler/z80/cpunode.pas index 26de8c07ea..1a51db82cd 100644 --- a/compiler/z80/cpunode.pas +++ b/compiler/z80/cpunode.pas @@ -38,6 +38,7 @@ unit cpunode; ,nz80cal ,nz80mat ,nz80mem + ,nz80inl // ,nz80cnv // ,nz80util, { these are not really nodes } diff --git a/compiler/z80/nz80inl.pas b/compiler/z80/nz80inl.pas new file mode 100644 index 0000000000..8b78273aab --- /dev/null +++ b/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. diff --git a/rtl/z80/cpuh.inc b/rtl/z80/cpuh.inc index e3f3caf416..dfdb708eb3 100644 --- a/rtl/z80/cpuh.inc +++ b/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]; + diff --git a/rtl/z80/cpuinnr.inc b/rtl/z80/cpuinnr.inc new file mode 100644 index 0000000000..a60f295e3c --- /dev/null +++ b/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; +