mk6502ins.pp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. {
  2. Copyright (c) 2020, 2024 by Nikolay Nikolov
  3. Convert mos6502ins.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 mk6502ins;
  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 mos6502ins.dat; to regenerate, run ''make insdat'' in the compiler directory }';
  18. max_operands = 2;
  19. ParamTypes: array [0..12,0..1] of string = (
  20. ('void', 'OT_IMPLICIT'),
  21. ('A', 'OT_ACCUMULATOR'),
  22. ('#', 'OT_IMMEDIATE'),
  23. ('zpg', 'OT_ZERO_PAGE'),
  24. ('zpg,X', 'OT_ZERO_PAGE_X'),
  25. ('zpg,Y', 'OT_ZERO_PAGE_Y'),
  26. ('rel', 'OT_RELATIVE'),
  27. ('abs', 'OT_ABSOLUTE'),
  28. ('abs,X', 'OT_ABSOLUTE_X'),
  29. ('abs,Y', 'OT_ABSOLUTE_Y'),
  30. ('(ind)', 'OT_INDIRECT'),
  31. ('(ind,X)', 'OT_INDEXED_INDIRECT'),
  32. ('(ind),Y', 'OT_INDIRECT_INDEXED')
  33. );
  34. type
  35. { TMOS6502InsDatOutputFiles }
  36. TMOS6502InsDatOutputFiles = class
  37. public
  38. OpFile: TextFile;
  39. NOpFile: TextFile;
  40. StdOpNames: TextFile;
  41. InsTabFile: TextFile;
  42. constructor Create;
  43. destructor Destroy;override;
  44. end;
  45. { ***************************************************************************
  46. the routines LeftStr, AnsiStartsStr are copied and reformatted
  47. from StrUtils and thus covered by the copyright of strutils (see below) as compiler utilities cannot
  48. depend on packages
  49. This file is part of the Free Pascal run time library.
  50. Copyright (c) 1999-2005 by the Free Pascal development team
  51. See the file COPYING.FPC, included in this distribution,
  52. for details about the copyright.
  53. This program is distributed in the hope that it will be useful,
  54. but WITHOUT ANY WARRANTY; without even the implied warranty of
  55. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  56. *************************************************************************** }
  57. function LeftStr(const AText: AnsiString; const ACount: SizeInt): AnsiString;
  58. begin
  59. Result:=Copy(AText,1,ACount);
  60. end;
  61. function AnsiStartsStr(const ASubText, AText: string): Boolean;
  62. begin
  63. Result := (ASubText = '') or (LeftStr(AText, Length(ASubText)) = ASubText);
  64. end;
  65. { ***************************************************************************
  66. end of StrUtils code
  67. ***************************************************************************}
  68. function PasEncode(const S: string): string;
  69. var
  70. Ch: Char;
  71. InQuotes: Boolean;
  72. begin
  73. Result:='';
  74. InQuotes:=False;
  75. for Ch in S do
  76. if (Ch>=#32) and (Ch<=#126) then
  77. begin
  78. if not InQuotes then
  79. begin
  80. Result:=Result+'''';
  81. InQuotes:=True;
  82. end;
  83. if Ch='''' then
  84. Result:=Result+''''''
  85. else
  86. Result:=Result+Ch;
  87. end
  88. else
  89. begin
  90. if InQuotes then
  91. begin
  92. Result:=Result+'''';
  93. InQuotes:=False;
  94. end;
  95. Result:=Result+'#'+IntToStr(Ord(Ch));
  96. end;
  97. if InQuotes then
  98. Result:=Result+'''';
  99. if Result='' then
  100. Result:='''''';
  101. end;
  102. constructor TMOS6502InsDatOutputFiles.Create;
  103. begin
  104. AssignFile(OpFile,'mos6502op.inc');
  105. Rewrite(OpFile);
  106. Writeln(OpFile,HeaderStr);
  107. Writeln(OpFile,'(');
  108. AssignFile(NOpFile,'mos6502nop.inc');
  109. Rewrite(NOpFile);
  110. Writeln(NOpFile,HeaderStr);
  111. AssignFile(StdOpNames,'mos6502stdopnames.inc');
  112. Rewrite(StdOpNames);
  113. Writeln(StdOpNames,HeaderStr);
  114. Writeln(StdOpNames,'(');
  115. AssignFile(InsTabFile,'mos6502tab.inc');
  116. Rewrite(InsTabFile);
  117. Writeln(InsTabFile,HeaderStr);
  118. Writeln(InsTabFile,'(');
  119. end;
  120. destructor TMOS6502InsDatOutputFiles.Destroy;
  121. begin
  122. CloseFile(OpFile);
  123. CloseFile(NOpFile);
  124. CloseFile(StdOpNames);
  125. CloseFile(InsTabFile);
  126. inherited Destroy;
  127. end;
  128. function FindParamType(const ParamTypeStr: string): Integer;
  129. var
  130. I: Integer;
  131. begin
  132. for I:=Low(ParamTypes) to High(ParamTypes) do
  133. if ParamTypes[I,0]=ParamTypeStr then
  134. exit(I);
  135. raise Exception.Create('Invalid param type: '''+ParamTypeStr+'''');
  136. end;
  137. var
  138. InsDatFile: TextFile;
  139. OutputFiles: TMOS6502InsDatOutputFiles=nil;
  140. S, op, ParamsStr: string;
  141. FirstIns: Boolean=true;
  142. OpCount: Integer=0;
  143. S_Split, S_Params: TStringArray;
  144. ParamIdx: Integer;
  145. begin
  146. writeln('FPC 6502 Instruction Table Converter Version ',Version);
  147. AssignFile(InsDatFile,'../mos6502/mos6502ins.dat');
  148. Reset(InsDatFile);
  149. try
  150. OutputFiles:=TMOS6502InsDatOutputFiles.Create;
  151. while not EoF(InsDatFile) do
  152. begin
  153. Readln(InsDatFile,S);
  154. S:=Trim(S);
  155. if AnsiStartsStr(';',S) then
  156. continue
  157. else if AnsiStartsStr('[',S) then
  158. begin
  159. op:=Copy(S,2,Length(S)-2);
  160. if not FirstIns then
  161. begin
  162. Writeln(OutputFiles.OpFile,',');
  163. Writeln(OutputFiles.StdOpNames,',');
  164. end;
  165. FirstIns:=False;
  166. Write(OutputFiles.OpFile,'A_'+op);
  167. Write(OutputFiles.StdOpNames,''''+LowerCase(op)+'''');
  168. end
  169. else if S<>'' then
  170. begin
  171. Inc(OpCount);
  172. if OpCount<>1 then
  173. Writeln(OutputFiles.InsTabFile,',');
  174. S_Split:=S.Split(' ',TStringSplitOptions.ExcludeEmpty);
  175. S_Params:=S_Split[0].Split('!',TStringSplitOptions.ExcludeEmpty);
  176. if (Length(S_Params)=1) and (S_Params[0]='void') then
  177. SetLength(S_Params,0);
  178. Writeln(OutputFiles.InsTabFile,' (');
  179. Writeln(OutputFiles.InsTabFile,' opcode : A_',op,';');
  180. Writeln(OutputFiles.InsTabFile,' ops : ',Length(S_Params),';');
  181. Write(OutputFiles.InsTabFile, ' optypes : (');
  182. if Length(S_Params)>max_operands then
  183. raise Exception.Create('Too many operands');
  184. for ParamIdx:=0 to max_operands-1 do
  185. begin
  186. if ParamIdx<>0 then
  187. Write(OutputFiles.InsTabFile,',');
  188. if ParamIdx<=High(S_Params) then
  189. Write(OutputFiles.InsTabFile,ParamTypes[FindParamType(S_Params[ParamIdx]),1])
  190. else
  191. Write(OutputFiles.InsTabFile,'OT_NONE');
  192. end;
  193. Writeln(OutputFiles.InsTabFile, ');');
  194. Writeln(OutputFiles.InsTabFile, ' code : ',PasEncode(S_Split[1]),';');
  195. Writeln(OutputFiles.InsTabFile, ' flags : 0');
  196. Write(OutputFiles.InsTabFile, ' )');
  197. end;
  198. end;
  199. Writeln(OutputFiles.OpFile,');');
  200. Writeln(OutputFiles.StdOpNames,');');
  201. Writeln(OutputFiles.NOpFile,OpCount,';');
  202. Writeln(OutputFiles.InsTabFile);
  203. Writeln(OutputFiles.InsTabFile,');');
  204. finally
  205. FreeAndNil(OutputFiles);
  206. CloseFile(InsDatFile);
  207. end;
  208. end.