123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- {
- 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;
- 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;
- { ***************************************************************************
- the routines LeftStr, AnsiStartsStr are copied and reformatted
- from StrUtils and thus covered by the copyright of strutils (see below) as compiler utilities cannot
- depend on packages
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2005 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.
- *************************************************************************** }
- function LeftStr(const AText: AnsiString; const ACount: SizeInt): AnsiString;
- begin
- Result:=Copy(AText,1,ACount);
- end;
- function AnsiStartsStr(const ASubText, AText: string): Boolean;
- begin
- Result := (ASubText = '') or (LeftStr(AText, Length(ASubText)) = ASubText);
- end;
- { ***************************************************************************
- end of StrUtils code
- ***************************************************************************}
- 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.
|