mk6502ins.pp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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', 'AM_IMPLICIT'),
  21. ('A', 'AM_ACCUMULATOR'),
  22. ('#', 'AM_IMMEDIATE'),
  23. ('zpg', 'AM_ZERO_PAGE'),
  24. ('zpg,X', 'AM_ZERO_PAGE_X'),
  25. ('zpg,Y', 'AM_ZERO_PAGE_Y'),
  26. ('rel', 'AM_RELATIVE'),
  27. ('abs', 'AM_ABSOLUTE'),
  28. ('abs,X', 'AM_ABSOLUTE_X'),
  29. ('abs,Y', 'AM_ABSOLUTE_Y'),
  30. ('(ind)', 'AM_INDIRECT'),
  31. ('(ind,X)', 'AM_INDEXED_INDIRECT'),
  32. ('(ind),Y', 'AM_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, S_AddrMode: string;
  141. FirstIns: Boolean=true;
  142. OpCount: Integer=0;
  143. S_Split: TStringArray;
  144. begin
  145. writeln('FPC 6502 Instruction Table Converter Version ',Version);
  146. AssignFile(InsDatFile,'../mos6502/mos6502ins.dat');
  147. Reset(InsDatFile);
  148. try
  149. OutputFiles:=TMOS6502InsDatOutputFiles.Create;
  150. while not EoF(InsDatFile) do
  151. begin
  152. Readln(InsDatFile,S);
  153. S:=Trim(S);
  154. if AnsiStartsStr(';',S) then
  155. continue
  156. else if AnsiStartsStr('[',S) then
  157. begin
  158. op:=Copy(S,2,Length(S)-2);
  159. if not FirstIns then
  160. begin
  161. Writeln(OutputFiles.OpFile,',');
  162. Writeln(OutputFiles.StdOpNames,',');
  163. end;
  164. FirstIns:=False;
  165. Write(OutputFiles.OpFile,'A_'+op);
  166. Write(OutputFiles.StdOpNames,''''+LowerCase(op)+'''');
  167. end
  168. else if S<>'' then
  169. begin
  170. Inc(OpCount);
  171. if OpCount<>1 then
  172. Writeln(OutputFiles.InsTabFile,',');
  173. S_Split:=S.Split(' ',TStringSplitOptions.ExcludeEmpty);
  174. S_AddrMode:=S_Split[0];
  175. Writeln(OutputFiles.InsTabFile,' (');
  176. Writeln(OutputFiles.InsTabFile,' opcode : A_',op,';');
  177. Writeln(OutputFiles.InsTabFile, ' adrmode : ',ParamTypes[FindParamType(S_AddrMode),1],';');
  178. Writeln(OutputFiles.InsTabFile, ' code : ',S_Split[1],';');
  179. Writeln(OutputFiles.InsTabFile, ' flags : 0');
  180. Write(OutputFiles.InsTabFile, ' )');
  181. end;
  182. end;
  183. Writeln(OutputFiles.OpFile,');');
  184. Writeln(OutputFiles.StdOpNames,');');
  185. Writeln(OutputFiles.NOpFile,OpCount,';');
  186. Writeln(OutputFiles.InsTabFile);
  187. Writeln(OutputFiles.InsTabFile,');');
  188. finally
  189. FreeAndNil(OutputFiles);
  190. CloseFile(InsDatFile);
  191. end;
  192. end.