From 3deeff689a60db13e751f28fb380a71f8bef07f5 Mon Sep 17 00:00:00 2001 From: nickysn Date: Sun, 19 Apr 2020 01:09:03 +0000 Subject: [PATCH] + added a ZX Spectrum target to the compiler git-svn-id: branches/z80@44815 - --- .gitattributes | 2 + compiler/systems.inc | 6 +- compiler/systems/i_zxspectrum.pas | 107 ++++++++++ compiler/systems/t_zxspectrum.pas | 312 ++++++++++++++++++++++++++++++ compiler/z80/cputarg.pas | 3 + 5 files changed, 428 insertions(+), 2 deletions(-) create mode 100644 compiler/systems/i_zxspectrum.pas create mode 100644 compiler/systems/t_zxspectrum.pas diff --git a/.gitattributes b/.gitattributes index 2088c25ff2..3c89885fe5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -857,6 +857,7 @@ compiler/systems/i_wdosx.pas svneol=native#text/plain compiler/systems/i_wii.pas svneol=native#text/plain compiler/systems/i_win.pas svneol=native#text/plain compiler/systems/i_win16.pas svneol=native#text/plain +compiler/systems/i_zxspectrum.pas svneol=native#text/plain compiler/systems/mac_crea.txt svneol=native#text/plain compiler/systems/t_aix.pas svneol=native#text/plain compiler/systems/t_amiga.pas svneol=native#text/plain @@ -890,6 +891,7 @@ compiler/systems/t_wdosx.pas svneol=native#text/plain compiler/systems/t_wii.pas svneol=native#text/plain compiler/systems/t_win.pas svneol=native#text/plain compiler/systems/t_win16.pas svneol=native#text/plain +compiler/systems/t_zxspectrum.pas svneol=native#text/plain compiler/tgobj.pas svneol=native#text/plain compiler/tokens.pas svneol=native#text/plain compiler/utils/Makefile svneol=native#text/plain diff --git a/compiler/systems.inc b/compiler/systems.inc index 3d334397af..48da90d0cc 100644 --- a/compiler/systems.inc +++ b/compiler/systems.inc @@ -195,7 +195,8 @@ system_xtensa_embedded, { 103 } system_xtensa_freertos, { 104 } system_xtensa_linux, { 105 } - system_z80_embedded { 106 } + system_z80_embedded, { 106 } + system_z80_zxspectrum { 107 } ); type @@ -292,7 +293,8 @@ ld_int_windows, ld_int_msdos, ld_int_win16, - ld_freertos + ld_freertos, + ld_zxspectrum ); tar = (ar_none diff --git a/compiler/systems/i_zxspectrum.pas b/compiler/systems/i_zxspectrum.pas new file mode 100644 index 0000000000..69df58c7f7 --- /dev/null +++ b/compiler/systems/i_zxspectrum.pas @@ -0,0 +1,107 @@ +{ + This unit implements support information structures for the FPC ZX Spectrum target + + Copyright (c) 1998-2006 by Peter Vreman + + 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 i_zxspectrum; + +{$i fpcdefs.inc} + + interface + + uses + systems; + + const + system_z80_zxspectrum_info : tsysteminfo = + ( + system : system_z80_zxspectrum; + name : 'ZX Spectrum'; + shortname : 'zxspectrum'; + flags : [tf_needs_symbol_size,tf_files_case_sensitive, + tf_smartlink_sections]; + cpu : cpu_sys_z80; + unit_env : ''; + extradefines : ''; + exeext : ''; + defext : '.def'; + scriptext : '.sh'; + smartext : '.sl'; + unitext : '.ppu'; + unitlibext : '.ppl'; + asmext : '.s'; + objext : '.o'; + resext : '.res'; + resobjext : '.or'; + sharedlibext : '.so'; + staticlibext : '.a'; + staticlibprefix : 'libp'; + sharedlibprefix : 'lib'; + sharedClibext : '.so'; + staticClibext : '.a'; + staticClibprefix : 'lib'; + sharedClibprefix : 'lib'; + importlibprefix : 'libimp'; + importlibext : '.a'; + Cprefix : ''; + newline : #10; + dirsep : '/'; + assem : as_sdcc_sdasz80; + assemextern : as_sdcc_sdasz80; + link : ld_none; + linkextern : ld_zxspectrum; + ar : ar_gnu_ar; + res : res_none; + dbg : dbg_dwarf2; + script : script_unix; + endian : endian_little; + alignment : + ( + procalign : 1; + loopalign : 1; + jumpalign : 0; + jumpalignskipmax : 0; + coalescealign : 0; + coalescealignskipmax : 0; + constalignmin : 0; + constalignmax : 1; + varalignmin : 0; + varalignmax : 1; + localalignmin : 0; + localalignmax : 1; + recordalignmin : 0; + recordalignmax : 1; + maxCrecordalign : 1 + ); + first_parm_offset : 4; + stacksize : 1024; + stackalign : 1; + abi : abi_default; + llvmdatalayout : 'todo'; + ); + + implementation + +initialization +{$ifdef CPUZ80} + {$ifdef zxspectrum} + set_source_info(system_z80_zxspectrum_info); + {$endif zxspectrum} +{$endif CPUZ80} +end. + diff --git a/compiler/systems/t_zxspectrum.pas b/compiler/systems/t_zxspectrum.pas new file mode 100644 index 0000000000..034c4a5dc1 --- /dev/null +++ b/compiler/systems/t_zxspectrum.pas @@ -0,0 +1,312 @@ +{ + Copyright (c) 2005-2020 by Free Pascal Compiler team + + This unit implements support import, export, link routines + for the ZX Spectrum Target + + 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 t_zxspectrum; + +{$i fpcdefs.inc} + +interface + + +implementation + + uses + SysUtils, + cutils,cfileutl,cclasses, + globtype,globals,systems,verbose,comphook,cscript,fmodule,i_zxspectrum,link, + cpuinfo; + + type + + { TLinkerZXSpectrum_SdccSdld - the sdld linker from the SDCC project ( http://sdcc.sourceforge.net/ ) } + + TLinkerZXSpectrum_SdccSdld=class(texternallinker) + private + Function WriteResponseFile: Boolean; + public +{ constructor Create; override;} + procedure SetDefaultInfo; override; + function MakeExecutable:boolean; override; +{ function postprocessexecutable(const fn : string;isdll:boolean):boolean;} + end; + + +{***************************************************************************** + TLinkerZXSpectrum_SdccSdld +*****************************************************************************} + +function TLinkerZXSpectrum_SdccSdld.WriteResponseFile: Boolean; + Var + linkres : TLinkRes; + i : longint; + HPath : TCmdStrListItem; + s,s1,s2 : TCmdStr; + prtobj, + cprtobj : string[80]; + linklibc : boolean; + found1, + found2 : boolean; + {$if defined(ARM)} + LinkStr : string; + {$endif} + begin + WriteResponseFile:=False; + linklibc:=(SharedLibFiles.Find('c')<>nil); + prtobj:='prt0'; + cprtobj:='cprt0'; + if linklibc then + prtobj:=cprtobj; + + { Open link.res file } + LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true); + + { Write path to search libraries } +(* HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First); + while assigned(HPath) do + begin + s:=HPath.Str; + if (cs_link_on_target in current_settings.globalswitches) then + s:=ScriptFixFileName(s); + LinkRes.Add('-L'+s); + HPath:=TCmdStrListItem(HPath.Next); + end; + HPath:=TCmdStrListItem(LibrarySearchPath.First); + while assigned(HPath) do + begin + s:=HPath.Str; + if s<>'' then + LinkRes.Add('SEARCH_DIR("'+s+'")'); + HPath:=TCmdStrListItem(HPath.Next); + end; + + LinkRes.Add('INPUT ('); + { add objectfiles, start with prt0 always }*) + //s:=FindObjectFile('prt0','',false); + if prtobj<>'' then + begin + s:=FindObjectFile(prtobj,'',false); + LinkRes.AddFileName(s); + end; + + { try to add crti and crtbegin if linking to C } + if linklibc then + begin + if librarysearchpath.FindFile('crtbegin.o',false,s) then + LinkRes.AddFileName(s); + if librarysearchpath.FindFile('crti.o',false,s) then + LinkRes.AddFileName(s); + end; + + while not ObjectFiles.Empty do + begin + s:=ObjectFiles.GetFirst; + if s<>'' then + begin + { vlink doesn't use SEARCH_DIR for object files } + if not(cs_link_on_target in current_settings.globalswitches) then + s:=FindObjectFile(s,'',false); + LinkRes.AddFileName((maybequoted(s))); + end; + end; + + { Write staticlibraries } + if not StaticLibFiles.Empty then + begin + { vlink doesn't need, and doesn't support GROUP } +{ if (cs_link_on_target in current_settings.globalswitches) then + begin + LinkRes.Add(')'); + LinkRes.Add('GROUP('); + end;} + while not StaticLibFiles.Empty do + begin + S:=StaticLibFiles.GetFirst; + LinkRes.AddFileName((maybequoted(s))); + end; + end; + +(* if (cs_link_on_target in current_settings.globalswitches) then + begin + LinkRes.Add(')'); + + { Write sharedlibraries like -l, also add the needed dynamic linker + here to be sure that it gets linked this is needed for glibc2 systems (PFV) } + linklibc:=false; + while not SharedLibFiles.Empty do + begin + S:=SharedLibFiles.GetFirst; + if s<>'c' then + begin + i:=Pos(target_info.sharedlibext,S); + if i>0 then + Delete(S,i,255); + LinkRes.Add('-l'+s); + end + else + begin + LinkRes.Add('-l'+s); + linklibc:=true; + end; + end; + { be sure that libc&libgcc is the last lib } + if linklibc then + begin + LinkRes.Add('-lc'); + LinkRes.Add('-lgcc'); + end; + end + else + begin + while not SharedLibFiles.Empty do + begin + S:=SharedLibFiles.GetFirst; + LinkRes.Add('lib'+s+target_info.staticlibext); + end; + LinkRes.Add(')'); + end;*) + + { objects which must be at the end } + (*if linklibc then + begin + found1:=librarysearchpath.FindFile('crtend.o',false,s1); + found2:=librarysearchpath.FindFile('crtn.o',false,s2); + if found1 or found2 then + begin + LinkRes.Add('INPUT('); + if found1 then + LinkRes.AddFileName(s1); + if found2 then + LinkRes.AddFileName(s2); + LinkRes.Add(')'); + end; + end;*) + + { Write and Close response } + linkres.writetodisk; + linkres.free; + + WriteResponseFile:=True; + end; + +procedure TLinkerZXSpectrum_SdccSdld.SetDefaultInfo; + const +{$if defined(Z80)} + ExeName='sdcc-sdldz80'; +{$else} + ExeName='sdcc-sdld'; +{$endif} + begin + with Info do + begin + ExeCmd[1]:=ExeName+' -n $OPT -i $MAP $EXE -f $RES' + //-g '+platform_select+' $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP -L. -o $EXE -T $RES'; + end; + end; + +function TLinkerZXSpectrum_SdccSdld.MakeExecutable: boolean; + var + binstr, + cmdstr, + mapstr: TCmdStr; + success : boolean; + StaticStr, + GCSectionsStr, + DynLinkStr, + StripStr, + FixedExeFileName: string; + begin + { for future use } + StaticStr:=''; + StripStr:=''; + mapstr:=''; + DynLinkStr:=''; + FixedExeFileName:=maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename,'.ihx'))); + +(* GCSectionsStr:='--gc-sections'; + //if not(cs_link_extern in current_settings.globalswitches) then + if not(cs_link_nolink in current_settings.globalswitches) then + Message1(exec_i_linking,current_module.exefilename);*) + + if (cs_link_map in current_settings.globalswitches) then + mapstr:='-mw'; + + { Write used files and libraries } + WriteResponseFile(); + + { Call linker } + SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr); + Replace(cmdstr,'$OPT',Info.ExtraOptions); + if not(cs_link_on_target in current_settings.globalswitches) then + begin + Replace(cmdstr,'$EXE',FixedExeFileName); + Replace(cmdstr,'$RES',(maybequoted(ScriptFixFileName(outputexedir+Info.ResName)))); + Replace(cmdstr,'$STATIC',StaticStr); + Replace(cmdstr,'$STRIP',StripStr); + Replace(cmdstr,'$MAP',mapstr); + Replace(cmdstr,'$GCSECTIONS',GCSectionsStr); + Replace(cmdstr,'$DYNLINK',DynLinkStr); + end + else + begin + Replace(cmdstr,'$EXE',FixedExeFileName); + Replace(cmdstr,'$RES',maybequoted(ScriptFixFileName(outputexedir+Info.ResName))); + Replace(cmdstr,'$STATIC',StaticStr); + Replace(cmdstr,'$STRIP',StripStr); + Replace(cmdstr,'$MAP',mapstr); + Replace(cmdstr,'$GCSECTIONS',GCSectionsStr); + Replace(cmdstr,'$DYNLINK',DynLinkStr); + end; + success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false); + + { Remove ReponseFile } + if success and not(cs_link_nolink in current_settings.globalswitches) then + DeleteFile(outputexedir+Info.ResName); + +(* { Post process } + if success and not(cs_link_nolink in current_settings.globalswitches) then + success:=PostProcessExecutable(FixedExeFileName,false); + + if success and (target_info.system in [system_arm_embedded,system_avr_embedded,system_mipsel_embedded,system_xtensa_embedded]) then + begin + success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O ihex '+ + FixedExeFileName+' '+ + maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename,'.hex'))),true,false); + if success then + success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+ + FixedExeFileName+' '+ + maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename,'.bin'))),true,false); + end;*) + + MakeExecutable:=success; { otherwise a recursive call to link method } + end; + + +{***************************************************************************** + Initialize +*****************************************************************************} + +initialization +{$ifdef z80} + RegisterLinker(ld_zxspectrum,TLinkerZXSpectrum_SdccSdld); + RegisterTarget(system_z80_zxspectrum_info); +{$endif z80} +end. diff --git a/compiler/z80/cputarg.pas b/compiler/z80/cputarg.pas index 10fe3ccbb3..71b756a90f 100644 --- a/compiler/z80/cputarg.pas +++ b/compiler/z80/cputarg.pas @@ -38,6 +38,9 @@ implementation {$ifndef NOTARGETEMBEDDED} ,t_embed {$endif} + {$ifndef NOTARGETZXSPECTRUM} + ,t_zxspectrum + {$endif} {************************************** Assemblers