z80compiler.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. // z80compiler.cpp : Defines the entry point for the console application.
  2. //
  3. #include <stdarg.h> // For va_start, etc.
  4. #include <regex>
  5. #include <string>
  6. #include <fstream>
  7. #include <functional>
  8. using namespace std;
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #endif
  12. #define BITFLAG(n) (1 << n)
  13. #define F BITFLAG(0)
  14. #define A BITFLAG(1)
  15. #define AF (A | F)
  16. #define C BITFLAG(2)
  17. #define B BITFLAG(3)
  18. #define BC (B | C)
  19. #define E BITFLAG(4)
  20. #define D BITFLAG(5)
  21. #define DE (D | E)
  22. #define L BITFLAG(6)
  23. #define H BITFLAG(7)
  24. #define HL (H | L)
  25. #define IY BITFLAG(8)
  26. #define IX BITFLAG(9)
  27. #define R BITFLAG(10)
  28. #define SP BITFLAG(11)
  29. #define CARRY BITFLAG(12)
  30. #define ZERO BITFLAG(13)
  31. #define SIGN BITFLAG(14)
  32. #define HFLAG BITFLAG(15)
  33. #define OVERFLOWFLAG BITFLAG(16)
  34. #define NFLAG BITFLAG(17)
  35. #define FLAGS (CARRY|ZERO|SIGN|HFLAG|OVERFLOWFLAG|NFLAG)
  36. class C6502Translator
  37. {
  38. public:
  39. C6502Translator( const string& oZ80Code )
  40. : m_oZ80Code( oZ80Code )
  41. {
  42. Replace(m_oZ80Code, "\r", "");
  43. };
  44. ~C6502Translator() {};
  45. string Translate();
  46. private:
  47. void Replace(string& str, const string& from, const string& to);
  48. bool GetNextLine(string& oLine);
  49. bool ParsingOK( const string& oSource, const char *szPattern, const char* szArgument1, const char* szArgument2 );
  50. bool ParsingOK( const string& oSource, const char *szPattern, const char* szArgument1 );
  51. bool FixArg( char* szArgument );
  52. int CountParameters( string pattern );
  53. string string_format(const string fmt, ...);
  54. void MakeParameterALabel( char *szArgument );
  55. void AddReferencedLabel( string oLabel );
  56. void AddDefinedLabel( string oLabel );
  57. string AddReferencedNotDefinedLabels();
  58. string m_oZ80Code;
  59. vector<string> m_oReferencedLabels;
  60. vector<string> m_oDefinedLabels;
  61. };
  62. void C6502Translator::AddReferencedLabel( string oLabel )
  63. {
  64. if ( !oLabel.empty() )
  65. {
  66. if ( oLabel.substr(0,1) == "(" && oLabel.substr(oLabel.size()-1, 1) == ")" )
  67. {
  68. oLabel = oLabel.substr( 1, oLabel.size() - 2 );
  69. }
  70. m_oReferencedLabels.push_back( oLabel );
  71. }
  72. }
  73. void C6502Translator::AddDefinedLabel( string oLabel )
  74. {
  75. if ( !oLabel.empty() )
  76. {
  77. if ( oLabel.substr(0,1) == "(" && oLabel.substr(oLabel.size() - 1, 1) == ")" )
  78. {
  79. oLabel = oLabel.substr( 1, oLabel.size() - 2 );
  80. }
  81. if ( oLabel.find( ':') != -1 )
  82. {
  83. oLabel = oLabel.substr(0, oLabel.find( ':') );
  84. }
  85. m_oDefinedLabels.push_back( oLabel );
  86. }
  87. }
  88. int CompareStrings( const string &pElem1, const string &pElem2 )
  89. {
  90. return pElem1.compare(pElem2);
  91. }
  92. string C6502Translator::AddReferencedNotDefinedLabels()
  93. {
  94. string oLabel;
  95. string oCode;
  96. string oStr;
  97. // sort arrays
  98. sort(m_oDefinedLabels.begin(), m_oDefinedLabels.end(), greater<string>());
  99. sort(m_oReferencedLabels.begin(), m_oReferencedLabels.end(), greater<string>());
  100. // remove duplicates from defined labels
  101. auto last_def = unique(m_oDefinedLabels.begin(), m_oDefinedLabels.end());
  102. m_oDefinedLabels.erase(last_def, m_oDefinedLabels.end());
  103. // remove duplicates from referenced labels
  104. auto last_ref = unique(m_oReferencedLabels.begin(), m_oReferencedLabels.end());
  105. m_oReferencedLabels.erase(last_ref, m_oReferencedLabels.end());
  106. for ( size_t iPos = 0; iPos < m_oReferencedLabels.size(); iPos++ )
  107. {
  108. oLabel = m_oReferencedLabels[iPos];
  109. if ( find(m_oDefinedLabels.begin(), m_oDefinedLabels.end(), oLabel) != m_oDefinedLabels.end())
  110. {
  111. char* pEnd = NULL;
  112. oStr = oLabel.substr(1);
  113. //oStr = oLabel;
  114. if ( strtol( oStr.c_str(), &pEnd, 16 ) != 0 && !*pEnd )
  115. {
  116. oCode += oLabel + " equ $" + oStr + "\n";
  117. }
  118. else
  119. {
  120. oCode += oLabel + " equ " + oStr + "\n";
  121. }
  122. }
  123. }
  124. return oCode;
  125. }
  126. void C6502Translator::Replace(string& str, const string& from, const string& to) {
  127. if (from.empty())
  128. return;
  129. for (size_t pos = 0; ; pos += to.length()) {
  130. // Locate the substring to replace
  131. pos = str.find(from, pos);
  132. if (pos == string::npos) break;
  133. // Replace by erasing and inserting
  134. str.erase(pos, from.length());
  135. str.insert(pos, to);
  136. }
  137. }
  138. bool C6502Translator::GetNextLine( string& oLine )
  139. {
  140. int iPos = m_oZ80Code.find( "\n" );
  141. if ( iPos >= 0 )
  142. {
  143. oLine = m_oZ80Code.substr(0, iPos );
  144. m_oZ80Code = m_oZ80Code.substr( iPos + 1 );
  145. }
  146. else
  147. {
  148. oLine = m_oZ80Code;
  149. m_oZ80Code.clear();
  150. }
  151. return !oLine.empty() || !m_oZ80Code.empty();
  152. }
  153. int C6502Translator::CountParameters(string pattern)
  154. {
  155. return count(pattern.begin(), pattern.end(), '%' );
  156. }
  157. string C6502Translator::string_format(const string fmt, ...) {
  158. int size = ((int)fmt.size()) * 2 + 50; // Use a rubric appropriate for your code
  159. string str;
  160. va_list ap;
  161. while (1) { // Maximum two passes on a POSIX system...
  162. str.resize(size);
  163. va_start(ap, fmt);
  164. int n = vsnprintf((char *)str.data(), size, fmt.c_str(), ap);
  165. va_end(ap);
  166. if (n > -1 && n < size) { // Everything worked
  167. str.resize(n);
  168. return str;
  169. }
  170. if (n > -1) // Needed size returned
  171. size = n + 1; // For null char
  172. else
  173. size *= 2; // Guess at a larger size (OS specific)
  174. }
  175. return str;
  176. }
  177. bool C6502Translator::ParsingOK( const string& oSource, const char *szPattern, const char* szArgument1, const char* szArgument2 )
  178. {
  179. string oResult = string_format( szPattern, szArgument1, szArgument2 );
  180. return oSource == oResult;
  181. }
  182. bool C6502Translator::ParsingOK( const string& oSource, const char *szPattern, const char* szArgument1 )
  183. {
  184. string oResult = string_format( szPattern, szArgument1 );
  185. return oSource == oResult;
  186. }
  187. bool C6502Translator::FixArg( char* szArgument )
  188. {
  189. char *p=strchr(szArgument,')');
  190. if (!p) p=strchr(szArgument,',');
  191. if (p) *p = '\0';
  192. return true;
  193. }
  194. void C6502Translator::MakeParameterALabel( char *szArgument )
  195. {
  196. string oParameter = string(szArgument);
  197. char *szEnd = NULL;
  198. if ( !oParameter.empty()
  199. && (oParameter[0] != 'L')
  200. && (oParameter[0] != '(')
  201. && strtol(szArgument, &szEnd, 16) != 0L
  202. && *szEnd == 0)
  203. {
  204. oParameter.insert(0, "L");
  205. }
  206. else
  207. {
  208. //oParameter = '$' + oParameter;
  209. }
  210. strncpy( szArgument, oParameter.c_str(), oParameter.size());
  211. }
  212. #define FLAG_MAKE_1ST_PARAM_A_LABEL 1
  213. struct
  214. {
  215. const char *szPattern;
  216. const char *sz6502Code;
  217. int iRead;
  218. int iWrite;
  219. int iFlag;
  220. } g_oCodePatterns[] =
  221. {
  222. { "LD C,D", "lda z80_d|sta z80_c", D, C },
  223. { "LD C,L", "lda z80_l|sta z80_c", L, C },
  224. { "LD L,C", "lda z80_c|sta z80_l", C, L },
  225. { "LD A,A", "ora #$00 ; WHY?", A, A },
  226. { "LD H,A", "sta z80_h", A, H },
  227. { "LD A,H", "lda z80_h", H, A },
  228. { "LD C,A", "sta z80_c", A, C },
  229. { "LD A,C", "lda z80_c", C, A },
  230. { "LD L,A", "sta z80_l", A, L },
  231. { "LD A,L", "lda z80_l", L, A },
  232. { "LD E,A", "sta z80_e", A, E },
  233. { "LD A,B", "lda z80_b", B, A },
  234. { "LD B,A", "sta z80_b", A, B },
  235. { "LD A,D", "lda z80_d", D, A },
  236. { "LD D,A", "sta z80_d", A, D },
  237. { "LD D,B", "lda z80_b|sta z80_d", B, D },
  238. { "LD H,B", "lda z80_b|sta z80_h", B, H },
  239. { "LD H,D", "lda z80_d|sta z80_h", D, H },
  240. { "LD H,E", "lda z80_e|sta z80_h", E, H },
  241. { "LD H,H", "lda z80_h|sta z80_h", H, H },
  242. { "LD H,L", "lda z80_l|sta z80_h", L, H },
  243. { "LD L,D", "lda z80_d|sta z80_l", D, L },
  244. { "LD L,E", "lda z80_e|sta z80_l", E, L },
  245. { "LD A,E", "lda z80_e", E, A },
  246. { "LD B,C", "lda z80_c|sta z80_b", C, B },
  247. { "LD B,H", "lda z80_h|sta z80_b", H, B },
  248. { "LD E,L", "lda z80_l|sta z80_e", L, E },
  249. { "LD E,C", "lda z80_c|sta z80_e", C, E },
  250. { "LD H,C", "lda z80_c|sta z80_h", C, H },
  251. { "LD D,L", "lda z80_l|sta z80_d", L, D },
  252. { "LD D,H", "lda z80_h|sta z80_d", H, D },
  253. { "LD A,R", "ld_a_r", R, A },
  254. { "LD SP,HL", "; TODO: LD SP,HL", HL, SP },
  255. { "LD SP,HL", "; TODO: LD SP,HL", HL, SP},
  256. { "LD A,$%02s", "lda #$%1", 0, A },
  257. { "LD B,$%02s", "lda #$%1|sta z80_b", 0, B },
  258. { "LD C,$%02s", "lda #$%1|sta z80_c", 0, C },
  259. { "LD D,$%02s", "lda #$%1|sta z80_d", 0, D },
  260. { "LD E,$%02s", "lda #$%1|sta z80_e", 0, E },
  261. { "LD L,$%02s", "lda #$%1|sta z80_l", 0, L },
  262. { "LD H,$%02s", "lda #$%1|sta z80_h", 0, H },
  263. { "LD IY,%s", "lda #<%1|sta z80_iy|lda #>%1|sta z80_iy+1", 0, IY, FLAG_MAKE_1ST_PARAM_A_LABEL },
  264. { "LD IX,%s", "lda #<%1|sta z80_ix|lda #>%1|sta z80_ix+1", 0, IX, FLAG_MAKE_1ST_PARAM_A_LABEL },
  265. { "LD BC,(%05s)", "lda %1|sta z80_c|lda %1+1|sta z80_b", 0, HL, FLAG_MAKE_1ST_PARAM_A_LABEL },
  266. { "LD BC,%s", "lda #<%1|sta z80_c|lda #>%1|sta z80_b", 0, BC, FLAG_MAKE_1ST_PARAM_A_LABEL },
  267. { "LD DE,(%05s)", "lda %1|sta z80_e|lda %1+1|sta z80_d", 0, HL, FLAG_MAKE_1ST_PARAM_A_LABEL },
  268. { "LD DE,%s", "lda #<%1|sta z80_e|lda #>%1|sta z80_d", 0, DE, FLAG_MAKE_1ST_PARAM_A_LABEL },
  269. { "LD HL,(%05s)", "lda %1|sta z80_l|lda %1+1|sta z80_h", 0, HL, FLAG_MAKE_1ST_PARAM_A_LABEL },
  270. { "LD HL,%s", "lda #<%1|sta z80_l|lda #>%1|sta z80_h", 0, HL, FLAG_MAKE_1ST_PARAM_A_LABEL },
  271. { "LD A,(IX+%02s)", "ldy #$%1|lda (z80_ix),y", IX, A },
  272. { "LD A,(IY+%02s)", "ldy #$%1|lda (z80_iy),y", IY, A },
  273. { "LD B,(IX+%02s)", "ldy #$%1|lda (z80_ix),y|sta z80_b", IX, B },
  274. { "LD C,(IX+%02s)", "ldy #$%1|lda (z80_ix),y|sta z80_c", IX, C },
  275. { "LD D,(IX+%02s)", "ldy #$%1|lda (z80_ix),y|sta z80_d", IX, D},
  276. { "LD L,(IX+%02s)", "ldy #$%1|lda (z80_ix),y|sta z80_l", IX, L },
  277. { "LD H,(IX+%02s)", "ldy #$%1|lda (z80_ix),y|sta z80_h", IX, H },
  278. { "LD (IX+%02s),A", "ldy #$%1|sta (z80_ix),y", A|IX, 0 },
  279. { "LD (IX+%02s),B", "ldy #$%1|lda z80_b|sta (z80_ix),y", B|IX, 0 },
  280. { "LD (IX+%02s),C", "ldy #$%1|lda z80_c|sta (z80_ix),y", C|IX, 0 },
  281. { "LD (IX+%02s),L", "ldy #$%1|lda z80_l|sta (z80_ix),y", L|IX, 0 },
  282. { "LD (IX+%02s),H", "ldy #$%1|lda z80_h|sta (z80_ix),y", H|IX, 0 },
  283. { "LD (IX+%02s),%02s", "ldy #$%1|lda #$%2|sta (z80_ix),y", IX, 0 },
  284. { "LD (IY+%02s),A", "ldy #$%1|sta (z80_iy),y", A|IY, 0 },
  285. { "LD (IY+%02s),C", "ldy #$%1|lda z80_c|sta (z80_iy),y", C|IY, 0 },
  286. { "LD (IY+%02s),D", "ldy #$%1|lda z80_d|sta (z80_iy),y", D|IY, 0 },
  287. { "LD (IY+%02s),E", "ldy #$%1|lda z80_e|sta (z80_iy),y", E|IY, 0 },
  288. { "LD (IY+%02s),%02s", "ldy #$%1|lda #$%2|sta (z80_iy),y", IY, 0 },
  289. { "LD D,(IY+%02s)", "ldy #$%1|lda (z80_iy),y|sta z80_d", IY, D },
  290. { "LD E,(IY+%02s)", "ldy #$%1|lda (z80_iy),y|sta z80_e", IY, E },
  291. { "LD L,(IY+%02s)", "ldy #$%1|lda (z80_iy),y|sta z80_l", IY, L },
  292. { "LD A,(HL)", "ldy #$00|lda (z80_hl),y", HL, A },
  293. { "LD A,(DE)", "ldy #$00|lda (z80_de),y", DE, A },
  294. { "LD A,(BC)", "ldy #$00|lda (z80_bc),y", BC, A },
  295. { "LD (BC),A", "ldy #$00|sta (z80_bc),y", A|BC, 0 },
  296. { "LD (DE),A", "ldy #$00|sta (z80_de),y", A|DE, 0 },
  297. { "LD A,(%05s)", "lda %1", 0, A, FLAG_MAKE_1ST_PARAM_A_LABEL },
  298. { "LD (%05s),A", "sta %1", A, 0, FLAG_MAKE_1ST_PARAM_A_LABEL },
  299. { "LD B,(HL)", "ldy #$00|lda (z80_hl),y|sta z80_b", HL, B },
  300. { "LD C,(HL)", "ldy #$00|lda (z80_hl),y|sta z80_c", HL, C },
  301. { "LD D,(HL)", "ldy #$00|lda (z80_hl),y|sta z80_d", HL, D },
  302. { "LD E,(HL)", "ldy #$00|lda (z80_hl),y|sta z80_e", HL, E },
  303. { "LD H,(HL)", "ldy #$00|lda (z80_hl),y|sta z80_h", HL, H },
  304. { "LD L,(HL)", "ldy #$00|lda (z80_hl),y|sta z80_l", HL, L },
  305. { "LD (HL),A", "ldy #$00|sta (z80_hl),y", A|HL, 0 },
  306. { "LD (HL),C", "lda z80_c|ldy #$00|sta (z80_hl),y", C|HL, 0 },
  307. { "LD (HL),D", "lda z80_d|ldy #$00|sta (z80_hl),y", D|HL, 0 },
  308. { "LD (HL),E", "lda z80_e|ldy #$00|sta (z80_hl),y", E|HL, 0 },
  309. { "LD (HL),$%02s", "lda #$%1|ldy #$00|sta (z80_hl),y", HL, 0 },
  310. { "LD SP,(%05s)", "; LD SP,(%1): TODO ", 0, SP},
  311. { "LD SP,%s", "; LD SP,%1: TODO ", 0, SP},
  312. { "LD (%05s),HL", "lda z80_l|sta %1|lda z80_h|sta %1+1", HL, 0, FLAG_MAKE_1ST_PARAM_A_LABEL },
  313. { "LD A,(%s)", "lda %1", 0, A, FLAG_MAKE_1ST_PARAM_A_LABEL },
  314. { "LD (%s),A", "sta %1", A, 0, FLAG_MAKE_1ST_PARAM_A_LABEL },
  315. { "LD (%05s),SP", "; TODO: LD (%1),SP", SP, 0, FLAG_MAKE_1ST_PARAM_A_LABEL },
  316. { "LD (%05s),HL", "lda z80_l|sta %1|lda z80_h|sta %1+1", HL, 0, FLAG_MAKE_1ST_PARAM_A_LABEL },
  317. { "LD (%05s),DE", "lda z80_e|sta %1|lda z80_d|sta %1+1", DE, 0, FLAG_MAKE_1ST_PARAM_A_LABEL },
  318. { "LDH A,($%02s) ; %s", "lda $FF%1", 0, A },
  319. { "LDH ($%02s),A ; %s", "sta $FF%1", A, 0 },
  320. { "OR (IY+%02s)", "ldy #$%1|ora (z80_iy),y", A|IY, A|FLAGS },
  321. { "OR (IX+%02s)", "ldy #$%1|ora (z80_ix),y", A|IX, A|FLAGS },
  322. { "OR A", "ora #$00 ; OR A: Warning: probably tests for zero", A, A | FLAGS },
  323. { "OR B", "ora z80_b", A|B, A|FLAGS },
  324. { "OR C", "ora z80_c", A|C, A|FLAGS },
  325. { "OR D", "ora z80_d", A|D, A|FLAGS },
  326. { "OR E", "ora z80_e", A|E, A|FLAGS },
  327. { "OR L", "ora z80_l", A|L, A|FLAGS },
  328. { "OR H", "ora z80_h", A|H, A|FLAGS },
  329. { "OR (HL)", "ldy #$00|ora (z80_hl),y", A|HL, A|FLAGS },
  330. { "OR $%02s", "ora #$%1", A, A|FLAGS },
  331. { "ADD A,A", "asl @", A, A|FLAGS },
  332. { "ADD A,B", "clc|adc z80_b", A|B, A|FLAGS },
  333. { "ADD A,C", "clc|adc z80_c", A|C, A|FLAGS },
  334. { "ADD A,D", "clc|adc z80_d", A|D, A|FLAGS },
  335. { "ADD A,E", "clc|adc z80_e", A|E, A|FLAGS },
  336. { "ADD A,L", "clc|adc z80_l", A|L, A|FLAGS },
  337. { "ADD A,H", "clc|adc z80_h", A|H, A|FLAGS },
  338. { "ADD IY,DE", "jsr add_iy_de", IY|DE, IY|HFLAG|CARRY|NFLAG },
  339. { "ADD IY,BC", "jsr add_iy_bc", IY|BC, IY|HFLAG|CARRY|NFLAG },
  340. { "ADD IX,DE", "jsr add_ix_de", IX|DE, IX|HFLAG|CARRY|NFLAG },
  341. { "ADD HL,DE", "jsr add_hl_de", HL|DE, HL|HFLAG|CARRY|NFLAG },
  342. { "ADD HL,BC", "jsr add_hl_bc", HL|BC, HL|HFLAG|CARRY|NFLAG },
  343. { "ADD HL,SP", "jsr add_hl_sp", HL|SP, HL|HFLAG|CARRY|NFLAG },
  344. { "ADD HL,HL", "asl z80_l|rol z80_h", HL, HL|HFLAG|CARRY|NFLAG },
  345. { "ADD A,(HL)", "ldy #$00|clc|adc (z80_hl),y", A|HL, A|FLAGS },
  346. { "ADD A,(IX+%02s)", "ldy #$%1|clc|adc (z80_ix),y", A|IX, A|FLAGS },
  347. { "ADD A,(IY+%02s)", "ldy #$%1|clc|adc (z80_iy),y", A|IY, A|FLAGS },
  348. { "ADD A,$%02s", "clc|adc #$%1", A, A|FLAGS },
  349. { "ADD A", "asl @", A, A|FLAGS },
  350. { "ADC A,B", "adc z80_b", A|B|CARRY, A|FLAGS },
  351. { "ADC A,$%02s", "adc #$%1", A|CARRY, A|FLAGS },
  352. { "SUB (IX+%02s)", "ldy #$%1|sec|sbc (z80_ix),y", A|IX, A|FLAGS },
  353. { "SUB (IY+%02s)", "ldy #$%1|sec|sbc (z80_iy),y", A|IY, A|FLAGS },
  354. { "SUB B", "sec|sbc z80_b", A|B, A|FLAGS },
  355. { "SUB C", "sec|sbc z80_c", A|C, A|FLAGS },
  356. { "SUB D", "sec|sbc z80_d", A|D, A|FLAGS },
  357. { "SUB E", "sec|sbc z80_e", A|E, A|FLAGS },
  358. { "SUB L", "sec|sbc z80_l", A|L, A|FLAGS },
  359. { "SUB H", "sec|sbc z80_h", A|H, A|FLAGS },
  360. { "SUB (HL)", "ldy #$00|sec|sbc (z80_hl),y", A | HL, A | FLAGS },
  361. { "SUB $%02s", "sec|sbc #$%1", A, A|FLAGS },
  362. { "SBC A,A", "lda #$00|sec", A | A | FLAGS },
  363. { "SBC A,B", "sec|sbc z80_b", A | B, A | FLAGS },
  364. { "SBC A,H", "sec|sbc z80_h", A | H, A | FLAGS },
  365. { "SBC A,(HL)", "ldy #$00|sec|sbc (z80_hl),y", A | HL, A | FLAGS },
  366. { "SBC HL,DE", "jsr sbc_hl_de", HL|DE|CARRY, HL|FLAGS },
  367. { "SBC HL,BC", "jsr sbc_hl_bc", HL|BC|CARRY, HL|FLAGS },
  368. { "AND A", "; AND A: Warning: probably tests for zero", A, A|FLAGS },
  369. { "AND B", "and z80_b", A|B, FLAGS },
  370. { "AND C", "and z80_c", A|C, FLAGS },
  371. { "AND D", "and z80_d", A|D, FLAGS },
  372. { "AND L", "and z80_l", A|L, FLAGS },
  373. { "AND (HL)", "ldy #$00|and (z80_hl),y", A|HL, A|FLAGS },
  374. { "AND $%02s", "and #$%1", A, A|FLAGS },
  375. { "CP B", "cmp z80_b", A|B, FLAGS },
  376. { "CP C", "cmp z80_c", A|C, FLAGS },
  377. { "CP D", "cmp z80_d", A|D, FLAGS },
  378. { "CP E", "cmp z80_e", A|E, FLAGS },
  379. { "CP H", "cmp z80_h", A|H, FLAGS },
  380. { "CP L", "cmp z80_l", A|L, FLAGS },
  381. { "CP (HL)", "ldy #$00|cmp (z80_hl),y", A|HL, FLAGS },
  382. { "CP (IX+%02s)", "ldy #$%1|cmp (z80_ix),y", A|IX, FLAGS },
  383. { "CP (IY+%02s)", "ldy #$%1|cmp (z80_iy),y", A|IY, FLAGS },
  384. { "CP $%02s", "cmp #$%1", A, FLAGS },
  385. { "NEG", "eor #$ff|clc|adc #$01", A, A|FLAGS },
  386. { "CPL", "eor #$ff", A, A|NFLAG|HFLAG },
  387. { "XOR A", "lda #$00", 0, A|FLAGS },
  388. { "XOR B", "eor z80_b", A|B, FLAGS },
  389. { "XOR C", "eor z80_c", A|C, FLAGS },
  390. { "XOR D", "eor z80_d", A|D, FLAGS },
  391. { "XOR E", "eor z80_e", A|E, FLAGS },
  392. { "XOR (HL)", "ldy #$00|eor (z80_hl),y", A|HL, A|FLAGS },
  393. { "XOR (IX+%02s)", "ldy #$%1|eor (z80_ix),y", A|IX, A|FLAGS },
  394. { "XOR $%02s", "eor #$%1", A, A|FLAGS },
  395. { "INC A", "clc|adc #$01", A, A|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  396. { "INC B", "inc z80_b", B, B|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  397. { "INC C", "inc z80_c", C, C|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  398. { "INC D", "inc z80_d", D, D|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  399. { "INC E", "inc z80_e", E, E|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  400. { "INC L", "inc z80_l", L, L|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  401. { "INC H", "inc z80_h", H, H|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  402. { "INC HL", "inc z80_l|bne *+4|inc z80_h", HL, HL },
  403. { "INC BC", "inc z80_c|bne *+4|inc z80_b", BC, BC },
  404. { "INC DE", "inc z80_e|bne *+4|inc z80_d", DE, DE },
  405. { "INC IX", "inc z80_ix|bne *+4|inc z80_ix+1", IX, IX },
  406. { "INC IY", "inc z80_iy|bne *+4|inc z80_iy+1", IY, IY },
  407. { "INC SP", "pla", SP, SP },
  408. { "INC (IX+%02s)", "ldy #$%1|lda (z80_ix),y|clc|adc #$01|sta (z80_ix),y", IX, SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  409. { "INC (HL)", "ldy #$00|lda (z80_hl),y|clc|adc #$01|sta (z80_hl),y", HL, SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  410. { "DEC A", "sec|sbc #$01", A, A|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  411. { "DEC B", "dec z80_b", B, B|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  412. { "DEC C", "dec z80_c", C, C|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  413. { "DEC D", "dec z80_d", D, D|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  414. { "DEC E", "dec z80_e", E, E|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  415. { "DEC H", "dec z80_h", H, H|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  416. { "DEC L", "dec z80_l", L, L|SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  417. { "DEC (HL)", "ldy #$00|lda (z80_hl),y|sec|sbc #$01|sta (z80_hl),y", HL, SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  418. { "DEC (IX+%02s)", "ldy #$%1|lda (z80_ix),y|sec|sbc #$01|sta (z80_ix),y", IX, SIGN|ZERO|HFLAG|OVERFLOWFLAG|NFLAG },
  419. { "DEC IX", "jsr dec_ix", IX, IX },
  420. { "DEC HL", "jsr dec_hl", HL, HL },
  421. { "DEC BC", "jsr dec_bc", BC, BC },
  422. { "DEC DE", "jsr dec_de", DE, DE },
  423. { "DEC SP", "pha", SP, SP },
  424. { "EX DE,HL", "jsr ex_de_hl", DE|HL, DE|HL },
  425. { "RRCA", "lsr @ ; RRCA: Warning: this copies bit 0 to bit 7", A, A|HFLAG|NFLAG|CARRY },
  426. { "RRC A", "lsr @ ; RRCA: Warning: this copies bit 0 to bit 7", A, A|HFLAG|NFLAG|CARRY },
  427. { "RLCA", "asl @ ; RLCA: Warning: this copies bit 7 to bit 0", A, A|HFLAG|NFLAG|CARRY },
  428. { "RRA", "ror @", A|CARRY, A|HFLAG|NFLAG|CARRY },
  429. { "SRA A", "cmp #$80|ror @", A, A|FLAGS },
  430. { "SRL A", "lsr @", A, A|FLAGS },
  431. { "SRL E", "lsr z80_e", E, E|FLAGS },
  432. { "SRL D", "lsr z80_d", D, D|FLAGS },
  433. { "SRL B", "lsr z80_b", B, B|FLAGS },
  434. { "SRL C", "lsr z80_c", C, C|FLAGS },
  435. { "SLA A", "asl @", A, A|FLAGS },
  436. { "SLA C", "asl z80_c", C, C|FLAGS },
  437. { "SLA E", "asl z80_e", E, E|FLAGS },
  438. { "SRL H", "lsr z80_h", H, H|FLAGS },
  439. { "RL C", "rol z80_c", C|CARRY, C|FLAGS },
  440. { "RL D", "rol z80_d", D|CARRY, D|FLAGS },
  441. { "RL E", "rol z80_e", E|CARRY, E|FLAGS },
  442. { "RR C", "ror z80_c", C|CARRY, C|FLAGS },
  443. { "RR L", "ror z80_l", L|CARRY, L|FLAGS },
  444. { "CALL C,%s", "bcs *+5|jsr %1 ; CALL C: Warning: check carry", CARRY, 0 },
  445. { "CALL NC,%s", "bcc *+5|jsr %1 ; CALL NC: Warning: check carry", CARRY, 0 },
  446. { "CALL Z,%s", "bne *+5|jsr %1", ZERO, 0 },
  447. { "CALL NZ,%s", "beq *+5|jsr %1", ZERO, 0 },
  448. { "CALL %s", "jsr %1", 0, 0 },
  449. { "JP Z,%s", "jeq %1", ZERO, 0 },
  450. { "JP NZ,%s", "jne %1", ZERO, 0 },
  451. { "JP NC,%s", "jcs %1", CARRY, 0 },
  452. { "JP C,%s", "jcc %1", CARRY, 0 },
  453. { "JP M,%s", "jmi %1", SIGN, 0 },
  454. { "JP P,%s", "jpl %1", SIGN, 0 },
  455. { "JP (HL)", "jmp (z80_hl)", HL, 0 },
  456. { "JP %s", "jmp %1", 0, 0 },
  457. { "DJNZ %s", "dec z80_b|jne %1", B, B },
  458. { "JR Z,%s", "jeq %1", ZERO, 0 },
  459. { "JR C,%s", "jcc %1", CARRY, 0 },
  460. { "JR NC,%s", "jcs %1", CARRY, 0 },
  461. { "JR NZ,%s", "jne %1", ZERO, 0 },
  462. { "JR %s", "jmp %1", 0, 0 },
  463. { "BIT %1s,(IX+%02s)", "ldy #$%2|lda (z80_ix),y|bit _bitmem%1", IX, ZERO|HFLAG|NFLAG },
  464. { "SET %1s,(IX+%02s)", "ldy #$%2|lda (z80_ix),y|ora #_bitvalue%1|sta (z80_ix),y", IX, 0 },
  465. { "RES %1s,(IX+%02s)", "ldy #$%2|lda (z80_ix),y|and #_notbitvalue%1|sta (z80_ix),y", IX, 0 },
  466. { "BIT %1s,(IY+%02s)", "ldy #$%2|lda (z80_iy),y|bit _bitmem%1", IY, ZERO|HFLAG|NFLAG },
  467. { "SET %1s,(IY+%02s)", "ldy #$%2|lda (z80_iy),y|ora #_bitvalue%1|sta (z80_iy),y", IY, 0 },
  468. { "RES %1s,(IY+%02s)", "ldy #$%2|lda (z80_iy),y|and #_notbitvalue%1|sta (z80_iy),y", IY, 0 },
  469. { "RES %1s,(HL)", "ldy #$00|lda (z80_hl),y|and #_notbitvalue%1|sta (z80_hl),y", HL, 0 },
  470. { "SET %1s,(HL)", "ldy #$00|lda (z80_hl),y|ora #_bitvalue%1|sta (z80_hl),y", HL, 0 },
  471. { "BIT %1s,(HL)", "ldy #$00|lda (z80_hl),y|bit _bitmem%1", HL, ZERO|HFLAG|NFLAG },
  472. { "BIT %1s,E", "lda z80_e|bit _bitmem%1", E, ZERO|HFLAG|NFLAG },
  473. { "BIT %1s,C", "lda z80_c|bit _bitmem%1", C, ZERO|HFLAG|NFLAG },
  474. { "SET %1s,C", "lda z80_c|ora #_bitvalue%1|sta z80_c", C, C },
  475. { "RES %1s,C", "lda z80_c|and #_notbitvalue%1|sta z80_c", C, C },
  476. { "BIT %1s,A", "bit _bitmem%1", A, ZERO|HFLAG|NFLAG },
  477. { "SET %1s,A", "lda z80_a|ora #_bitvalue%1|sta z80_a", A, A }, // added
  478. { "RES %1s,A", "lda z80_a|and #_notbitvalue%1|sta z80_a", A, A }, // added
  479. { "SET %s,A", "lda z80_a|ora #%1|sta z80_a", A, A }, // added
  480. { "RES %s,A", "lda z80_a|and #%1|sta z80_a", A, A }, // added
  481. { "RETI", "rti", 0, 0 },
  482. { "RET", "rts", 0, 0 },
  483. { "RET NZ", "beq *+3|rts", ZERO, 0 },
  484. { "RET NC", "bcc *+3|rts", CARRY, 0 },
  485. { "RET C", "bcs *+3|rts", CARRY, 0 },
  486. { "RET Z", "bne *+3|rts", ZERO, 0 },
  487. { "RET M", "bpl *+3|rts", SIGN, 0 },
  488. { "RET P", "bmi *+3|rts", SIGN, 0 },
  489. { "PUSH DE", "lda z80_e|pha|lda z80_d|pha", DE, SP },
  490. { "PUSH HL", "lda z80_l|pha|lda z80_h|pha", HL, SP },
  491. { "POP HL", "pla|sta z80_h|pla|sta z80_l", SP, HL },
  492. { "POP DE", "pla|sta z80_d|pla|sta z80_e", SP, DE },
  493. { "PUSH IX", "lda z80_ix|pha|lda z80_ix+1|pha", IX, SP },
  494. { "POP IX", "pla|sta z80_ix+1|pla|sta z80_ix", SP, IX },
  495. { "PUSH IY", "lda z80_iy|pha|lda z80_iy+1|pha", IY, SP },
  496. { "POP IY", "pla|sta z80_iy+1|pla|sta z80_iy", SP, IY },
  497. { "PUSH BC", "lda z80_c|pha|lda z80_b|pha", BC, SP },
  498. { "POP BC", "pla|sta z80_b|pla|sta z80_c", SP, BC },
  499. { "PUSH AF", "pha|php", A|FLAGS, SP },
  500. { "POP AF", "plp|pha", SP, A|FLAGS },
  501. { "LDIR", "jsr ldir", HL|DE|BC, HL|DE|BC|HFLAG|OVERFLOWFLAG|NFLAG },
  502. { "LDDR", "jsr lddr", HL|DE|BC, HL|DE|BC|HFLAG|OVERFLOWFLAG|NFLAG },
  503. { "EX AF,AF'", "ldx z80_ap|sta z80_ap|txa ; TODO: EX AF,AF'", A|FLAGS, A|FLAGS },
  504. { "EXX", "jsr exx ; TODO: EXX", HL|DE|BC, HL|DE|BC },
  505. { "EX (SP),HL", "jsr ex_sp_hl; TODO: EX (SP),HL", SP|HL, HL },
  506. { "SCF", "sec", 0, CARRY },
  507. { "NOP", "nop", 0, 0 },
  508. { "DAA", "; TODO: decimal mode", A|CARRY|HFLAG, A|CARRY|HFLAG|SIGN|ZERO|OVERFLOWFLAG },
  509. { "OUT (FE),A", "jsr out_fe", A, 0 },
  510. { "OUT (FD),A", "jsr out_fd", A, 0 },
  511. { "IN A,(FE)", "jsr in_a_fe", 0, A },
  512. { "IN A,(1F)", "jsr in_a_1f", 0, A },
  513. { "EI", "jsr ei", 0, 0 },
  514. { "DI", "jsr di", 0, 0 },
  515. { "DW ", "; .wo 0", 0, 0 },
  516. { "DW %s", ".wo %1", 0, 0 },
  517. { "DB %s", ".he %1", 0, 0 },
  518. { NULL, NULL, 0, 0 }
  519. };
  520. string C6502Translator::Translate()
  521. {
  522. string oCodeLine;
  523. string oLabel;
  524. string oInstruction;
  525. bool bParsed = false;
  526. string oZ80Code;
  527. string o6502CodeLine;
  528. string o6502Code;
  529. string oAllCode;
  530. int iPos, iPadSpaces = 8;
  531. int iPreviousInstructionPattern = -1;
  532. int iPattern;
  533. regex e ("\\b([ ]+)([^ ]*)");
  534. string fmt (" $2");
  535. char szArgument1[128], szArgument2[128];
  536. while ( GetNextLine( oCodeLine ) )
  537. {
  538. if ( oCodeLine.empty() )
  539. {
  540. // flush block
  541. oAllCode += oZ80Code + "\n" + o6502Code + "\n";
  542. oZ80Code.clear();
  543. o6502Code.clear();
  544. iPreviousInstructionPattern = -1;
  545. continue;
  546. }
  547. Replace(oCodeLine, "\t", string(iPadSpaces, ' '));
  548. oZ80Code += ";" + oCodeLine + "\n";
  549. if ( oCodeLine[0] == ';' )
  550. {
  551. // comment
  552. o6502Code += oCodeLine + "\n";
  553. continue;
  554. }
  555. if (oCodeLine.length() > 7 && oCodeLine.at(7) != ' ' )
  556. {
  557. // label definition without mnemonic
  558. o6502Code += oCodeLine + "\n";
  559. AddDefinedLabel( oCodeLine );
  560. continue;
  561. }
  562. oLabel = oCodeLine.substr(0, iPadSpaces);
  563. oLabel.erase(find_if(oLabel.rbegin(), oLabel.rend(),
  564. not1(ptr_fun<int, int>(isspace))).base(), oLabel.end()); // trim right
  565. if (oLabel.empty() || (oLabel.find(':') == string::npos))
  566. {
  567. oLabel.clear();
  568. iPos = iPadSpaces;
  569. o6502CodeLine = string(iPadSpaces, ' ');
  570. }
  571. else
  572. {
  573. o6502CodeLine = string_format("%-8s", oLabel.c_str());
  574. iPos = oLabel.size();
  575. oLabel.erase(remove(oLabel.begin(), oLabel.end(), ':'), oLabel.end()); // Remove
  576. AddDefinedLabel(oLabel);
  577. }
  578. oInstruction = oCodeLine.substr(iPos);
  579. char buf[128];
  580. char buf2[128];
  581. int blen = oInstruction.size() + 1;
  582. if (blen > 128) blen = 128;
  583. strncpy(&buf[0], oInstruction.c_str(), blen); buf[--blen]='\0';
  584. *regex_replace(&buf2[0], &buf[0], &buf[0]+strlen(buf), e, fmt) = '\0';
  585. oInstruction = string(buf2);
  586. ::transform(oInstruction.begin(), oInstruction.end(), oInstruction.begin(), ::toupper);
  587. Replace(oInstruction, ", ", ",");
  588. Replace(oInstruction, "[", "(");
  589. Replace(oInstruction, "]", ")");
  590. bParsed = false;
  591. for ( iPattern = 0; !bParsed && g_oCodePatterns[iPattern].szPattern != NULL; iPattern++ )
  592. {
  593. string pattern = g_oCodePatterns[iPattern].szPattern;
  594. //pattern.Replace("%02s", " %s");
  595. Replace(pattern, "%05s", " %s");
  596. Replace(pattern, "%1s", " %s");
  597. Replace(pattern, ", %s", ",%s");
  598. Replace(pattern, "( %", "(%");
  599. Replace(pattern, "$ %", "$%");
  600. bool test=(iPattern==143 && oInstruction.substr(0,2) == "CP");
  601. switch( CountParameters( pattern ) )
  602. {
  603. case 0:
  604. if ( oInstruction == g_oCodePatterns[iPattern].szPattern )
  605. {
  606. o6502CodeLine += g_oCodePatterns[iPattern].sz6502Code;
  607. bParsed = true;
  608. }
  609. break;
  610. case 1:
  611. if ( sscanf( oInstruction.c_str(), pattern.c_str(), szArgument1 ) == 1 &&
  612. FixArg( szArgument1 ) && ParsingOK( oInstruction, pattern.c_str(), szArgument1 ) )
  613. {
  614. o6502CodeLine += g_oCodePatterns[iPattern].sz6502Code;
  615. if ( g_oCodePatterns[iPattern].iFlag == FLAG_MAKE_1ST_PARAM_A_LABEL )
  616. {
  617. MakeParameterALabel( szArgument1 );
  618. string oArgument1(szArgument1);
  619. AddReferencedLabel(oArgument1);
  620. }
  621. string oArgument1(szArgument1);
  622. if ( oInstruction.substr(0,2) == "DB" )
  623. {
  624. oArgument1.erase(remove(oArgument1.begin(), oArgument1.end(), 'h'), oArgument1.end()); // Remove
  625. }
  626. Replace(o6502CodeLine, "%1", oArgument1);
  627. bParsed = true;
  628. }
  629. break;
  630. case 2:
  631. if ( sscanf( oInstruction.c_str(), pattern.c_str(), szArgument1, szArgument2 ) == 2 &&
  632. FixArg( szArgument1 ) && ParsingOK( oInstruction, pattern.c_str(), szArgument1, szArgument2 ) )
  633. {
  634. o6502CodeLine += g_oCodePatterns[iPattern].sz6502Code;
  635. string oArgument1(szArgument1);
  636. Replace(o6502CodeLine, "%1", oArgument1);
  637. string oArgument2(szArgument2);
  638. Replace(o6502CodeLine, "%2", oArgument2);
  639. bParsed = true;
  640. }
  641. break;
  642. }
  643. }
  644. if ( bParsed )
  645. {
  646. iPos = o6502CodeLine.find( '|' );
  647. if ( iPos != -1 )
  648. {
  649. o6502CodeLine.insert( iPos, " ; " + oInstruction );
  650. }
  651. else
  652. {
  653. o6502CodeLine += " ; " + oInstruction;
  654. }
  655. Replace(o6502CodeLine, "|", "\n ");
  656. iPattern -= 1;
  657. if ( (g_oCodePatterns[iPattern].iRead & A)
  658. && iPreviousInstructionPattern != -1
  659. && !(g_oCodePatterns[iPreviousInstructionPattern].iWrite & A)
  660. && !(g_oCodePatterns[iPreviousInstructionPattern].iRead & A)
  661. //&& !(g_oCodePatterns[iPreviousInstructionPattern].iWrite & BC|DE|HL|IX|IY)
  662. )
  663. {
  664. o6502CodeLine += "; Warning: A read but not set by previous instruction";
  665. }
  666. if ( (g_oCodePatterns[iPattern].iRead & A)
  667. && iPreviousInstructionPattern == -1
  668. )
  669. {
  670. o6502CodeLine += "; Warning: A read at the beginning of the block";
  671. }
  672. if ( (g_oCodePatterns[iPattern].iRead & A) && !oLabel.empty() )
  673. {
  674. o6502CodeLine += "; Warning: A read at jump target instruction";
  675. }
  676. if ( (g_oCodePatterns[iPattern].iRead & ZERO) && iPreviousInstructionPattern != -1 && !(g_oCodePatterns[iPreviousInstructionPattern].iWrite & ZERO))
  677. {
  678. o6502CodeLine += "; Warning: ZERO flag read but not set by previous instruction";
  679. }
  680. if ( (g_oCodePatterns[iPattern].iRead & SIGN) && iPreviousInstructionPattern != -1 && !(g_oCodePatterns[iPreviousInstructionPattern].iWrite & SIGN))
  681. {
  682. o6502CodeLine += "; Warning: SIGN flag read but not set by previous instruction";
  683. }
  684. if ( (g_oCodePatterns[iPattern].iRead & CARRY)
  685. && iPreviousInstructionPattern != -1
  686. && (strncmp( g_oCodePatterns[iPattern].szPattern, "JP", 2 ) == 0 || strncmp( g_oCodePatterns[iPattern].szPattern, "JR", 2 ) == 0 || strncmp( g_oCodePatterns[iPattern].szPattern, "RET", 3 ) == 0 || strncmp( g_oCodePatterns[iPattern].szPattern, "CALL", 4 ) == 0 ) )
  687. {
  688. if ( !(g_oCodePatterns[iPreviousInstructionPattern].iWrite & CARRY) )
  689. {
  690. o6502CodeLine += "; Warning: CARRY flag read but not set by previous instruction";
  691. }
  692. else if ( strncmp( g_oCodePatterns[iPreviousInstructionPattern].szPattern, "CP", 2 ) != 0
  693. && strncmp( g_oCodePatterns[iPreviousInstructionPattern].szPattern, "SUB", 3 ) != 0
  694. && strncmp( g_oCodePatterns[iPreviousInstructionPattern].szPattern, "SBC", 3 ) != 0
  695. )
  696. {
  697. o6502CodeLine += "; Warning: CARRY flag read but not set not by CP/SUB/SBC instruction, may need to invert";
  698. }
  699. }
  700. iPreviousInstructionPattern = iPattern;
  701. }
  702. else if (oInstruction.size() > 0)
  703. {
  704. // AfxMessageBox( "Syntax Error: " + oInstruction );
  705. o6502CodeLine = "; Syntax Error: " + oInstruction;
  706. }
  707. o6502Code += (o6502CodeLine + "\n");
  708. }
  709. oAllCode += oZ80Code + "\n" + o6502Code;
  710. oAllCode = AddReferencedNotDefinedLabels() + "\n\n" + oAllCode;
  711. return oAllCode;
  712. }
  713. int main(int argc, char* argv[])
  714. {
  715. int nRetCode = 0;
  716. string oCode;
  717. //
  718. try
  719. {
  720. string fName = "D:\\Source\\Repos\\pokeyellow\\home.asm";
  721. if (argc == 2) fName = argv[1];
  722. ifstream oFile;
  723. oFile.open(fName, ifstream::in);
  724. char c = oFile.get();
  725. while (oFile.good()) {
  726. oCode.push_back(c);
  727. c = oFile.get();
  728. }
  729. oFile.close();
  730. }
  731. catch(ios_base::failure f)
  732. {
  733. fprintf(stderr, "%s", f.what());
  734. }
  735. //
  736. //oCode = "@@73 LD (IX+09),C\n";
  737. C6502Translator oTranslator( oCode );
  738. string o6502Code = oTranslator.Translate();
  739. fprintf(stdout, "%s", o6502Code.c_str());
  740. return nRetCode;
  741. }