mkz80ins.pp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. {
  2. Copyright (c) 2020 by Nikolay Nikolov
  3. Convert z80ins.dat to a set of .inc files for usage with
  4. the Free pascal compiler
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. program mkz80ins;
  12. {$mode objfpc}{$H+}
  13. uses
  14. SysUtils;
  15. const
  16. Version = '1.0.0';
  17. HeaderStr = '{ don''t edit, this file is generated from z80ins.dat; to regenerate, run ''make insdat'' in the compiler directory }';
  18. max_operands = 2;
  19. ParamTypes: array [0..40,0..1] of string = (
  20. ('void', 'OT_NONE'),
  21. ('r', 'OT_REG8'),
  22. ('r''', 'OT_REG8'),
  23. ('b', 'OT_IMM3'),
  24. ('n', 'OT_IMM8'),
  25. ('p', 'OT_IMM_RST'),
  26. ('e', 'OT_RELJMP8'),
  27. ('nn', 'OT_IMM16'),
  28. ('0', 'OT_IMM_VAL0'),
  29. ('1', 'OT_IMM_VAL1'),
  30. ('2', 'OT_IMM_VAL2'),
  31. ('cc', 'OT_COND'),
  32. ('C', 'OT_COND_C'),
  33. ('NC', 'OT_COND_NC'),
  34. ('Z', 'OT_COND_Z'),
  35. ('NZ', 'OT_COND_NZ'),
  36. ('dd', 'OT_REG16_BC_DE_HL_SP'),
  37. ('qq', 'OT_REG16_BC_DE_HL_AF'),
  38. ('pp', 'OT_REG16_BC_DE_IX_SP'),
  39. ('rr', 'OT_REG16_BC_DE_IY_SP'),
  40. ('A', 'OT_REG8_A'),
  41. ('I', 'OT_REG8_I'),
  42. ('R', 'OT_REG8_R'),
  43. ('IX', 'OT_REG16_IX'),
  44. ('IY', 'OT_REG16_IY'),
  45. ('SP', 'OT_REG16_SP'),
  46. ('DE', 'OT_REG16_DE'),
  47. ('HL', 'OT_REG16_HL'),
  48. ('AF', 'OT_REG16_AF'),
  49. ('AF''', 'OT_REG16_AF_'),
  50. ('(C)', 'OT_REG8_C_PORT'),
  51. ('(n)', 'OT_IMM_PORT'),
  52. ('(nn)', 'OT_REF_ADDR16'),
  53. ('(BC)', 'OT_REF_BC'),
  54. ('(DE)', 'OT_REF_DE'),
  55. ('(HL)', 'OT_REF_HL'),
  56. ('(SP)', 'OT_REF_SP'),
  57. ('(IX)', 'OT_REF_IX'),
  58. ('(IY)', 'OT_REF_IY'),
  59. ('(IX+d)','OT_REF_IX_d'),
  60. ('(IY+d)','OT_REF_IY_d')
  61. );
  62. type
  63. { TZ80InsDatOutputFiles }
  64. TZ80InsDatOutputFiles = class
  65. public
  66. OpFile: TextFile;
  67. NOpFile: TextFile;
  68. StdOpNames: TextFile;
  69. InsTabFile: TextFile;
  70. constructor Create;
  71. destructor Destroy;override;
  72. end;
  73. { ***************************************************************************
  74. the routines LeftStr, AnsiStartsStr are copied and reformatted
  75. from StrUtils and thus covered by the copyright of strutils (see below) as compiler utilities cannot
  76. depend on packages
  77. This file is part of the Free Pascal run time library.
  78. Copyright (c) 1999-2005 by the Free Pascal development team
  79. See the file COPYING.FPC, included in this distribution,
  80. for details about the copyright.
  81. This program is distributed in the hope that it will be useful,
  82. but WITHOUT ANY WARRANTY; without even the implied warranty of
  83. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  84. *************************************************************************** }
  85. function LeftStr(const AText: AnsiString; const ACount: SizeInt): AnsiString;
  86. begin
  87. Result:=Copy(AText,1,ACount);
  88. end;
  89. function AnsiStartsStr(const ASubText, AText: string): Boolean;
  90. begin
  91. Result := (ASubText = '') or (LeftStr(AText, Length(ASubText)) = ASubText);
  92. end;
  93. { ***************************************************************************
  94. end of StrUtils code
  95. ***************************************************************************}
  96. function PasEncode(const S: string): string;
  97. var
  98. Ch: Char;
  99. InQuotes: Boolean;
  100. begin
  101. Result:='';
  102. InQuotes:=False;
  103. for Ch in S do
  104. if (Ch>=#32) and (Ch<=#126) then
  105. begin
  106. if not InQuotes then
  107. begin
  108. Result:=Result+'''';
  109. InQuotes:=True;
  110. end;
  111. if Ch='''' then
  112. Result:=Result+''''''
  113. else
  114. Result:=Result+Ch;
  115. end
  116. else
  117. begin
  118. if InQuotes then
  119. begin
  120. Result:=Result+'''';
  121. InQuotes:=False;
  122. end;
  123. Result:=Result+'#'+IntToStr(Ord(Ch));
  124. end;
  125. if InQuotes then
  126. Result:=Result+'''';
  127. if Result='' then
  128. Result:='''''';
  129. end;
  130. constructor TZ80InsDatOutputFiles.Create;
  131. begin
  132. AssignFile(OpFile,'z80op.inc');
  133. Rewrite(OpFile);
  134. Writeln(OpFile,HeaderStr);
  135. Writeln(OpFile,'(');
  136. AssignFile(NOpFile,'z80nop.inc');
  137. Rewrite(NOpFile);
  138. Writeln(NOpFile,HeaderStr);
  139. AssignFile(StdOpNames,'z80stdopnames.inc');
  140. Rewrite(StdOpNames);
  141. Writeln(StdOpNames,HeaderStr);
  142. Writeln(StdOpNames,'(');
  143. AssignFile(InsTabFile,'z80tab.inc');
  144. Rewrite(InsTabFile);
  145. Writeln(InsTabFile,HeaderStr);
  146. Writeln(InsTabFile,'(');
  147. end;
  148. destructor TZ80InsDatOutputFiles.Destroy;
  149. begin
  150. CloseFile(OpFile);
  151. CloseFile(NOpFile);
  152. CloseFile(StdOpNames);
  153. CloseFile(InsTabFile);
  154. inherited Destroy;
  155. end;
  156. function FindParamType(const ParamTypeStr: string): Integer;
  157. var
  158. I: Integer;
  159. begin
  160. for I:=Low(ParamTypes) to High(ParamTypes) do
  161. if ParamTypes[I,0]=ParamTypeStr then
  162. exit(I);
  163. raise Exception.Create('Invalid param type: '''+ParamTypeStr+'''');
  164. end;
  165. var
  166. InsDatFile: TextFile;
  167. OutputFiles: TZ80InsDatOutputFiles=nil;
  168. S, op, ParamsStr: string;
  169. FirstIns: Boolean=true;
  170. OpCount: Integer=0;
  171. S_Split, S_Params: TStringArray;
  172. ParamIdx: Integer;
  173. begin
  174. writeln('FPC Z80 Instruction Table Converter Version ',Version);
  175. AssignFile(InsDatFile,'../z80/z80ins.dat');
  176. Reset(InsDatFile);
  177. try
  178. OutputFiles:=TZ80InsDatOutputFiles.Create;
  179. while not EoF(InsDatFile) do
  180. begin
  181. Readln(InsDatFile,S);
  182. S:=Trim(S);
  183. if AnsiStartsStr(';',S) then
  184. continue
  185. else if AnsiStartsStr('[',S) then
  186. begin
  187. op:=Copy(S,2,Length(S)-2);
  188. if not FirstIns then
  189. begin
  190. Writeln(OutputFiles.OpFile,',');
  191. Writeln(OutputFiles.StdOpNames,',');
  192. end;
  193. FirstIns:=False;
  194. Write(OutputFiles.OpFile,'A_'+op);
  195. Write(OutputFiles.StdOpNames,''''+LowerCase(op)+'''');
  196. end
  197. else if S<>'' then
  198. begin
  199. Inc(OpCount);
  200. if OpCount<>1 then
  201. Writeln(OutputFiles.InsTabFile,',');
  202. S_Split:=S.Split(' ',TStringSplitOptions.ExcludeEmpty);
  203. S_Params:=S_Split[0].Split(',',TStringSplitOptions.ExcludeEmpty);
  204. if (Length(S_Params)=1) and (S_Params[0]='void') then
  205. SetLength(S_Params,0);
  206. Writeln(OutputFiles.InsTabFile,' (');
  207. Writeln(OutputFiles.InsTabFile,' opcode : A_',op,';');
  208. Writeln(OutputFiles.InsTabFile,' ops : ',Length(S_Params),';');
  209. Write(OutputFiles.InsTabFile, ' optypes : (');
  210. if Length(S_Params)>max_operands then
  211. raise Exception.Create('Too many operands');
  212. for ParamIdx:=0 to max_operands-1 do
  213. begin
  214. if ParamIdx<>0 then
  215. Write(OutputFiles.InsTabFile,',');
  216. if ParamIdx<=High(S_Params) then
  217. Write(OutputFiles.InsTabFile,ParamTypes[FindParamType(S_Params[ParamIdx]),1])
  218. else
  219. Write(OutputFiles.InsTabFile,'OT_NONE');
  220. end;
  221. Writeln(OutputFiles.InsTabFile, ');');
  222. Writeln(OutputFiles.InsTabFile, ' code : ',PasEncode(S_Split[1]),';');
  223. Writeln(OutputFiles.InsTabFile, ' flags : 0');
  224. Write(OutputFiles.InsTabFile, ' )');
  225. end;
  226. end;
  227. Writeln(OutputFiles.OpFile,');');
  228. Writeln(OutputFiles.StdOpNames,');');
  229. Writeln(OutputFiles.NOpFile,OpCount,';');
  230. Writeln(OutputFiles.InsTabFile);
  231. Writeln(OutputFiles.InsTabFile,');');
  232. finally
  233. FreeAndNil(OutputFiles);
  234. CloseFile(InsDatFile);
  235. end;
  236. end.