mkz80ins.pp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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,StrUtils;
  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. ParamTypes: array [0..40,0..1] of string = (
  19. ('void', 'OT_NONE'),
  20. ('r', 'OT_REG8'),
  21. ('r''', 'OT_REG8'),
  22. ('b', 'OT_IMM3'),
  23. ('n', 'OT_IMM8'),
  24. ('p', 'OT_IMM_RST'),
  25. ('e', 'OT_RELJMP8'),
  26. ('nn', 'OT_IMM16'),
  27. ('0', 'OT_IMM_VAL0'),
  28. ('1', 'OT_IMM_VAL1'),
  29. ('2', 'OT_IMM_VAL2'),
  30. ('cc', 'OT_COND'),
  31. ('C', 'OT_COND_C'),
  32. ('NC', 'OT_COND_NC'),
  33. ('Z', 'OT_COND_Z'),
  34. ('NZ', 'OT_COND_NZ'),
  35. ('dd', 'OT_REG16_BC_DE_HL_SP'),
  36. ('qq', 'OT_REG16_BC_DE_HL_AF'),
  37. ('pp', 'OT_REG16_BC_DE_IX_SP'),
  38. ('rr', 'OT_REG16_BC_DE_IY_SP'),
  39. ('A', 'OT_REG8_A'),
  40. ('I', 'OT_REG8_I'),
  41. ('R', 'OT_REG8_R'),
  42. ('IX', 'OT_REG16_IX'),
  43. ('IY', 'OT_REG16_IY'),
  44. ('SP', 'OT_REG16_SP'),
  45. ('DE', 'OT_REG16_DE'),
  46. ('HL', 'OT_REG16_HL'),
  47. ('AF', 'OT_REG16_AF'),
  48. ('AF''', 'OT_REG16_AF_'),
  49. ('(C)', 'OT_REG8_C_PORT'),
  50. ('(n)', 'OT_IMM_PORT'),
  51. ('(nn)', 'OT_REF_ADDR16'),
  52. ('(BC)', 'OT_REF_BC'),
  53. ('(DE)', 'OT_REF_DE'),
  54. ('(HL)', 'OT_REF_HL'),
  55. ('(SP)', 'OT_REF_SP'),
  56. ('(IX)', 'OT_REF_IX'),
  57. ('(IY)', 'OT_REF_IY'),
  58. ('(IX+d)','OT_REF_IX_d'),
  59. ('(IY+d)','OT_REF_IY_d')
  60. );
  61. type
  62. { TZ80InsDatOutputFiles }
  63. TZ80InsDatOutputFiles = class
  64. public
  65. OpFile: TextFile;
  66. NOpFile: TextFile;
  67. StdOpNames: TextFile;
  68. InsTabFile: TextFile;
  69. constructor Create;
  70. destructor Destroy;override;
  71. end;
  72. function PasEncode(const S: string): string;
  73. var
  74. Ch: Char;
  75. InQuotes: Boolean;
  76. begin
  77. Result:='';
  78. InQuotes:=False;
  79. for Ch in S do
  80. if (Ch>=#32) and (Ch<=#126) then
  81. begin
  82. if not InQuotes then
  83. begin
  84. Result:=Result+'''';
  85. InQuotes:=True;
  86. end;
  87. if Ch='''' then
  88. Result:=Result+''''''
  89. else
  90. Result:=Result+Ch;
  91. end
  92. else
  93. begin
  94. if InQuotes then
  95. begin
  96. Result:=Result+'''';
  97. InQuotes:=False;
  98. end;
  99. Result:=Result+'#'+IntToStr(Ord(Ch));
  100. end;
  101. if InQuotes then
  102. Result:=Result+'''';
  103. if Result='' then
  104. Result:='''''';
  105. end;
  106. constructor TZ80InsDatOutputFiles.Create;
  107. begin
  108. AssignFile(OpFile,'z80op.inc');
  109. Rewrite(OpFile);
  110. Writeln(OpFile,HeaderStr);
  111. Writeln(OpFile,'(');
  112. AssignFile(NOpFile,'z80nop.inc');
  113. Rewrite(NOpFile);
  114. Writeln(NOpFile,HeaderStr);
  115. AssignFile(StdOpNames,'z80stdopnames.inc');
  116. Rewrite(StdOpNames);
  117. Writeln(StdOpNames,HeaderStr);
  118. Writeln(StdOpNames,'(');
  119. AssignFile(InsTabFile,'z80tab.inc');
  120. Rewrite(InsTabFile);
  121. Writeln(InsTabFile,HeaderStr);
  122. Writeln(InsTabFile,'(');
  123. end;
  124. destructor TZ80InsDatOutputFiles.Destroy;
  125. begin
  126. CloseFile(OpFile);
  127. CloseFile(NOpFile);
  128. CloseFile(StdOpNames);
  129. CloseFile(InsTabFile);
  130. inherited Destroy;
  131. end;
  132. function FindParamType(const ParamTypeStr: string): Integer;
  133. var
  134. I: Integer;
  135. begin
  136. for I:=Low(ParamTypes) to High(ParamTypes) do
  137. if ParamTypes[I,0]=ParamTypeStr then
  138. exit(I);
  139. raise Exception.Create('Invalid param type: '''+ParamTypeStr+'''');
  140. end;
  141. var
  142. InsDatFile: TextFile;
  143. OutputFiles: TZ80InsDatOutputFiles=nil;
  144. S, op, ParamsStr: string;
  145. FirstIns: Boolean=true;
  146. OpCount: Integer=0;
  147. S_Split, S_Params: TStringArray;
  148. ParamIdx: Integer;
  149. begin
  150. writeln('FPC Z80 Instruction Table Converter Version ',Version);
  151. AssignFile(InsDatFile,'../z80/z80ins.dat');
  152. Reset(InsDatFile);
  153. try
  154. OutputFiles:=TZ80InsDatOutputFiles.Create;
  155. while not EoF(InsDatFile) do
  156. begin
  157. Readln(InsDatFile,S);
  158. S:=Trim(S);
  159. if AnsiStartsStr(';',S) then
  160. continue
  161. else if AnsiStartsStr('[',S) then
  162. begin
  163. op:=Copy(S,2,Length(S)-2);
  164. if not FirstIns then
  165. begin
  166. Writeln(OutputFiles.OpFile,',');
  167. Writeln(OutputFiles.StdOpNames,',');
  168. end;
  169. FirstIns:=False;
  170. Write(OutputFiles.OpFile,'A_'+op);
  171. Write(OutputFiles.StdOpNames,''''+LowerCase(op)+'''');
  172. end
  173. else if S<>'' then
  174. begin
  175. Inc(OpCount);
  176. if OpCount<>1 then
  177. Writeln(OutputFiles.InsTabFile,',');
  178. S_Split:=S.Split(' ',TStringSplitOptions.ExcludeEmpty);
  179. S_Params:=S_Split[0].Split(',',TStringSplitOptions.ExcludeEmpty);
  180. if (Length(S_Params)=1) and (S_Params[0]='void') then
  181. SetLength(S_Params,0);
  182. Writeln(OutputFiles.InsTabFile,' (');
  183. Writeln(OutputFiles.InsTabFile,' opcode : A_',op,';');
  184. Writeln(OutputFiles.InsTabFile,' ops : ',Length(S_Params),';');
  185. Write(OutputFiles.InsTabFile, ' optypes : (');
  186. for ParamIdx:=0 to 3 do
  187. begin
  188. if ParamIdx<>0 then
  189. Write(OutputFiles.InsTabFile,',');
  190. if ParamIdx<=High(S_Params) then
  191. Write(OutputFiles.InsTabFile,ParamTypes[FindParamType(S_Params[ParamIdx]),1])
  192. else
  193. Write(OutputFiles.InsTabFile,'OT_NONE');
  194. end;
  195. Writeln(OutputFiles.InsTabFile, ');');
  196. Writeln(OutputFiles.InsTabFile, ' code : ',PasEncode(S_Split[1]),';');
  197. Writeln(OutputFiles.InsTabFile, ' flags : 0');
  198. Write(OutputFiles.InsTabFile, ' )');
  199. end;
  200. end;
  201. Writeln(OutputFiles.OpFile,');');
  202. Writeln(OutputFiles.StdOpNames,');');
  203. Writeln(OutputFiles.NOpFile,OpCount,';');
  204. Writeln(OutputFiles.InsTabFile);
  205. Writeln(OutputFiles.InsTabFile,');');
  206. finally
  207. FreeAndNil(OutputFiles);
  208. CloseFile(InsDatFile);
  209. end;
  210. end.