mkz80ins.pp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. 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. function PasEncode(const S: string): string;
  74. var
  75. Ch: Char;
  76. InQuotes: Boolean;
  77. begin
  78. Result:='';
  79. InQuotes:=False;
  80. for Ch in S do
  81. if (Ch>=#32) and (Ch<=#126) then
  82. begin
  83. if not InQuotes then
  84. begin
  85. Result:=Result+'''';
  86. InQuotes:=True;
  87. end;
  88. if Ch='''' then
  89. Result:=Result+''''''
  90. else
  91. Result:=Result+Ch;
  92. end
  93. else
  94. begin
  95. if InQuotes then
  96. begin
  97. Result:=Result+'''';
  98. InQuotes:=False;
  99. end;
  100. Result:=Result+'#'+IntToStr(Ord(Ch));
  101. end;
  102. if InQuotes then
  103. Result:=Result+'''';
  104. if Result='' then
  105. Result:='''''';
  106. end;
  107. constructor TZ80InsDatOutputFiles.Create;
  108. begin
  109. AssignFile(OpFile,'z80op.inc');
  110. Rewrite(OpFile);
  111. Writeln(OpFile,HeaderStr);
  112. Writeln(OpFile,'(');
  113. AssignFile(NOpFile,'z80nop.inc');
  114. Rewrite(NOpFile);
  115. Writeln(NOpFile,HeaderStr);
  116. AssignFile(StdOpNames,'z80stdopnames.inc');
  117. Rewrite(StdOpNames);
  118. Writeln(StdOpNames,HeaderStr);
  119. Writeln(StdOpNames,'(');
  120. AssignFile(InsTabFile,'z80tab.inc');
  121. Rewrite(InsTabFile);
  122. Writeln(InsTabFile,HeaderStr);
  123. Writeln(InsTabFile,'(');
  124. end;
  125. destructor TZ80InsDatOutputFiles.Destroy;
  126. begin
  127. CloseFile(OpFile);
  128. CloseFile(NOpFile);
  129. CloseFile(StdOpNames);
  130. CloseFile(InsTabFile);
  131. inherited Destroy;
  132. end;
  133. function FindParamType(const ParamTypeStr: string): Integer;
  134. var
  135. I: Integer;
  136. begin
  137. for I:=Low(ParamTypes) to High(ParamTypes) do
  138. if ParamTypes[I,0]=ParamTypeStr then
  139. exit(I);
  140. raise Exception.Create('Invalid param type: '''+ParamTypeStr+'''');
  141. end;
  142. var
  143. InsDatFile: TextFile;
  144. OutputFiles: TZ80InsDatOutputFiles=nil;
  145. S, op, ParamsStr: string;
  146. FirstIns: Boolean=true;
  147. OpCount: Integer=0;
  148. S_Split, S_Params: TStringArray;
  149. ParamIdx: Integer;
  150. begin
  151. writeln('FPC Z80 Instruction Table Converter Version ',Version);
  152. AssignFile(InsDatFile,'../z80/z80ins.dat');
  153. Reset(InsDatFile);
  154. try
  155. OutputFiles:=TZ80InsDatOutputFiles.Create;
  156. while not EoF(InsDatFile) do
  157. begin
  158. Readln(InsDatFile,S);
  159. S:=Trim(S);
  160. if AnsiStartsStr(';',S) then
  161. continue
  162. else if AnsiStartsStr('[',S) then
  163. begin
  164. op:=Copy(S,2,Length(S)-2);
  165. if not FirstIns then
  166. begin
  167. Writeln(OutputFiles.OpFile,',');
  168. Writeln(OutputFiles.StdOpNames,',');
  169. end;
  170. FirstIns:=False;
  171. Write(OutputFiles.OpFile,'A_'+op);
  172. Write(OutputFiles.StdOpNames,''''+LowerCase(op)+'''');
  173. end
  174. else if S<>'' then
  175. begin
  176. Inc(OpCount);
  177. if OpCount<>1 then
  178. Writeln(OutputFiles.InsTabFile,',');
  179. S_Split:=S.Split(' ',TStringSplitOptions.ExcludeEmpty);
  180. S_Params:=S_Split[0].Split(',',TStringSplitOptions.ExcludeEmpty);
  181. if (Length(S_Params)=1) and (S_Params[0]='void') then
  182. SetLength(S_Params,0);
  183. Writeln(OutputFiles.InsTabFile,' (');
  184. Writeln(OutputFiles.InsTabFile,' opcode : A_',op,';');
  185. Writeln(OutputFiles.InsTabFile,' ops : ',Length(S_Params),';');
  186. Write(OutputFiles.InsTabFile, ' optypes : (');
  187. if Length(S_Params)>max_operands then
  188. raise Exception.Create('Too many operands');
  189. for ParamIdx:=0 to max_operands-1 do
  190. begin
  191. if ParamIdx<>0 then
  192. Write(OutputFiles.InsTabFile,',');
  193. if ParamIdx<=High(S_Params) then
  194. Write(OutputFiles.InsTabFile,ParamTypes[FindParamType(S_Params[ParamIdx]),1])
  195. else
  196. Write(OutputFiles.InsTabFile,'OT_NONE');
  197. end;
  198. Writeln(OutputFiles.InsTabFile, ');');
  199. Writeln(OutputFiles.InsTabFile, ' code : ',PasEncode(S_Split[1]),';');
  200. Writeln(OutputFiles.InsTabFile, ' flags : 0');
  201. Write(OutputFiles.InsTabFile, ' )');
  202. end;
  203. end;
  204. Writeln(OutputFiles.OpFile,');');
  205. Writeln(OutputFiles.StdOpNames,');');
  206. Writeln(OutputFiles.NOpFile,OpCount,';');
  207. Writeln(OutputFiles.InsTabFile);
  208. Writeln(OutputFiles.InsTabFile,');');
  209. finally
  210. FreeAndNil(OutputFiles);
  211. CloseFile(InsDatFile);
  212. end;
  213. end.