summaryrefslogtreecommitdiff
path: root/compiler/utils/mkz80ins.pp
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils/mkz80ins.pp')
-rw-r--r--compiler/utils/mkz80ins.pp232
1 files changed, 232 insertions, 0 deletions
diff --git a/compiler/utils/mkz80ins.pp b/compiler/utils/mkz80ins.pp
new file mode 100644
index 0000000000..3c12563fa1
--- /dev/null
+++ b/compiler/utils/mkz80ins.pp
@@ -0,0 +1,232 @@
+{
+ Copyright (c) 2020 by Nikolay Nikolov
+
+ Convert z80ins.dat to a set of .inc files for usage with
+ the Free pascal compiler
+
+ 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.
+
+ **********************************************************************}
+
+program mkz80ins;
+
+{$mode objfpc}{$H+}
+
+uses
+ SysUtils,StrUtils;
+
+const
+ Version = '1.0.0';
+ HeaderStr = '{ don''t edit, this file is generated from z80ins.dat; to regenerate, run ''make insdat'' in the compiler directory }';
+ max_operands = 2;
+
+ ParamTypes: array [0..40,0..1] of string = (
+ ('void', 'OT_NONE'),
+ ('r', 'OT_REG8'),
+ ('r''', 'OT_REG8'),
+ ('b', 'OT_IMM3'),
+ ('n', 'OT_IMM8'),
+ ('p', 'OT_IMM_RST'),
+ ('e', 'OT_RELJMP8'),
+ ('nn', 'OT_IMM16'),
+ ('0', 'OT_IMM_VAL0'),
+ ('1', 'OT_IMM_VAL1'),
+ ('2', 'OT_IMM_VAL2'),
+ ('cc', 'OT_COND'),
+ ('C', 'OT_COND_C'),
+ ('NC', 'OT_COND_NC'),
+ ('Z', 'OT_COND_Z'),
+ ('NZ', 'OT_COND_NZ'),
+ ('dd', 'OT_REG16_BC_DE_HL_SP'),
+ ('qq', 'OT_REG16_BC_DE_HL_AF'),
+ ('pp', 'OT_REG16_BC_DE_IX_SP'),
+ ('rr', 'OT_REG16_BC_DE_IY_SP'),
+ ('A', 'OT_REG8_A'),
+ ('I', 'OT_REG8_I'),
+ ('R', 'OT_REG8_R'),
+ ('IX', 'OT_REG16_IX'),
+ ('IY', 'OT_REG16_IY'),
+ ('SP', 'OT_REG16_SP'),
+ ('DE', 'OT_REG16_DE'),
+ ('HL', 'OT_REG16_HL'),
+ ('AF', 'OT_REG16_AF'),
+ ('AF''', 'OT_REG16_AF_'),
+ ('(C)', 'OT_REG8_C_PORT'),
+ ('(n)', 'OT_IMM_PORT'),
+ ('(nn)', 'OT_REF_ADDR16'),
+ ('(BC)', 'OT_REF_BC'),
+ ('(DE)', 'OT_REF_DE'),
+ ('(HL)', 'OT_REF_HL'),
+ ('(SP)', 'OT_REF_SP'),
+ ('(IX)', 'OT_REF_IX'),
+ ('(IY)', 'OT_REF_IY'),
+ ('(IX+d)','OT_REF_IX_d'),
+ ('(IY+d)','OT_REF_IY_d')
+ );
+
+type
+
+ { TZ80InsDatOutputFiles }
+
+ TZ80InsDatOutputFiles = class
+ public
+ OpFile: TextFile;
+ NOpFile: TextFile;
+ StdOpNames: TextFile;
+ InsTabFile: TextFile;
+
+ constructor Create;
+ destructor Destroy;override;
+ end;
+
+function PasEncode(const S: string): string;
+ var
+ Ch: Char;
+ InQuotes: Boolean;
+ begin
+ Result:='';
+ InQuotes:=False;
+ for Ch in S do
+ if (Ch>=#32) and (Ch<=#126) then
+ begin
+ if not InQuotes then
+ begin
+ Result:=Result+'''';
+ InQuotes:=True;
+ end;
+ if Ch='''' then
+ Result:=Result+''''''
+ else
+ Result:=Result+Ch;
+ end
+ else
+ begin
+ if InQuotes then
+ begin
+ Result:=Result+'''';
+ InQuotes:=False;
+ end;
+ Result:=Result+'#'+IntToStr(Ord(Ch));
+ end;
+ if InQuotes then
+ Result:=Result+'''';
+ if Result='' then
+ Result:='''''';
+ end;
+
+constructor TZ80InsDatOutputFiles.Create;
+ begin
+ AssignFile(OpFile,'z80op.inc');
+ Rewrite(OpFile);
+ Writeln(OpFile,HeaderStr);
+ Writeln(OpFile,'(');
+ AssignFile(NOpFile,'z80nop.inc');
+ Rewrite(NOpFile);
+ Writeln(NOpFile,HeaderStr);
+ AssignFile(StdOpNames,'z80stdopnames.inc');
+ Rewrite(StdOpNames);
+ Writeln(StdOpNames,HeaderStr);
+ Writeln(StdOpNames,'(');
+ AssignFile(InsTabFile,'z80tab.inc');
+ Rewrite(InsTabFile);
+ Writeln(InsTabFile,HeaderStr);
+ Writeln(InsTabFile,'(');
+ end;
+
+destructor TZ80InsDatOutputFiles.Destroy;
+ begin
+ CloseFile(OpFile);
+ CloseFile(NOpFile);
+ CloseFile(StdOpNames);
+ CloseFile(InsTabFile);
+ inherited Destroy;
+ end;
+
+function FindParamType(const ParamTypeStr: string): Integer;
+var
+ I: Integer;
+begin
+ for I:=Low(ParamTypes) to High(ParamTypes) do
+ if ParamTypes[I,0]=ParamTypeStr then
+ exit(I);
+ raise Exception.Create('Invalid param type: '''+ParamTypeStr+'''');
+end;
+
+var
+ InsDatFile: TextFile;
+ OutputFiles: TZ80InsDatOutputFiles=nil;
+ S, op, ParamsStr: string;
+ FirstIns: Boolean=true;
+ OpCount: Integer=0;
+ S_Split, S_Params: TStringArray;
+ ParamIdx: Integer;
+begin
+ writeln('FPC Z80 Instruction Table Converter Version ',Version);
+ AssignFile(InsDatFile,'../z80/z80ins.dat');
+ Reset(InsDatFile);
+ try
+ OutputFiles:=TZ80InsDatOutputFiles.Create;
+ while not EoF(InsDatFile) do
+ begin
+ Readln(InsDatFile,S);
+ S:=Trim(S);
+ if AnsiStartsStr(';',S) then
+ continue
+ else if AnsiStartsStr('[',S) then
+ begin
+ op:=Copy(S,2,Length(S)-2);
+ if not FirstIns then
+ begin
+ Writeln(OutputFiles.OpFile,',');
+ Writeln(OutputFiles.StdOpNames,',');
+ end;
+ FirstIns:=False;
+ Write(OutputFiles.OpFile,'A_'+op);
+ Write(OutputFiles.StdOpNames,''''+LowerCase(op)+'''');
+ end
+ else if S<>'' then
+ begin
+ Inc(OpCount);
+ if OpCount<>1 then
+ Writeln(OutputFiles.InsTabFile,',');
+ S_Split:=S.Split(' ',TStringSplitOptions.ExcludeEmpty);
+ S_Params:=S_Split[0].Split(',',TStringSplitOptions.ExcludeEmpty);
+ if (Length(S_Params)=1) and (S_Params[0]='void') then
+ SetLength(S_Params,0);
+ Writeln(OutputFiles.InsTabFile,' (');
+ Writeln(OutputFiles.InsTabFile,' opcode : A_',op,';');
+ Writeln(OutputFiles.InsTabFile,' ops : ',Length(S_Params),';');
+ Write(OutputFiles.InsTabFile, ' optypes : (');
+ if Length(S_Params)>max_operands then
+ raise Exception.Create('Too many operands');
+ for ParamIdx:=0 to max_operands-1 do
+ begin
+ if ParamIdx<>0 then
+ Write(OutputFiles.InsTabFile,',');
+ if ParamIdx<=High(S_Params) then
+ Write(OutputFiles.InsTabFile,ParamTypes[FindParamType(S_Params[ParamIdx]),1])
+ else
+ Write(OutputFiles.InsTabFile,'OT_NONE');
+ end;
+ Writeln(OutputFiles.InsTabFile, ');');
+ Writeln(OutputFiles.InsTabFile, ' code : ',PasEncode(S_Split[1]),';');
+ Writeln(OutputFiles.InsTabFile, ' flags : 0');
+ Write(OutputFiles.InsTabFile, ' )');
+ end;
+ end;
+ Writeln(OutputFiles.OpFile,');');
+ Writeln(OutputFiles.StdOpNames,');');
+ Writeln(OutputFiles.NOpFile,OpCount,';');
+ Writeln(OutputFiles.InsTabFile);
+ Writeln(OutputFiles.InsTabFile,');');
+ finally
+ FreeAndNil(OutputFiles);
+ CloseFile(InsDatFile);
+ end;
+end.
+