Advertisement
Guest User

Untitled

a guest
Feb 20th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 75.61 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <winsock2.h>
  3.  
  4. #pragma comment(lib, "wsock32.lib")
  5.  
  6. #define STUDENT_NUMBER    "17043938"
  7. #define IP_ADDRESS_SERVER "127.0.0.1"
  8.  
  9. #define PORT_SERVER 0x1984 //We define a port that we are going to use.
  10. #define PORT_CLIENT 0x1985 //We define a port that we are going to use.
  11.  
  12. #define WORD  unsigned short
  13. #define DWORD unsigned long
  14. #define BYTE  unsigned char
  15.  
  16. #define MAX_FILENAME_SIZE 500
  17. #define MAX_BUFFER_SIZE   500
  18.  
  19. SOCKADDR_IN server_addr;
  20. SOCKADDR_IN client_addr;
  21.  
  22. SOCKET sock; //This is our socket, it is the handle to the IO address to read/write packets
  23.  
  24. WSADATA data;
  25.  
  26. char InputBuffer [MAX_BUFFER_SIZE];
  27. char hex_file [MAX_BUFFER_SIZE];
  28. char trc_file [MAX_BUFFER_SIZE];
  29.  
  30. //Any mathematical/logical instructions set the flags
  31. //Any conditional jump or return reads the value from flags
  32.  
  33. //C = carry flag, Z = zero flag, N = negative flag, I = interrupt flag, O = overflow flag
  34. //Zero flag = 1 if result of mathematical or logical operation = 0, or it is set to 0
  35. //Carry flag = 1 if addition result > 8 bits, or when a borrow is used in subtraction, otherwise it is set to 0
  36. //Negative flag = 1 if the MSB of the result = 1, or 0
  37. //Interrupt flag is used to enable/disable interrupts
  38. //Overflow flag = 1 if there is an overflow or borrow on the MSB. Important when signed binary arithmetic is being used.
  39. //16-bit WORDs can be used if the result of an operation is > 8 bits.
  40.  
  41. //////////////////////////
  42. //      Registers       //
  43. //////////////////////////
  44.  
  45. #define FLAG_I  0x10
  46. #define FLAG_V  0x08
  47. #define FLAG_N  0x04
  48. #define FLAG_Z  0x02
  49. #define FLAG_C  0x01
  50. #define REGISTER_A  5
  51. #define REGISTER_F  4
  52. #define REGISTER_E  3
  53. #define REGISTER_D  2
  54. #define REGISTER_C  1
  55. #define REGISTER_B  0
  56. #define REGISTER_X 0
  57. #define REGISTER_Y 1
  58. BYTE Index_Registers[2];
  59.  
  60. BYTE Registers[6];
  61. BYTE Flags;
  62. WORD ProgramCounter;
  63. WORD StackPointer;
  64.  
  65. ////////////
  66. // Memory //
  67. ////////////
  68.  
  69. #define MEMORY_SIZE 65536
  70.  
  71. BYTE Memory[MEMORY_SIZE];
  72.  
  73. #define TEST_ADDRESS_1  0x01FA
  74. #define TEST_ADDRESS_2  0x01FB
  75. #define TEST_ADDRESS_3  0x01FC
  76. #define TEST_ADDRESS_4  0x01FD
  77. #define TEST_ADDRESS_5  0x01FE
  78. #define TEST_ADDRESS_6  0x01FF
  79. #define TEST_ADDRESS_7  0x0200
  80. #define TEST_ADDRESS_8  0x0201
  81. #define TEST_ADDRESS_9  0x0202
  82. #define TEST_ADDRESS_10  0x0203
  83. #define TEST_ADDRESS_11  0x0204
  84. #define TEST_ADDRESS_12  0x0205
  85.  
  86. ///////////////////////
  87. // Control variables //
  88. ///////////////////////
  89.  
  90. bool memory_in_range = true;
  91. bool halt = false;
  92.  
  93. ///////////////////////
  94. // Disassembly table //
  95. ///////////////////////
  96.  
  97. char opcode_mneumonics[][14] = {
  98. "ILLEGAL     ",
  99. "ILLEGAL     ",
  100. "STX abs      ",
  101. "ILLEGAL     ",
  102. "ILLEGAL     ",
  103. "ILLEGAL     ",
  104. "ILLEGAL     ",
  105. "MV  #,B      ",
  106. "MV  #,C      ",
  107. "MV  #,D      ",
  108. "MV  #,E      ",
  109. "MV  #,F      ",
  110. "MAY impl     ",
  111. "MYA impl     ",
  112. "MAS impl     ",
  113. "CSA impl     ",
  114.  
  115. "ILLEGAL     ",
  116. "ILLEGAL     ",
  117. "STX abs,X    ",
  118. "ILLEGAL     ",
  119. "ILLEGAL     ",
  120. "ILLEGAL     ",
  121. "SWI impl     ",
  122. "RTI impl     ",
  123. "CLC impl     ",
  124. "SEC impl     ",
  125. "CLI impl     ",
  126. "STI impl     ",
  127. "STV impl     ",
  128. "CLV impl     ",
  129. "ILLEGAL     ",
  130. "ILLEGAL     ",
  131.  
  132. "ILLEGAL     ",
  133. "ILLEGAL     ",
  134. "STX abs,Y    ",
  135. "ADD A,B      ",
  136. "SUB A,B      ",
  137. "CMP A,B      ",
  138. "OR A,B       ",
  139. "AND A,B      ",
  140. "EOR A,B      ",
  141. "BT A,B       ",
  142. "LD A,A       ",
  143. "LD B,A       ",
  144. "LD C,A       ",
  145. "LD D,A       ",
  146. "LD E,A       ",
  147. "LD F,A       ",
  148.  
  149. "ILLEGAL     ",
  150. "LDX  #       ",
  151. "STX abs,XY   ",
  152. "ADD A,C      ",
  153. "SUB A,C      ",
  154. "CMP A,C      ",
  155. "OR A,C       ",
  156. "AND A,C      ",
  157. "EOR A,C      ",
  158. "BT A,C       ",
  159. "LD A,B       ",
  160. "LD B,B       ",
  161. "LD C,B       ",
  162. "LD D,B       ",
  163. "LD E,B       ",
  164. "LD F,B       ",
  165.  
  166. "ILLEGAL     ",
  167. "LDX abs      ",
  168. "STX (ind),XY ",
  169. "ADD A,D      ",
  170. "SUB A,D      ",
  171. "CMP A,D      ",
  172. "OR A,D       ",
  173. "AND A,D      ",
  174. "EOR A,D      ",
  175. "BT A,D       ",
  176. "LD A,C       ",
  177. "LD B,C       ",
  178. "LD C,C       ",
  179. "LD D,C       ",
  180. "LD E,C       ",
  181. "LD F,C       ",
  182.  
  183. "ILLEGAL     ",
  184. "LDX abs,X    ",
  185. "ILLEGAL     ",
  186. "ADD A,E      ",
  187. "SUB A,E      ",
  188. "CMP A,E      ",
  189. "OR A,E       ",
  190. "AND A,E      ",
  191. "EOR A,E      ",
  192. "BT A,E       ",
  193. "LD A,D       ",
  194. "LD B,D       ",
  195. "LD C,D       ",
  196. "LD D,D       ",
  197. "LD E,D       ",
  198. "LD F,D       ",
  199.  
  200. "ILLEGAL     ",
  201. "LDX abs,Y    ",
  202. "ILLEGAL     ",
  203. "ADD A,F      ",
  204. "SUB A,F      ",
  205. "CMP A,F      ",
  206. "OR A,F       ",
  207. "AND A,F      ",
  208. "EOR A,F      ",
  209. "BT A,F       ",
  210. "LD A,E       ",
  211. "LD B,E       ",
  212. "LD C,E       ",
  213. "LD D,E       ",
  214. "LD E,E       ",
  215. "LD F,E       ",
  216.  
  217. "ILLEGAL     ",
  218. "LDX abs,XY   ",
  219. "ILLEGAL     ",
  220. "NOP impl     ",
  221. "HLT impl     ",
  222. "ILLEGAL     ",
  223. "ILLEGAL     ",
  224. "ILLEGAL     ",
  225. "ILLEGAL     ",
  226. "ILLEGAL     ",
  227. "LD A,F       ",
  228. "LD B,F       ",
  229. "LD C,F       ",
  230. "LD D,F       ",
  231. "LD E,F       ",
  232. "LD F,F       ",
  233.  
  234. "ILLEGAL     ",
  235. "LDX (ind),XY ",
  236. "ADI  #       ",
  237. "SBI  #       ",
  238. "CPI  #       ",
  239. "ORI  #       ",
  240. "ANI  #       ",
  241. "XRI  #       ",
  242. "ILLEGAL     ",
  243. "ILLEGAL     ",
  244. "ILLEGAL     ",
  245. "ILLEGAL     ",
  246. "ILLEGAL     ",
  247. "ILLEGAL     ",
  248. "ILLEGAL     ",
  249. "ILLEGAL     ",
  250.  
  251. "LDA  #       ",
  252. "TST abs      ",
  253. "INC abs      ",
  254. "DEC abs      ",
  255. "RCR abs      ",
  256. "RLC abs      ",
  257. "ASL abs      ",
  258. "SAR abs      ",
  259. "COM abs      ",
  260. "RAL abs      ",
  261. "ROR abs      ",
  262. "LX  #,A      ",
  263. "ILLEGAL     ",
  264. "LODS  #      ",
  265. "PUSH  ,A     ",
  266. "POP A,       ",
  267.  
  268. "LDA abs      ",
  269. "TST abs,X    ",
  270. "INC abs,X    ",
  271. "DEC abs,X    ",
  272. "RCR abs,X    ",
  273. "RLC abs,X    ",
  274. "ASL abs,X    ",
  275. "SAR abs,X    ",
  276. "COM abs,X    ",
  277. "RAL abs,X    ",
  278. "ROR abs,X    ",
  279. "ILLEGAL     ",
  280. "STO abs      ",
  281. "LODS abs     ",
  282. "PUSH  ,s     ",
  283. "POP s,       ",
  284.  
  285. "LDA abs,X    ",
  286. "TST abs,Y    ",
  287. "INC abs,Y    ",
  288. "DEC abs,Y    ",
  289. "RCR abs,Y    ",
  290. "RLC abs,Y    ",
  291. "ASL abs,Y    ",
  292. "SAR abs,Y    ",
  293. "COM abs,Y    ",
  294. "RAL abs,Y    ",
  295. "ROR abs,Y    ",
  296. "ILLEGAL     ",
  297. "STO abs,X    ",
  298. "LODS abs,X   ",
  299. "PUSH  ,B     ",
  300. "POP B,       ",
  301.  
  302. "LDA abs,Y    ",
  303. "TST abs,XY   ",
  304. "INC abs,XY   ",
  305. "DEC abs,XY   ",
  306. "RCR abs,XY   ",
  307. "RLC abs,XY   ",
  308. "ASL abs,XY   ",
  309. "SAR abs,XY   ",
  310. "COM abs,XY   ",
  311. "RAL abs,XY   ",
  312. "ROR abs,XY   ",
  313. "ILLEGAL     ",
  314. "STO abs,Y    ",
  315. "LODS abs,Y   ",
  316. "PUSH  ,C     ",
  317. "POP C,       ",
  318.  
  319. "LDA abs,XY   ",
  320. "TSTA A,A     ",
  321. "INCA A,A     ",
  322. "DECA A,A     ",
  323. "RCRA A,A     ",
  324. "RLCA A,A     ",
  325. "ASLA A,A     ",
  326. "SARA A,A     ",
  327. "COMA A,A     ",
  328. "RALA A,A     ",
  329. "RORA A,A     ",
  330. "RTN impl     ",
  331. "STO abs,XY   ",
  332. "LODS abs,XY  ",
  333. "PUSH  ,D     ",
  334. "POP D,       ",
  335.  
  336. "LDA (ind),XY ",
  337. "DEX impl     ",
  338. "INX impl     ",
  339. "DEY impl     ",
  340. "INCY impl    ",
  341. "ILLEGAL     ",
  342. "ILLEGAL     ",
  343. "ILLEGAL     ",
  344. "ILLEGAL     ",
  345. "JSR abs      ",
  346. "JMP abs      ",
  347. "ILLEGAL     ",
  348. "STO (ind),XY ",
  349. "LODS (ind),XY",
  350. "PUSH  ,E     ",
  351. "POP E,       ",
  352.  
  353. "BRA rel      ",
  354. "BCC rel      ",
  355. "BCS rel      ",
  356. "BNE rel      ",
  357. "BEQ rel      ",
  358. "BVC rel      ",
  359. "BVS rel      ",
  360. "BMI rel      ",
  361. "BPL rel      ",
  362. "BGE rel      ",
  363. "BLE rel      ",
  364. "BGT rel      ",
  365. "BLT rel      ",
  366. "ILLEGAL     ",
  367. "PUSH  ,F     ",
  368. "POP F,       ",
  369. };
  370.  
  371. ////////////////////////////////////////////////////////////////////////////////
  372. //                              Emulator (Start)                              //
  373. ////////////////////////////////////////////////////////////////////////////////
  374.  
  375. BYTE fetch() { //returns value in memory
  376.     BYTE b = 0;
  377.    
  378.     if ((ProgramCounter >= 0) && (ProgramCounter <= MEMORY_SIZE)) {
  379.         memory_in_range = true;
  380.         b = Memory[ProgramCounter];
  381.         ProgramCounter++;
  382.     } else memory_in_range = false;
  383.  
  384.     return b;
  385. }
  386.  
  387. //functions for setting flags (C set manually)
  388. void set_flag_v(BYTE in1, BYTE in2, BYTE out) {
  389.     if ((((in1 & 0x80) == 0x80) && ((in2 & 0x80) == 0x80) && ((out & 0x80) != 0x80)) //overflow
  390.         || (((in1 & 0x80) != 0x80) && ((in2 & 0x80) != 0x80) && ((out & 0x80) == 0x80))) //overflow
  391.     {
  392.         Flags = Flags | FLAG_V;
  393.     }
  394.     else Flags = Flags & (0xFF - FLAG_V);
  395. }
  396. void set_flag_n(BYTE inReg) {
  397.     if ((inReg & 0x80) != 0) Flags = Flags | FLAG_N;
  398.     else Flags = Flags & (0xFF - FLAG_N);
  399. }
  400. void set_flag_z(BYTE inReg) {
  401.     if (inReg == 0) Flags = Flags | FLAG_Z;
  402.     else Flags = Flags & (0xFF - FLAG_Z);
  403. }
  404.  
  405. //functions that return the address for different addressing modes
  406. WORD address_abs() {
  407.     BYTE HB = fetch();
  408.     BYTE LB = fetch();
  409.     WORD address = (WORD)((WORD)HB << 8) + LB;
  410.     return address;
  411. }
  412. WORD address_absX() {
  413.     BYTE HB = fetch();
  414.     BYTE LB = fetch();
  415.     WORD address = Index_Registers[REGISTER_X];
  416.     address += (WORD)((WORD)HB << 8) + LB;
  417.     return address;
  418. }
  419. WORD address_absY() {
  420.     BYTE HB = fetch();
  421.     BYTE LB = fetch();
  422.     WORD address = Index_Registers[REGISTER_Y];
  423.     address += (WORD)((WORD)HB << 8) + LB;
  424.     return address;
  425. }
  426. WORD address_absXY() {
  427.     BYTE HB = fetch();
  428.     BYTE LB = fetch();
  429.     WORD address = (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
  430.     address += (WORD)((WORD)HB << 8) + LB;
  431.     return address;
  432. }
  433. WORD address_indXY() {
  434.     BYTE HB = fetch();
  435.     BYTE LB = fetch();
  436.     WORD address = (WORD)((WORD)HB << 8) + LB;
  437.     HB = Memory[address];
  438.     LB = Memory[address + 1];
  439.     address = (WORD)((WORD)HB << 8) + LB;
  440.     address += Index_Registers[REGISTER_X] + (WORD)((WORD)Index_Registers[REGISTER_Y] << 8);
  441.     return address;
  442. }
  443.  
  444. void Group_1(BYTE opcode) {
  445.     BYTE LB = 0, HB = 0, flagThing = 0;
  446.     WORD address = 0;
  447.     WORD data = 0;
  448.     WORD temp_word = 0;
  449.     WORD offset = 0;
  450.  
  451.     switch (opcode) {
  452.         ////////////////////////////////////////////////// NOP (no operation) //////////////////////////////////////////////////
  453.         case 0x73: //NOP impl
  454.             //nothing
  455.             break;
  456.         ////////////////////////////////////////////////// HLT (wait for interrupt) //////////////////////////////////////////////////
  457.         case 0x74: //HLT impl
  458.             halt = true;
  459.             break;
  460.         ////////////////////////////////////////////////// LDA (loads memory into accumulator) //////////////////////////////////////////////////
  461.         case 0x90: //LDA #
  462.             data = fetch();
  463.             Registers[REGISTER_A] = data;
  464.  
  465.             set_flag_n((BYTE)Registers[REGISTER_A]);
  466.             set_flag_z((BYTE)Registers[REGISTER_A]);
  467.             break;
  468.         case 0xA0: //LDA abs
  469.             address = address_abs();
  470.  
  471.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_A] = Memory[address];
  472.  
  473.             set_flag_n((BYTE)Registers[REGISTER_A]);
  474.             set_flag_z((BYTE)Registers[REGISTER_A]);
  475.             break;
  476.         case 0xB0: //LDA abs,X
  477.             address = address_absX();
  478.  
  479.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_A] = Memory[address];
  480.  
  481.             set_flag_n((BYTE)Registers[REGISTER_A]);
  482.             set_flag_z((BYTE)Registers[REGISTER_A]);
  483.             break;
  484.         case 0xC0: //LDA abs,Y
  485.             address = address_absY();
  486.  
  487.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_A] = Memory[address];
  488.  
  489.             set_flag_n((BYTE)Registers[REGISTER_A]);
  490.             set_flag_z((BYTE)Registers[REGISTER_A]);
  491.             break;
  492.         case 0xD0: //LDA abs,XY
  493.             address = address_absXY();
  494.  
  495.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_A] = Memory[address];
  496.  
  497.             set_flag_n((BYTE)Registers[REGISTER_A]);
  498.             set_flag_z((BYTE)Registers[REGISTER_A]);
  499.             break;
  500.         case 0xE0: //LDA (ind),XY
  501.             address = address_indXY();
  502.            
  503.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_A] = Memory[address];
  504.  
  505.             set_flag_n((BYTE)Registers[REGISTER_A]);
  506.             set_flag_z((BYTE)Registers[REGISTER_A]);
  507.             break;
  508.         ////////////////////////////////////////////////// STO (stores accumulator into memory) //////////////////////////////////////////////////
  509.         case 0xAC: //STO abs
  510.             address = address_abs();
  511.  
  512.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_A];
  513.  
  514.             set_flag_n((BYTE)Registers[REGISTER_A]);
  515.             set_flag_z((BYTE)Registers[REGISTER_A]);
  516.             break;
  517.         case 0xBC: //STO abs,X
  518.             address = address_absX();
  519.  
  520.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_A];
  521.  
  522.             set_flag_n((BYTE)Registers[REGISTER_A]);
  523.             set_flag_z((BYTE)Registers[REGISTER_A]);
  524.             break;
  525.         case 0xCC: //STO abs,Y
  526.             address = address_absY();
  527.  
  528.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_A];
  529.  
  530.             set_flag_n((BYTE)Registers[REGISTER_A]);
  531.             set_flag_z((BYTE)Registers[REGISTER_A]);
  532.             break;
  533.         case 0xDC: //STO abs,XY
  534.             address = address_absXY();
  535.  
  536.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_A];
  537.  
  538.             set_flag_n((BYTE)Registers[REGISTER_A]);
  539.             set_flag_z((BYTE)Registers[REGISTER_A]);
  540.             break;
  541.         case 0xEC: //STO (ind),XY
  542.             address = address_indXY();
  543.  
  544.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_A];
  545.  
  546.             set_flag_n((BYTE)Registers[REGISTER_A]);
  547.             set_flag_z((BYTE)Registers[REGISTER_A]);
  548.             break;
  549.         ////////////////////////////////////////////////// MV (loads memory into register) //////////////////////////////////////////////////
  550.         case 0x07: //MV B,#
  551.             data = fetch();
  552.             Registers[REGISTER_B] = data;
  553.  
  554.             set_flag_n((BYTE)Registers[REGISTER_B]);
  555.             set_flag_z((BYTE)Registers[REGISTER_B]);
  556.             break;
  557.         case 0x08: //MV C,#
  558.             data = fetch();
  559.             Registers[REGISTER_C] = data;
  560.  
  561.             set_flag_n((BYTE)Registers[REGISTER_C]);
  562.             set_flag_z((BYTE)Registers[REGISTER_C]);
  563.             break;
  564.         case 0x09: //MV D,#
  565.             data = fetch();
  566.             Registers[REGISTER_D] = data;
  567.  
  568.             set_flag_n((BYTE)Registers[REGISTER_D]);
  569.             set_flag_z((BYTE)Registers[REGISTER_D]);
  570.             break;
  571.         case 0x0A: //MV E,#
  572.             data = fetch();
  573.             Registers[REGISTER_E] = data;
  574.  
  575.             set_flag_n((BYTE)Registers[REGISTER_E]);
  576.             set_flag_z((BYTE)Registers[REGISTER_E]);
  577.             break;
  578.         case 0x0B: //MV F,#
  579.             data = fetch();
  580.             Registers[REGISTER_F] = data;
  581.  
  582.             set_flag_n((BYTE)Registers[REGISTER_F]);
  583.             set_flag_z((BYTE)Registers[REGISTER_F]);
  584.             break;
  585.         ////////////////////////////////////////////////// LODS (loads memory into stackpointer) //////////////////////////////////////////////////
  586.         case 0x9D: //LODS #
  587.             data = fetch();
  588.             StackPointer = data << 8;
  589.             StackPointer += fetch();
  590.  
  591.             set_flag_n((BYTE)StackPointer);
  592.             set_flag_z((BYTE)StackPointer);
  593.             break;
  594.         case 0xAD: //LODS abs
  595.             address = address_abs();
  596.  
  597.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  598.                 StackPointer = (WORD)Memory[address] << 8;
  599.                 StackPointer += Memory[address + 1];
  600.             }
  601.  
  602.             set_flag_n((BYTE)StackPointer);
  603.             set_flag_z((BYTE)StackPointer);
  604.             break;
  605.         case 0xBD: //LODS abs,X
  606.             address = address_absX();
  607.  
  608.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  609.                 StackPointer = (WORD)Memory[address] << 8;
  610.                 StackPointer += Memory[address + 1];
  611.             }
  612.  
  613.             set_flag_n((BYTE)StackPointer);
  614.             set_flag_z((BYTE)StackPointer);
  615.             break;
  616.         case 0xCD: //LODS abs,Y
  617.             address = address_absY();
  618.  
  619.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  620.                 StackPointer = (WORD)Memory[address] << 8;
  621.                 StackPointer += Memory[address + 1];
  622.             }
  623.  
  624.             set_flag_n((BYTE)StackPointer);
  625.             set_flag_z((BYTE)StackPointer);
  626.             break;
  627.         case 0xDD: //LODS abs,XY
  628.             address = address_absXY();
  629.  
  630.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  631.                 StackPointer = (WORD)Memory[address] << 8;
  632.                 StackPointer += Memory[address + 1];
  633.             }
  634.  
  635.             set_flag_n((BYTE)StackPointer);
  636.             set_flag_z((BYTE)StackPointer);
  637.             break;
  638.         case 0xED: //LODS (ind),XY
  639.             address = address_indXY();
  640.  
  641.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  642.                 StackPointer = (WORD)Memory[address] << 8;
  643.                 StackPointer += Memory[address + 1];
  644.             }
  645.  
  646.             set_flag_n((BYTE)StackPointer);
  647.             set_flag_z((BYTE)StackPointer);
  648.             break;
  649.         ////////////////////////////////////////////////// ADD (register added to accumulator with carry) //////////////////////////////////////////////////
  650.         case 0x23: //ADD A,B
  651.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
  652.             if ((Flags & FLAG_C) != 0) temp_word++;
  653.            
  654.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_B], (BYTE)temp_word);
  655.             set_flag_n((BYTE)temp_word);
  656.             set_flag_z((BYTE)temp_word);
  657.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  658.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  659.  
  660.             Registers[REGISTER_A] = (BYTE)temp_word;
  661.             break;
  662.         case 0x33: //ADD A,C
  663.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
  664.             if ((Flags & FLAG_C) != 0) temp_word++;
  665.            
  666.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_C], (BYTE)temp_word);
  667.             set_flag_n((BYTE)temp_word);
  668.             set_flag_z((BYTE)temp_word);
  669.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  670.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  671.  
  672.             Registers[REGISTER_A] = (BYTE)temp_word;
  673.             break;
  674.         case 0x43: //ADD A,D
  675.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_D];
  676.             if ((Flags & FLAG_C) != 0) temp_word++;
  677.  
  678.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_D], (BYTE)temp_word);
  679.             set_flag_n((BYTE)temp_word);
  680.             set_flag_z((BYTE)temp_word);
  681.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  682.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  683.  
  684.             Registers[REGISTER_A] = (BYTE)temp_word;
  685.             break;
  686.         case 0x53: //ADD A,E
  687.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_E];
  688.             if ((Flags & FLAG_C) != 0) temp_word++;
  689.  
  690.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_E], (BYTE)temp_word);
  691.             set_flag_n((BYTE)temp_word);
  692.             set_flag_z((BYTE)temp_word);
  693.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  694.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  695.  
  696.             Registers[REGISTER_A] = (BYTE)temp_word;
  697.             break;
  698.         case 0x63: //ADD A,F
  699.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_F];
  700.             if ((Flags & FLAG_C) != 0) temp_word++;
  701.  
  702.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_F], (BYTE)temp_word);
  703.             set_flag_n((BYTE)temp_word);
  704.             set_flag_z((BYTE)temp_word);
  705.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  706.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  707.  
  708.             Registers[REGISTER_A] = (BYTE)temp_word;
  709.             break;
  710.         ////////////////////////////////////////////////// SUB (register subtracted to accumulator with carry) //////////////////////////////////////////////////
  711.         case 0x24: //SUB A,B
  712.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
  713.             if ((Flags & FLAG_C) != 0) temp_word--;
  714.  
  715.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_B]), (BYTE)temp_word);
  716.             set_flag_n((BYTE)temp_word);
  717.             set_flag_z((BYTE)temp_word);
  718.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  719.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  720.  
  721.             Registers[REGISTER_A] = (BYTE)temp_word;
  722.             break;
  723.         case 0x34: //SUB A,C
  724.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
  725.             if ((Flags & FLAG_C) != 0) temp_word--;
  726.  
  727.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_C]), (BYTE)temp_word);
  728.             set_flag_n((BYTE)temp_word);
  729.             set_flag_z((BYTE)temp_word);
  730.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  731.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  732.  
  733.             Registers[REGISTER_A] = (BYTE)temp_word;
  734.             break;
  735.         case 0x44: //SUB A,D
  736.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
  737.             if ((Flags & FLAG_C) != 0) temp_word--;
  738.  
  739.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_D]), (BYTE)temp_word);
  740.             set_flag_n((BYTE)temp_word);
  741.             set_flag_z((BYTE)temp_word);
  742.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  743.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  744.  
  745.             Registers[REGISTER_A] = (BYTE)temp_word;
  746.             break;
  747.         case 0x54: //SUB A,E
  748.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
  749.             if ((Flags & FLAG_C) != 0) temp_word--;
  750.  
  751.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_E]), (BYTE)temp_word);
  752.             set_flag_n((BYTE)temp_word);
  753.             set_flag_z((BYTE)temp_word);
  754.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  755.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  756.  
  757.             Registers[REGISTER_A] = (BYTE)temp_word;
  758.             break;
  759.         case 0x64: //SUB A,F
  760.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_F];
  761.             if ((Flags & FLAG_C) != 0) temp_word--;
  762.  
  763.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_F]), (BYTE)temp_word);
  764.             set_flag_n((BYTE)temp_word);
  765.             set_flag_z((BYTE)temp_word);
  766.             if (temp_word >= 0x100) Flags = Flags | FLAG_C; //set carry flag
  767.             else Flags = Flags & (0xFF - FLAG_C); //clear carry flag
  768.  
  769.             Registers[REGISTER_A] = (BYTE)temp_word;
  770.             break;
  771.         ////////////////////////////////////////////////// ADI (data added to accumulator with carry) //////////////////////////////////////////////////
  772.         case 0x82: //ADI #
  773.             data = fetch();
  774.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)data;
  775.             if ((Flags & FLAG_C) != 0) temp_word++;
  776.            
  777.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)data, (BYTE)temp_word);
  778.             set_flag_n((BYTE)Registers[REGISTER_A]);
  779.             set_flag_z((BYTE)Registers[REGISTER_A]);
  780.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  781.             else Flags = Flags & (0xFF - FLAG_C);
  782.  
  783.             Registers[REGISTER_A] = (BYTE)temp_word;
  784.             break;
  785.         ////////////////////////////////////////////////// SBI (data subtracted to accumulator with carry) //////////////////////////////////////////////////
  786.         case 0x83: //SBI #
  787.             data = fetch();
  788.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)data;
  789.             if ((Flags & FLAG_C) != 0) temp_word--;
  790.  
  791.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-data), (BYTE)temp_word);
  792.             set_flag_n((BYTE)temp_word);
  793.             set_flag_z((BYTE)temp_word);
  794.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  795.             else Flags = Flags & (0xFF - FLAG_C);
  796.  
  797.             Registers[REGISTER_A] = (BYTE)temp_word;
  798.             break;
  799.         ////////////////////////////////////////////////// AND (register bitwise AND with accumulator) //////////////////////////////////////////////////
  800.         case 0x27: //AND A,B
  801.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
  802.            
  803.             set_flag_n((BYTE)temp_word);
  804.             set_flag_z((BYTE)temp_word);
  805.  
  806.             Registers[REGISTER_A] = (BYTE)temp_word;
  807.             break;
  808.         case 0x37: //AND A,C
  809.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
  810.  
  811.             set_flag_n((BYTE)temp_word);
  812.             set_flag_z((BYTE)temp_word);
  813.  
  814.             Registers[REGISTER_A] = (BYTE)temp_word;
  815.             break;
  816.         case 0x47: //AND A,D
  817.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_D];
  818.  
  819.             set_flag_n((BYTE)temp_word);
  820.             set_flag_z((BYTE)temp_word);
  821.  
  822.             Registers[REGISTER_A] = (BYTE)temp_word;
  823.             break;
  824.         case 0x57: //AND A,E
  825.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_E];
  826.  
  827.             set_flag_n((BYTE)temp_word);
  828.             set_flag_z((BYTE)temp_word);
  829.  
  830.             Registers[REGISTER_A] = (BYTE)temp_word;
  831.             break;
  832.         case 0x67: //AND A,F
  833.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_F];
  834.  
  835.             set_flag_n((BYTE)temp_word);
  836.             set_flag_z((BYTE)temp_word);
  837.  
  838.             Registers[REGISTER_A] = (BYTE)temp_word;
  839.             break;
  840.         ////////////////////////////////////////////////// OR (register bitwise OR with accumulator) //////////////////////////////////////////////////
  841.         case 0x26: //OR A,B
  842.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_B];
  843.  
  844.             set_flag_n((BYTE)temp_word);
  845.             set_flag_z((BYTE)temp_word);
  846.  
  847.             Registers[REGISTER_A] = (BYTE)temp_word;
  848.             break;
  849.         case 0x36: //OR A,C
  850.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_C];
  851.  
  852.             set_flag_n((BYTE)temp_word);
  853.             set_flag_z((BYTE)temp_word);
  854.  
  855.             Registers[REGISTER_A] = (BYTE)temp_word;
  856.             break;
  857.         case 0x46: //OR A,D
  858.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_D];
  859.  
  860.             set_flag_n((BYTE)temp_word);
  861.             set_flag_z((BYTE)temp_word);
  862.  
  863.             Registers[REGISTER_A] = (BYTE)temp_word;
  864.             break;
  865.         case 0x56: //OR A,E
  866.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_E];
  867.  
  868.             set_flag_n((BYTE)temp_word);
  869.             set_flag_z((BYTE)temp_word);
  870.  
  871.             Registers[REGISTER_A] = (BYTE)temp_word;
  872.             break;
  873.         case 0x66: //OR A,F
  874.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_F];
  875.  
  876.             set_flag_n((BYTE)temp_word);
  877.             set_flag_z((BYTE)temp_word);
  878.  
  879.             Registers[REGISTER_A] = (BYTE)temp_word;
  880.             break;
  881.         ////////////////////////////////////////////////// EOR (register bitwise XOR with accumulator) //////////////////////////////////////////////////
  882.         case 0x28: //EOR A,B
  883.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_B];
  884.  
  885.             set_flag_n((BYTE)temp_word);
  886.             set_flag_z((BYTE)temp_word);
  887.  
  888.             Registers[REGISTER_A] = (BYTE)temp_word;
  889.             break;
  890.         case 0x38: //EOR A,C
  891.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_C];
  892.  
  893.             set_flag_n((BYTE)temp_word);
  894.             set_flag_z((BYTE)temp_word);
  895.  
  896.             Registers[REGISTER_A] = (BYTE)temp_word;
  897.             break;
  898.         case 0x48: //EOR A,D
  899.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_D];
  900.  
  901.             set_flag_n((BYTE)temp_word);
  902.             set_flag_z((BYTE)temp_word);
  903.  
  904.             Registers[REGISTER_A] = (BYTE)temp_word;
  905.             break;
  906.         case 0x58: //EOR A,E
  907.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_E];
  908.  
  909.             set_flag_n((BYTE)temp_word);
  910.             set_flag_z((BYTE)temp_word);
  911.  
  912.             Registers[REGISTER_A] = (BYTE)temp_word;
  913.             break;
  914.         case 0x68: //EOR A,F
  915.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_F];
  916.  
  917.             set_flag_n((BYTE)temp_word);
  918.             set_flag_z((BYTE)temp_word);
  919.  
  920.             Registers[REGISTER_A] = (BYTE)temp_word;
  921.             break;
  922.         ////////////////////////////////////////////////// BT (register bit tested with accumulator) //////////////////////////////////////////////////
  923.         case 0x29: //BT A,B
  924.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
  925.  
  926.             set_flag_n((BYTE)temp_word);
  927.             set_flag_z((BYTE)temp_word);
  928.             break;
  929.         case 0x39: //BT A,C
  930.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
  931.  
  932.             set_flag_n((BYTE)temp_word);
  933.             set_flag_z((BYTE)temp_word);
  934.             break;
  935.         case 0x49: //BT A,D
  936.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_D];
  937.  
  938.             set_flag_n((BYTE)temp_word);
  939.             set_flag_z((BYTE)temp_word);
  940.             break;
  941.         case 0x59: //BT A,E
  942.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_E];
  943.  
  944.             set_flag_n((BYTE)temp_word);
  945.             set_flag_z((BYTE)temp_word);
  946.             break;
  947.         case 0x69: //BT A,F
  948.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_F];
  949.  
  950.             set_flag_n((BYTE)temp_word);
  951.             set_flag_z((BYTE)temp_word);
  952.             break;
  953.         ////////////////////////////////////////////////// CMP (register compared to accumulator) //////////////////////////////////////////////////
  954.         case 0x25: //CMP A,B
  955.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
  956.            
  957.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_B]), (BYTE)temp_word);
  958.             set_flag_n((BYTE)temp_word);
  959.             set_flag_z((BYTE)temp_word);
  960.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  961.             else Flags = Flags & (0xFF - FLAG_C);
  962.             break;
  963.         case 0x35: //CMP A,C
  964.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
  965.  
  966.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_C]), (BYTE)temp_word);
  967.             set_flag_n((BYTE)temp_word);
  968.             set_flag_z((BYTE)temp_word);
  969.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  970.             else Flags = Flags & (0xFF - FLAG_C);
  971.             break;
  972.         case 0x45: //CMP A,D
  973.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
  974.  
  975.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_D]), (BYTE)temp_word);
  976.             set_flag_n((BYTE)temp_word);
  977.             set_flag_z((BYTE)temp_word);
  978.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  979.             else Flags = Flags & (0xFF - FLAG_C);
  980.             break;
  981.         case 0x55: //CMP A,E
  982.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
  983.  
  984.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_E]), (BYTE)temp_word);
  985.             set_flag_n((BYTE)temp_word);
  986.             set_flag_z((BYTE)temp_word);
  987.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  988.             else Flags = Flags & (0xFF - FLAG_C);
  989.             break;
  990.         case 0x65: //CMP A,F
  991.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_F];
  992.  
  993.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_F]), (BYTE)temp_word);
  994.             set_flag_n((BYTE)temp_word);
  995.             set_flag_z((BYTE)temp_word);
  996.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  997.             else Flags = Flags & (0xFF - FLAG_C);
  998.             break;
  999.         ////////////////////////////////////////////////// CPI (data compared to accumulator) //////////////////////////////////////////////////
  1000.         case 0x84: //CPI #
  1001.             data = fetch();
  1002.             temp_word = (WORD)Registers[REGISTER_A] - data;
  1003.  
  1004.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-data), (BYTE)temp_word);
  1005.             set_flag_n((BYTE)temp_word);
  1006.             set_flag_z((BYTE)temp_word);
  1007.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1008.             else Flags = Flags & (0xFF - FLAG_C);
  1009.             break;
  1010.         ////////////////////////////////////////////////// ANI (data bitwise AND with accumulator) //////////////////////////////////////////////////
  1011.         case 0x86: //ANI #
  1012.             data = fetch();
  1013.             temp_word = (WORD)data & (WORD)Registers[REGISTER_A];
  1014.  
  1015.             set_flag_n((BYTE)temp_word);
  1016.             set_flag_z((BYTE)temp_word);
  1017.  
  1018.             Registers[REGISTER_A] = (BYTE)temp_word;
  1019.             break;
  1020.         ////////////////////////////////////////////////// ORI (data bitwise OR with accumulator) //////////////////////////////////////////////////
  1021.         case 0x85: //ORI #
  1022.             data = fetch();
  1023.             temp_word = (WORD)data | (WORD)Registers[REGISTER_A];
  1024.  
  1025.             set_flag_n((BYTE)temp_word);
  1026.             set_flag_z((BYTE)temp_word);
  1027.  
  1028.             Registers[REGISTER_A] = (BYTE)temp_word;
  1029.             break;
  1030.         ////////////////////////////////////////////////// XRI (data bitwise XOR with accumulator) //////////////////////////////////////////////////
  1031.         case 0x87: //XRI #
  1032.             data = fetch();
  1033.             temp_word = (WORD)data ^ (WORD)Registers[REGISTER_A];
  1034.  
  1035.             set_flag_n((BYTE)temp_word);
  1036.             set_flag_z((BYTE)temp_word);
  1037.  
  1038.             Registers[REGISTER_A] = (BYTE)temp_word;
  1039.             break;
  1040.         ////////////////////////////////////////////////// CSA (transfers status register to accumulator) //////////////////////////////////////////////////
  1041.         case 0x0F: //CSA impl
  1042.             Registers[REGISTER_A] = Flags;
  1043.             break;
  1044.         ////////////////////////////////////////////////// LDX (loads memory into register X) //////////////////////////////////////////////////
  1045.         case 0x31: //LDX #
  1046.             data = fetch();
  1047.             Registers[REGISTER_X] = data;
  1048.  
  1049.             set_flag_n((BYTE)Index_Registers[REGISTER_X]);
  1050.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1051.             break;
  1052.         case 0x41: //LDX abs
  1053.             address = address_abs();
  1054.  
  1055.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_X] = Memory[address];
  1056.  
  1057.             set_flag_n((BYTE)Index_Registers[REGISTER_X]);
  1058.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1059.             break;
  1060.         case 0x51: //LDX abs,X
  1061.             address = address_absX();
  1062.  
  1063.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_X] = Memory[address];
  1064.  
  1065.             set_flag_n((BYTE)Index_Registers[REGISTER_X]);
  1066.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1067.             break;
  1068.         case 0x61: //LDX abs,Y
  1069.             address = address_absY();
  1070.  
  1071.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_X] = Memory[address];
  1072.  
  1073.             set_flag_n((BYTE)Index_Registers[REGISTER_X]);
  1074.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1075.             break;
  1076.         case 0x71: //LDX abs,XY
  1077.             address = address_absXY();
  1078.  
  1079.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_X] = Memory[address];
  1080.  
  1081.             set_flag_n((BYTE)Index_Registers[REGISTER_X]);
  1082.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1083.             break;
  1084.         case 0x81: //LDX (ind),XY
  1085.             address = address_indXY();
  1086.  
  1087.             if (address >= 0 && address < MEMORY_SIZE) Registers[REGISTER_A] = Memory[address];
  1088.  
  1089.             set_flag_n((BYTE)Index_Registers[REGISTER_X]);
  1090.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1091.             break;
  1092.         ////////////////////////////////////////////////// STX (stores register X into memory) //////////////////////////////////////////////////
  1093.         case 0x02: //STX abs
  1094.             address = address_abs();
  1095.  
  1096.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_X];
  1097.  
  1098.             set_flag_n((BYTE)Registers[REGISTER_X]);
  1099.             set_flag_z((BYTE)Registers[REGISTER_X]);
  1100.             break;
  1101.         case 0x12: //STX abs,X
  1102.             address = address_absX();
  1103.  
  1104.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_X];
  1105.  
  1106.             set_flag_n((BYTE)Registers[REGISTER_X]);
  1107.             set_flag_z((BYTE)Registers[REGISTER_X]);
  1108.             break;
  1109.         case 0x22: //STX abs,Y
  1110.             address = address_absY();
  1111.  
  1112.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_X];
  1113.  
  1114.             set_flag_n((BYTE)Registers[REGISTER_X]);
  1115.             set_flag_z((BYTE)Registers[REGISTER_X]);
  1116.             break;
  1117.         case 0x32: //STX abs,XY
  1118.             address = address_absXY();
  1119.  
  1120.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_X];
  1121.  
  1122.             set_flag_n((BYTE)Registers[REGISTER_X]);
  1123.             set_flag_z((BYTE)Registers[REGISTER_X]);
  1124.             break;
  1125.         case 0x42: //STX (ind),XY
  1126.             address = address_indXY();
  1127.  
  1128.             if (address >= 0 && address < MEMORY_SIZE) Memory[address] = Registers[REGISTER_X];
  1129.  
  1130.             set_flag_n((BYTE)Registers[REGISTER_X]);
  1131.             set_flag_z((BYTE)Registers[REGISTER_X]);
  1132.             break;
  1133.         ////////////////////////////////////////////////// MAY (transfers accumulator into register Y) //////////////////////////////////////////////////
  1134.         case 0x0C: //MAY impl
  1135.             Index_Registers[REGISTER_Y] = Registers[REGISTER_A];
  1136.  
  1137.             set_flag_n((BYTE)Registers[REGISTER_A]);
  1138.             break;
  1139.         ////////////////////////////////////////////////// MYA (transfers register Y to accumulator) //////////////////////////////////////////////////
  1140.         case 0x0D: //MYA impl
  1141.             Registers[REGISTER_A] = Index_Registers[REGISTER_Y];
  1142.  
  1143.             set_flag_n((BYTE)Index_Registers[REGISTER_Y]);
  1144.             set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
  1145.             break;
  1146.         ////////////////////////////////////////////////// MAS (transfers accumulator to status register) //////////////////////////////////////////////////
  1147.         case 0x0E: //MAS impl
  1148.             Flags = Registers[REGISTER_A];
  1149.             break;
  1150.         ////////////////////////////////////////////////// INC (increment memory or accumulator) //////////////////////////////////////////////////
  1151.         case 0x92: //INC abs
  1152.             address = address_abs();
  1153.            
  1154.             if (address >= 0 && address < MEMORY_SIZE) Memory[address]++;
  1155.  
  1156.             set_flag_n((BYTE)Memory[address]);
  1157.             set_flag_z((BYTE)Memory[address]);
  1158.             break;
  1159.         case 0xA2: //INC abs,X
  1160.             address = address_absX();
  1161.  
  1162.             if (address >= 0 && address < MEMORY_SIZE) Memory[address]++;
  1163.  
  1164.             set_flag_n((BYTE)Memory[address]);
  1165.             set_flag_z((BYTE)Memory[address]);
  1166.             break;
  1167.         case 0xB2: //INC abs,Y
  1168.             address = address_absY();
  1169.  
  1170.             if (address >= 0 && address < MEMORY_SIZE) Memory[address]++;
  1171.  
  1172.             set_flag_n((BYTE)Memory[address]);
  1173.             set_flag_z((BYTE)Memory[address]);
  1174.             break;
  1175.         case 0xC2: //INC abs,XY
  1176.             address = address_absXY();
  1177.  
  1178.             if (address >= 0 && address < MEMORY_SIZE) Memory[address]++;
  1179.  
  1180.             set_flag_n((BYTE)Memory[address]);
  1181.             set_flag_z((BYTE)Memory[address]);
  1182.             break;
  1183.         ////////////////////////////////////////////////// DEC (decrement memory or accumulator) //////////////////////////////////////////////////
  1184.         case 0x93: //DEC abs
  1185.             address = address_abs();
  1186.  
  1187.             if (address >= 0 && address < MEMORY_SIZE) Memory[address]--;
  1188.  
  1189.             set_flag_n((BYTE)Memory[address]);
  1190.             set_flag_z((BYTE)Memory[address]);
  1191.             break;
  1192.         case 0xA3: //DEC abs,X
  1193.             address = address_absX();
  1194.  
  1195.             if (address >= 0 && address < MEMORY_SIZE) Memory[address]--;
  1196.  
  1197.             set_flag_n((BYTE)Memory[address]);
  1198.             set_flag_z((BYTE)Memory[address]);
  1199.             break;
  1200.         case 0xB3: //DEC abs,Y
  1201.             address = address_absY();
  1202.  
  1203.             if (address >= 0 && address < MEMORY_SIZE) Memory[address]--;
  1204.  
  1205.             set_flag_n((BYTE)Memory[address]);
  1206.             set_flag_z((BYTE)Memory[address]);
  1207.             break;
  1208.         case 0xC3: //DEC abs,XY
  1209.             address = address_absXY();
  1210.  
  1211.             if (address >= 0 && address < MEMORY_SIZE) Memory[address]--;
  1212.  
  1213.             set_flag_n((BYTE)Memory[address]);
  1214.             set_flag_z((BYTE)Memory[address]);
  1215.             break;
  1216.         ////////////////////////////////////////////////// TST (bit test memory or accumulator) //////////////////////////////////////////////////
  1217.         case 0x91: //TST abs
  1218.             address = address_abs();
  1219.  
  1220.             temp_word = (WORD)Memory[address];
  1221.             Memory[address] = (BYTE)temp_word;
  1222.  
  1223.             set_flag_n((BYTE)temp_word);
  1224.             set_flag_z((BYTE)temp_word);
  1225.             break;
  1226.         case 0xA1: //TST abs,X
  1227.             address = address_absX();
  1228.  
  1229.             temp_word = (WORD)Memory[address];
  1230.             Memory[address] = (BYTE)temp_word;
  1231.  
  1232.             set_flag_n((BYTE)temp_word);
  1233.             set_flag_z((BYTE)temp_word);
  1234.             break;
  1235.         case 0xB1: //TST abs,Y
  1236.             address = address_absY();
  1237.  
  1238.             temp_word = (WORD)Memory[address];
  1239.             Memory[address] = (BYTE)temp_word;
  1240.  
  1241.             set_flag_n((BYTE)temp_word);
  1242.             set_flag_z((BYTE)temp_word);
  1243.             break;
  1244.         case 0xC1: //TST abs,XY
  1245.             address = address_absXY();
  1246.  
  1247.             temp_word = (WORD)Memory[address];
  1248.             Memory[address] = (BYTE)temp_word;
  1249.  
  1250.             set_flag_n((BYTE)temp_word);
  1251.             set_flag_z((BYTE)temp_word);
  1252.             break;
  1253.         ////////////////////////////////////////////////// TSTA (bit test memory or accumulator) //////////////////////////////////////////////////
  1254.         case 0xD1: //TSTA A
  1255.             temp_word = (WORD)Registers[REGISTER_A];
  1256.  
  1257.             set_flag_n((BYTE)temp_word);
  1258.             set_flag_z((BYTE)temp_word);
  1259.  
  1260.             Registers[REGISTER_A] = (BYTE)temp_word;
  1261.             break;
  1262.         ////////////////////////////////////////////////// INCA (increment memory or accumulator) //////////////////////////////////////////////////
  1263.         case 0xD2: //INCA A
  1264.             Registers[REGISTER_A]++;
  1265.  
  1266.             set_flag_n((BYTE)Registers[REGISTER_A]);
  1267.             set_flag_z((BYTE)Registers[REGISTER_A]);
  1268.             break;
  1269.         ////////////////////////////////////////////////// DECA (decrement memory or accumulator) //////////////////////////////////////////////////
  1270.         case 0xD3: //DECA A
  1271.             Registers[REGISTER_A]--;
  1272.  
  1273.             set_flag_n((BYTE)Registers[REGISTER_A]);
  1274.             set_flag_z((BYTE)Registers[REGISTER_A]);
  1275.             break;
  1276.         ////////////////////////////////////////////////// INX (increment register X) //////////////////////////////////////////////////
  1277.         case 0xE2: //INX impl
  1278.             Index_Registers[REGISTER_X]++;
  1279.  
  1280.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1281.             break;
  1282.         ////////////////////////////////////////////////// DEX (decrement register X) //////////////////////////////////////////////////
  1283.         case 0xE1: //DEX impl
  1284.             Index_Registers[REGISTER_X]--;
  1285.  
  1286.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1287.             break;
  1288.         ////////////////////////////////////////////////// INCY (increment register Y) //////////////////////////////////////////////////
  1289.         case 0xE4: //INCY impl
  1290.             Index_Registers[REGISTER_Y]++;
  1291.  
  1292.             set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
  1293.             break;
  1294.         ////////////////////////////////////////////////// DEY (decrement register Y) //////////////////////////////////////////////////
  1295.         case 0xE3: //DEY impl
  1296.             Index_Registers[REGISTER_Y]--;
  1297.  
  1298.             set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
  1299.             break;
  1300.         ////////////////////////////////////////////////// ASL (arithmetic shift left memory or accumulator) //////////////////////////////////////////////////
  1301.         case 0x96: //ASL abs
  1302.             address = address_abs();
  1303.            
  1304.             temp_word = Memory[address] << 1;
  1305.             Memory[address] = (BYTE)temp_word;
  1306.  
  1307.             set_flag_n((BYTE)temp_word);
  1308.             set_flag_z((BYTE)temp_word);
  1309.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1310.             else Flags = Flags & (0xFF - FLAG_C);
  1311.             break;
  1312.         case 0xA6: //ASL abs,X
  1313.             address = address_absX();
  1314.  
  1315.             temp_word = Memory[address] << 1;
  1316.             Memory[address] = (BYTE)temp_word;
  1317.  
  1318.             set_flag_n((BYTE)temp_word);
  1319.             set_flag_z((BYTE)temp_word);
  1320.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1321.             else Flags = Flags & (0xFF - FLAG_C);
  1322.             break;
  1323.         case 0xB6: //ASL abs,Y
  1324.             address = address_absY();
  1325.  
  1326.             temp_word = Memory[address] << 1;
  1327.             Memory[address] = (BYTE)temp_word;
  1328.  
  1329.             set_flag_n((BYTE)temp_word);
  1330.             set_flag_z((BYTE)temp_word);
  1331.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1332.             else Flags = Flags & (0xFF - FLAG_C);
  1333.             break;
  1334.         case 0xC6: //ASL abs,XY
  1335.             address = address_absXY();
  1336.  
  1337.             temp_word = Memory[address] << 1;
  1338.             Memory[address] = (BYTE)temp_word;
  1339.  
  1340.             set_flag_n((BYTE)temp_word);
  1341.             set_flag_z((BYTE)temp_word);
  1342.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1343.             else Flags = Flags & (0xFF - FLAG_C);
  1344.             break;
  1345.         ////////////////////////////////////////////////// ASLA (arithmetic shift left memory or accumulator) //////////////////////////////////////////////////
  1346.         case 0xD6: //ASLA A
  1347.             temp_word = Registers[REGISTER_A] << 1;
  1348.             Registers[REGISTER_A] = (BYTE)temp_word;
  1349.  
  1350.             set_flag_n((BYTE)temp_word);
  1351.             set_flag_z((BYTE)temp_word);
  1352.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1353.             else Flags = Flags & (0xFF - FLAG_C);
  1354.             break;
  1355.         ////////////////////////////////////////////////// SAR (arithmetic shift right memory or accumulator) //////////////////////////////////////////////////
  1356.         case 0x97: //SAR abs
  1357.             address = address_abs();
  1358.  
  1359.             temp_word = Memory[address] >> 1;
  1360.             Memory[address] = (BYTE)temp_word;
  1361.  
  1362.             set_flag_n((BYTE)temp_word);
  1363.             set_flag_z((BYTE)temp_word);
  1364.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1365.             else Flags = Flags & (0xFF - FLAG_C);
  1366.             break;
  1367.         case 0xA7: //SAR abs,X
  1368.             address = address_absX();
  1369.            
  1370.             temp_word = Memory[address] >> 1;
  1371.             Memory[address] = (BYTE)temp_word;
  1372.  
  1373.             set_flag_n((BYTE)temp_word);
  1374.             set_flag_z((BYTE)temp_word);
  1375.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1376.             else Flags = Flags & (0xFF - FLAG_C);
  1377.             break;
  1378.         case 0xB7: //SAR abs,Y
  1379.             address = address_absY();
  1380.  
  1381.             temp_word = Memory[address] >> 1;
  1382.             Memory[address] = (BYTE)temp_word;
  1383.  
  1384.             set_flag_n((BYTE)temp_word);
  1385.             set_flag_z((BYTE)temp_word);
  1386.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1387.             else Flags = Flags & (0xFF - FLAG_C);
  1388.             break;
  1389.         case 0xC7: //SAR abs,XY
  1390.             address = address_absXY();
  1391.  
  1392.             temp_word = Memory[address] >> 1;
  1393.             Memory[address] = (BYTE)temp_word;
  1394.  
  1395.             set_flag_n((BYTE)temp_word);
  1396.             set_flag_z((BYTE)temp_word);
  1397.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1398.             else Flags = Flags & (0xFF - FLAG_C);
  1399.             break;
  1400.         ////////////////////////////////////////////////// SARA (arithmetic shift right memory or accumulator) //////////////////////////////////////////////////
  1401.         case 0xD7: //SARA A
  1402.             temp_word = Registers[REGISTER_A] >> 1;
  1403.  
  1404.             Registers[REGISTER_A] = (BYTE)temp_word;
  1405.  
  1406.             set_flag_n((BYTE)temp_word);
  1407.             set_flag_z((BYTE)temp_word);
  1408.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1409.             else Flags = Flags & (0xFF - FLAG_C);
  1410.             break;
  1411.         ////////////////////////////////////////////////// RCR (rotate right through carry memory or accumulator) //////////////////////////////////////////////////
  1412.         case 0x94: //RCR abs
  1413.             address = address_abs();
  1414.  
  1415.             if (address >= 0 && address < MEMORY_SIZE) {
  1416.                 flagThing = Flags;
  1417.                 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1418.                 else Flags = Flags & (0xFF - FLAG_C);
  1419.                
  1420.                 Memory[address] = (Memory[address] >> 1) & 0x7F;
  1421.                 if ((flagThing & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
  1422.             }
  1423.  
  1424.             set_flag_n((BYTE)Memory[address]);
  1425.             set_flag_z((BYTE)Memory[address]);
  1426.             break;
  1427.         case 0xA4: //RCR abs,X
  1428.             address = address_absX();
  1429.  
  1430.             if (address >= 0 && address < MEMORY_SIZE) {
  1431.                 flagThing = Flags;
  1432.                 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1433.                 else Flags = Flags & (0xFF - FLAG_C);
  1434.  
  1435.                 Memory[address] = (Memory[address] >> 1) & 0x7F;
  1436.                 if ((flagThing & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
  1437.             }
  1438.  
  1439.             set_flag_n((BYTE)Memory[address]);
  1440.             set_flag_z((BYTE)Memory[address]);
  1441.             break;
  1442.         case 0xB4: //RCR abs,Y
  1443.             address = address_absY();
  1444.  
  1445.             if (address >= 0 && address < MEMORY_SIZE) {
  1446.                 flagThing = Flags;
  1447.                 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1448.                 else Flags = Flags & (0xFF - FLAG_C);
  1449.  
  1450.                 Memory[address] = (Memory[address] >> 1) & 0x7F;
  1451.                 if ((flagThing & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
  1452.             }
  1453.  
  1454.             set_flag_n((BYTE)Memory[address]);
  1455.             set_flag_z((BYTE)Memory[address]);
  1456.             break;
  1457.         case 0xC4: //RCR abs,XY
  1458.             address = address_absXY();
  1459.  
  1460.             if (address >= 0 && address < MEMORY_SIZE) {
  1461.                 flagThing = Flags;
  1462.                 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1463.                 else Flags = Flags & (0xFF - FLAG_C);
  1464.  
  1465.                 Memory[address] = (Memory[address] >> 1) & 0x7F;
  1466.                 if ((flagThing & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
  1467.             }
  1468.  
  1469.             set_flag_n((BYTE)Memory[address]);
  1470.             set_flag_z((BYTE)Memory[address]);
  1471.             break;
  1472.         ////////////////////////////////////////////////// RCRA (rotate right through carry memory or accumulator) //////////////////////////////////////////////////
  1473.         case 0xD4: //RCRA A
  1474.             if ((Registers[REGISTER_A] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1475.             else Flags = Flags & (0xFF - FLAG_C);
  1476.  
  1477.             Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
  1478.             if ((Flags & FLAG_C) == FLAG_C) Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
  1479.            
  1480.             set_flag_n((BYTE)Registers[REGISTER_A]);
  1481.             set_flag_z((BYTE)Registers[REGISTER_A]);
  1482.             break;
  1483.         ////////////////////////////////////////////////// RLC (rotate left through carry memory or accumulator) //////////////////////////////////////////////////
  1484.         case 0x95: //RLC abs
  1485.             address = address_abs();
  1486.  
  1487.             if (address >= 0 && address < MEMORY_SIZE) {
  1488.                 flagThing = Flags;
  1489.                 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1490.                 else Flags = Flags & (0xFF - FLAG_C);
  1491.  
  1492.                 Memory[address] = (Memory[address] << 1) & 0xFE;
  1493.                 if ((flagThing & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
  1494.             }
  1495.  
  1496.             set_flag_n((BYTE)Memory[address]);
  1497.             set_flag_z((BYTE)Memory[address]);
  1498.             break;
  1499.         case 0xA5: //RLC abs,X
  1500.             address = address_absX();
  1501.  
  1502.             if (address >= 0 && address < MEMORY_SIZE) {
  1503.                 flagThing = Flags;
  1504.                 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1505.                 else Flags = Flags & (0xFF - FLAG_C);
  1506.  
  1507.                 Memory[address] = (Memory[address] << 1) & 0xFE;
  1508.                 if ((flagThing & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
  1509.             }
  1510.  
  1511.             set_flag_n((BYTE)Memory[address]);
  1512.             set_flag_z((BYTE)Memory[address]);
  1513.             break;
  1514.         case 0xB5: //RLC abs,Y
  1515.             address = address_absY();
  1516.  
  1517.             if (address >= 0 && address < MEMORY_SIZE) {
  1518.                 flagThing = Flags;
  1519.                 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1520.                 else Flags = Flags & (0xFF - FLAG_C);
  1521.  
  1522.                 Memory[address] = (Memory[address] << 1) & 0xFE;
  1523.                 if ((flagThing & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
  1524.             }
  1525.  
  1526.             set_flag_n((BYTE)Memory[address]);
  1527.             set_flag_z((BYTE)Memory[address]);
  1528.             break;
  1529.         case 0xC5: //RLC abs,XY
  1530.             address = address_absXY();
  1531.  
  1532.             if (address >= 0 && address < MEMORY_SIZE) {
  1533.                 flagThing = Flags;
  1534.                 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1535.                 else Flags = Flags & (0xFF - FLAG_C);
  1536.  
  1537.                 Memory[address] = (Memory[address] << 1) & 0xFE;
  1538.                 if ((flagThing & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
  1539.             }
  1540.  
  1541.             set_flag_n((BYTE)Memory[address]);
  1542.             set_flag_z((BYTE)Memory[address]);
  1543.             break;
  1544.         ////////////////////////////////////////////////// RLCA (rotate left through carry memory or accumulator) //////////////////////////////////////////////////
  1545.         case 0xD5: //RLCA A
  1546.             if ((Registers[REGISTER_A] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1547.             else Flags = Flags & (0xFF - FLAG_C);
  1548.            
  1549.             Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
  1550.             if ((Flags & FLAG_C) == FLAG_C) Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
  1551.            
  1552.             set_flag_n((BYTE)Registers[REGISTER_A]);
  1553.             set_flag_z((BYTE)Registers[REGISTER_A]);
  1554.             break;
  1555.         ////////////////////////////////////////////////// RAL (rotate left without carry memory or accumulator) //////////////////////////////////////////////////
  1556.         case 0x99: //RAL abs
  1557.             address = address_abs();
  1558.  
  1559.             temp_word = (Memory[address] << 1);
  1560.             if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1561.  
  1562.             Memory[address] = (BYTE)temp_word;
  1563.  
  1564.             set_flag_n((BYTE)Memory[address]);
  1565.             set_flag_z((BYTE)Memory[address]);
  1566.             break;
  1567.         case 0xA9: //RAL abs,X
  1568.             address = address_absX();
  1569.  
  1570.             temp_word = (Memory[address] << 1);
  1571.             if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1572.  
  1573.             Memory[address] = (BYTE)temp_word;
  1574.  
  1575.             set_flag_n((BYTE)Memory[address]);
  1576.             set_flag_z((BYTE)Memory[address]);
  1577.             break;
  1578.         case 0xB9: //RAL abs,Y
  1579.             address = address_absY();
  1580.  
  1581.             temp_word = (Memory[address] << 1);
  1582.             if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1583.  
  1584.             Memory[address] = (BYTE)temp_word;
  1585.  
  1586.             set_flag_n((BYTE)Memory[address]);
  1587.             set_flag_z((BYTE)Memory[address]);
  1588.             break;
  1589.         case 0xC9: //RAL abs,XY
  1590.             address = address_absXY();
  1591.  
  1592.             temp_word = (Memory[address] << 1);
  1593.             if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1594.  
  1595.             Memory[address] = (BYTE)temp_word;
  1596.  
  1597.             set_flag_n((BYTE)Memory[address]);
  1598.             set_flag_z((BYTE)Memory[address]);
  1599.             break;
  1600.         ////////////////////////////////////////////////// RALA (rotate left without carry memory or accumulator) //////////////////////////////////////////////////
  1601.         case 0xD9: //RALA A
  1602.             temp_word = (Registers[REGISTER_A] << 1);
  1603.             if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1604.  
  1605.             Registers[REGISTER_A] = (BYTE)temp_word;
  1606.  
  1607.             set_flag_n((BYTE)Registers[REGISTER_A]);
  1608.             set_flag_z((BYTE)Registers[REGISTER_A]);
  1609.             break;
  1610.         ////////////////////////////////////////////////// ROR (rotate right without carry memory or accumulator) //////////////////////////////////////////////////
  1611.         case 0x9A: //ROR abs
  1612.             address = address_abs();
  1613.  
  1614.             temp_word = (Memory[address] >> 1);
  1615.             if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
  1616.  
  1617.             Memory[address] = (BYTE)temp_word;
  1618.  
  1619.             set_flag_n((BYTE)Memory[address]);
  1620.             set_flag_z((BYTE)Memory[address]);
  1621.             break;
  1622.         case 0xAA: //ROR abs,X
  1623.             address = address_absX();
  1624.  
  1625.             temp_word = (Memory[address] >> 1);
  1626.             if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
  1627.  
  1628.             Memory[address] = (BYTE)temp_word;
  1629.  
  1630.             set_flag_n((BYTE)Memory[address]);
  1631.             set_flag_z((BYTE)Memory[address]);
  1632.             break;
  1633.         case 0xBA: //ROR abs,Y
  1634.             address = address_absY();
  1635.  
  1636.             temp_word = (Memory[address] >> 1);
  1637.             if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
  1638.  
  1639.             Memory[address] = (BYTE)temp_word;
  1640.  
  1641.             set_flag_n((BYTE)Memory[address]);
  1642.             set_flag_z((BYTE)Memory[address]);
  1643.             break;
  1644.         case 0xCA: //ROR abs,XY
  1645.             address = address_absXY();
  1646.  
  1647.             temp_word = (Memory[address] >> 1);
  1648.             if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
  1649.  
  1650.             Memory[address] = (BYTE)temp_word;
  1651.  
  1652.             set_flag_n((BYTE)Memory[address]);
  1653.             set_flag_z((BYTE)Memory[address]);
  1654.             break;
  1655.         ////////////////////////////////////////////////// RORA (rotate right without carry memory or accumulator) //////////////////////////////////////////////////
  1656.         case 0xDA: //RORA A
  1657.             temp_word = (Registers[REGISTER_A] >> 1);
  1658.             if ((Registers[REGISTER_A] & 0x01) != 0) temp_word = temp_word | 0x80;
  1659.  
  1660.             Registers[REGISTER_A] = (BYTE)temp_word;
  1661.  
  1662.             set_flag_n((BYTE)Registers[REGISTER_A]);
  1663.             set_flag_z((BYTE)Registers[REGISTER_A]);
  1664.             break;
  1665.         ////////////////////////////////////////////////// COM (negate memory or accumulator) //////////////////////////////////////////////////
  1666.         case 0x98: //COM abs
  1667.             address = address_abs();
  1668.  
  1669.             temp_word = ~Memory[address]; // ~ is the bitwise complement
  1670.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1671.             else Flags = Flags & (0xFF - FLAG_C);
  1672.  
  1673.             Memory[address] = (BYTE)temp_word;
  1674.  
  1675.             set_flag_n((BYTE)Memory[address]);
  1676.             set_flag_z((BYTE)Memory[address]);
  1677.             break;
  1678.         case 0xA8: //COM abs,X
  1679.             address = address_absX();
  1680.  
  1681.             temp_word = ~Memory[address];
  1682.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1683.             else Flags = Flags & (0xFF - FLAG_C);
  1684.  
  1685.             Memory[address] = (BYTE)temp_word;
  1686.  
  1687.             set_flag_n((BYTE)Memory[address]);
  1688.             set_flag_z((BYTE)Memory[address]);
  1689.             break;
  1690.         case 0xB8: //COM abs,Y
  1691.             address = address_absY();
  1692.  
  1693.             temp_word = ~Memory[address];
  1694.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1695.             else Flags = Flags & (0xFF - FLAG_C);
  1696.  
  1697.             Memory[address] = (BYTE)temp_word;
  1698.  
  1699.             set_flag_n((BYTE)Memory[address]);
  1700.             set_flag_z((BYTE)Memory[address]);
  1701.             break;
  1702.         case 0xC8: //COM abs,XY
  1703.             address = address_absXY();
  1704.  
  1705.             temp_word = ~Memory[address];
  1706.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1707.             else Flags = Flags & (0xFF - FLAG_C);
  1708.  
  1709.             Memory[address] = (BYTE)temp_word;
  1710.  
  1711.             set_flag_n((BYTE)Memory[address]);
  1712.             set_flag_z((BYTE)Memory[address]);
  1713.             break;
  1714.         ////////////////////////////////////////////////// COMA (negate memory or accumulator) //////////////////////////////////////////////////
  1715.         case 0xD8: //COMA A
  1716.             temp_word = ~Memory[address];
  1717.            
  1718.             Registers[REGISTER_A] = (BYTE)temp_word;
  1719.            
  1720.             set_flag_n((BYTE)temp_word);
  1721.             set_flag_z((BYTE)temp_word);
  1722.             if (temp_word >= 0x100) Flags = Flags | FLAG_C;
  1723.             else Flags = Flags & (0xFF - FLAG_C);
  1724.             break;
  1725.         ////////////////////////////////////////////////// LX (loads memory into register pair) //////////////////////////////////////////////////
  1726.         case 0x9B: //LX AB,#
  1727.             data = fetch();
  1728.             Registers[REGISTER_A] = data;
  1729.             Registers[REGISTER_B] = data;
  1730.  
  1731.             set_flag_n((BYTE)data);
  1732.             set_flag_z((BYTE)data);
  1733.             break;
  1734.         ////////////////////////////////////////////////// JMP (loads memory into ProgramCounter) //////////////////////////////////////////////////
  1735.         case 0xEA: //JMP abs
  1736.             address = address_abs();
  1737.             ProgramCounter = address;
  1738.             break;
  1739.         ////////////////////////////////////////////////// JSR (jump to subroutine) //////////////////////////////////////////////////
  1740.         case 0xE9: //JSR abs
  1741.             address = address_abs();
  1742.  
  1743.             if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1744.                 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1745.                 StackPointer--;
  1746.                 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1747.                 StackPointer--;
  1748.             }
  1749.             ProgramCounter = address;
  1750.             break;
  1751.         ////////////////////////////////////////////////// RTN (return from subroutine) //////////////////////////////////////////////////
  1752.         case 0xDB: //RTN impl
  1753.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
  1754.                 StackPointer++;
  1755.                 HB = Memory[StackPointer];
  1756.                 StackPointer++;
  1757.                 LB = Memory[StackPointer];
  1758.             }
  1759.             ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
  1760.             break;
  1761.         ////////////////////////////////////////////////// BRA (branch always) //////////////////////////////////////////////////
  1762.         case 0xF0: //BRA rel
  1763.             LB = fetch();
  1764.             offset = (WORD)LB;
  1765.             if ((offset & 0x80) != 0) offset += 0xFF00;
  1766.             address = ProgramCounter + offset;
  1767.             ProgramCounter = address;
  1768.             break;
  1769.         ////////////////////////////////////////////////// BCC (branch on carry clear) //////////////////////////////////////////////////
  1770.         case 0xF1: //BCC rel
  1771.             LB = fetch();
  1772.             if (FLAG_C == 0x00) {
  1773.                 offset = (WORD)LB;
  1774.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1775.                 address = ProgramCounter + offset;
  1776.                 ProgramCounter = address;
  1777.             } else fetch();
  1778.             break;
  1779.         ////////////////////////////////////////////////// BCS (branch on carry set) //////////////////////////////////////////////////
  1780.         case 0xF2: //BCS rel
  1781.             LB = fetch();
  1782.             if (FLAG_C == 0x01) {
  1783.                 offset = (WORD)LB;
  1784.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1785.                 address = ProgramCounter + offset;
  1786.                 ProgramCounter = address;
  1787.             } else fetch();
  1788.             break;
  1789.         ////////////////////////////////////////////////// BNE (branch on result not zero) //////////////////////////////////////////////////
  1790.         case 0xF3: //BNE rel
  1791.             LB = fetch();
  1792.             if (FLAG_Z == 0x00) {
  1793.                 offset = (WORD)LB;
  1794.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1795.                 address = ProgramCounter + offset;
  1796.                 ProgramCounter = address;
  1797.             } else fetch();
  1798.             break;
  1799.         ////////////////////////////////////////////////// BEQ (branch on result equal to zero) //////////////////////////////////////////////////
  1800.         case 0xF4: //BEQ rel
  1801.             LB = fetch();
  1802.             if (FLAG_Z == 0x01) {
  1803.                 offset = (WORD)LB;
  1804.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1805.                 address = ProgramCounter + offset;
  1806.                 ProgramCounter = address;
  1807.             } else fetch();
  1808.             break;
  1809.         ////////////////////////////////////////////////// BVC (branch on overflow clear) //////////////////////////////////////////////////
  1810.         case 0xF5: //BVC rel
  1811.             LB = fetch();
  1812.             if (FLAG_V == 0x00) {
  1813.                 offset = (WORD)LB;
  1814.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1815.                 address = ProgramCounter + offset;
  1816.                 ProgramCounter = address;
  1817.             } else fetch();
  1818.             break;
  1819.         ////////////////////////////////////////////////// BVS (branch on overflow set) //////////////////////////////////////////////////
  1820.         case 0xF6: //BVS rel
  1821.             LB = fetch();
  1822.             if (FLAG_V == 0x01) {
  1823.                 offset = (WORD)LB;
  1824.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1825.                 address = ProgramCounter + offset;
  1826.                 ProgramCounter = address;
  1827.             } else fetch();
  1828.             break;
  1829.         ////////////////////////////////////////////////// BMI (branch on negative result) //////////////////////////////////////////////////
  1830.         case 0xF7: //BMI rel
  1831.             LB = fetch();
  1832.             if (FLAG_N == 0x01) {
  1833.                 offset = (WORD)LB;
  1834.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1835.                 address = ProgramCounter + offset;
  1836.                 ProgramCounter = address;
  1837.             } else fetch();
  1838.             break;
  1839.         ////////////////////////////////////////////////// BPL (branch on positive result) //////////////////////////////////////////////////
  1840.         case 0xF8: //BPL rel
  1841.             LB = fetch();
  1842.             if (FLAG_N == 0x00) {
  1843.                 offset = (WORD)LB;
  1844.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1845.                 address = ProgramCounter + offset;
  1846.                 ProgramCounter = address;
  1847.             } else fetch();
  1848.             break;
  1849.         ////////////////////////////////////////////////// BGE (branch on result <= 0) //////////////////////////////////////////////////
  1850.         case 0xF9: //BGE rel
  1851.             LB = fetch();
  1852.             if ((FLAG_N ^ FLAG_V) == 0x00) {
  1853.                 offset = (WORD)LB;
  1854.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1855.                 address = ProgramCounter + offset;
  1856.                 ProgramCounter = address;
  1857.             } else fetch();
  1858.             break;
  1859.         ////////////////////////////////////////////////// BLE (branch on result >= 0) //////////////////////////////////////////////////
  1860.         case 0xFA: //BLE rel
  1861.             LB = fetch();
  1862.             if ((FLAG_Z | FLAG_N ^ FLAG_V) == 0x01) {
  1863.                 offset = (WORD)LB;
  1864.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1865.                 address = ProgramCounter + offset;
  1866.                 ProgramCounter = address;
  1867.             } else fetch();
  1868.             break;
  1869.         ////////////////////////////////////////////////// BGT (branch on result < 0) //////////////////////////////////////////////////
  1870.         case 0xFB: //BGT rel
  1871.             LB = fetch();
  1872.             if ((FLAG_Z | FLAG_N ^ FLAG_V) == 0x00) {
  1873.                 offset = (WORD)LB;
  1874.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1875.                 address = ProgramCounter + offset;
  1876.                 ProgramCounter = address;
  1877.             } else fetch();
  1878.             break;
  1879.         ////////////////////////////////////////////////// BLT (branch on result > 0) //////////////////////////////////////////////////
  1880.         case 0xFC: //BLT rel
  1881.             LB = fetch();
  1882.             if ((FLAG_N ^ FLAG_V) == 0x01) {
  1883.                 offset = (WORD)LB;
  1884.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1885.                 address = ProgramCounter + offset;
  1886.                 ProgramCounter = address;
  1887.             } else fetch();
  1888.             break;
  1889.         ////////////////////////////////////////////////// PUSH (pushes register onto stack) //////////////////////////////////////////////////
  1890.         case 0x9E: //PUSH A
  1891.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1892.                 Memory[StackPointer] = Registers[REGISTER_A];
  1893.                 StackPointer--;
  1894.             }
  1895.             break;
  1896.         case 0xAE: //PUSH FL
  1897.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1898.                 Memory[StackPointer] = Flags;
  1899.                 StackPointer--;
  1900.             }
  1901.             break;
  1902.         case 0xBE: //PUSH B
  1903.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1904.                 Memory[StackPointer] = Registers[REGISTER_B];
  1905.                 StackPointer--;
  1906.             }
  1907.             break;
  1908.         case 0xCE: //PUSH C
  1909.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1910.                 Memory[StackPointer] = Registers[REGISTER_C];
  1911.                 StackPointer--;
  1912.             }
  1913.             break;
  1914.         case 0xDE: //PUSH D
  1915.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1916.                 Memory[StackPointer] = Registers[REGISTER_D];
  1917.                 StackPointer--;
  1918.             }
  1919.             break;
  1920.         case 0xEE: //PUSH E
  1921.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1922.                 Memory[StackPointer] = Registers[REGISTER_E];
  1923.                 StackPointer--;
  1924.             }
  1925.             break;
  1926.         case 0xFE: //PUSH F
  1927.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1928.                 Memory[StackPointer] = Registers[REGISTER_F];
  1929.                 StackPointer--;
  1930.             }
  1931.             break;
  1932.         ////////////////////////////////////////////////// POP (pop top of stack into register) //////////////////////////////////////////////////
  1933.         case 0x9F: //POP A
  1934.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1935.                 StackPointer++;
  1936.                 Registers[REGISTER_A] = Memory[StackPointer];
  1937.             }
  1938.             break;
  1939.         case 0xAF: //POP FL
  1940.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1941.                 StackPointer++;
  1942.                 Flags = Memory[StackPointer];
  1943.             }
  1944.             break;
  1945.         case 0xBF: //POP B
  1946.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1947.                 StackPointer++;
  1948.                 Registers[REGISTER_B] = Memory[StackPointer];
  1949.             }
  1950.             break;
  1951.         case 0xCF: //POP C
  1952.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1953.                 StackPointer++;
  1954.                 Registers[REGISTER_C] = Memory[StackPointer];
  1955.             }
  1956.             break;
  1957.         case 0xDF: //POP D
  1958.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1959.                 StackPointer++;
  1960.                 Registers[REGISTER_D] = Memory[StackPointer];
  1961.             }
  1962.             break;
  1963.         case 0xEF: //POP E
  1964.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE -1 )) {
  1965.                 StackPointer++;
  1966.                 Registers[REGISTER_E] = Memory[StackPointer];
  1967.             }
  1968.             break;
  1969.         case 0xFF: //POP F
  1970.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1971.                 StackPointer++;
  1972.                 Registers[REGISTER_F] = Memory[StackPointer];
  1973.             }
  1974.             break;
  1975.         ////////////////////////////////////////////////// SWI (software interrupt) //////////////////////////////////////////////////
  1976.         case 0x16: //SWI impl
  1977.            
  1978.             break;
  1979.         ////////////////////////////////////////////////// RTN (return from software interrupt) //////////////////////////////////////////////////
  1980.         case 0x17: //RTN impl
  1981.            
  1982.             break;
  1983.         ////////////////////////////////////////////////// SEC (set carry flag) //////////////////////////////////////////////////
  1984.         case 0x19: //SEC impl
  1985.             Flags = Flags | FLAG_C;
  1986.             break;
  1987.         ////////////////////////////////////////////////// CLC (clear carry flag) //////////////////////////////////////////////////
  1988.         case 0x18: //CLC impl
  1989.             Flags = Flags & (0xFF - FLAG_C);
  1990.             break;
  1991.         ////////////////////////////////////////////////// STI (set interrupt flag) //////////////////////////////////////////////////
  1992.         case 0x1B: //STI impl
  1993.             Flags = Flags | FLAG_I;
  1994.             break;
  1995.         ////////////////////////////////////////////////// CLI (clear interrupt flag) //////////////////////////////////////////////////
  1996.         case 0x1A: //CLI impl
  1997.             Flags = Flags & (0xFF - FLAG_I);
  1998.             break;
  1999.         ////////////////////////////////////////////////// STV (set overflow flag) //////////////////////////////////////////////////
  2000.         case 0x1C: //STV impl
  2001.             Flags = Flags | FLAG_V;
  2002.             break;
  2003.         ////////////////////////////////////////////////// CLV (clear overflow flag) //////////////////////////////////////////////////
  2004.         case 0x1D: //CLV impl
  2005.             Flags = Flags & (0xFF - FLAG_V);
  2006.             break;
  2007.     }
  2008. }
  2009.  
  2010. //LD function
  2011. void Group_2_Move(BYTE opcode) {
  2012.     BYTE destination = opcode >> 4; //top four bits point at one register....shift right to keep only top four
  2013.     BYTE source = opcode & 0x0F;//takes bottom four bits
  2014.     int destReg = 0, sourceReg = 0;
  2015.  
  2016.     switch (destination) { //COMBO OF DEST AND SOURCE GIVE REGISTERS ADDRESSES TO FOR MEMORY ADRESSER AT BOTTOM
  2017.         case 0x02://top four bits from op code
  2018.             destReg = REGISTER_A;
  2019.             break;
  2020.         case 0x03:
  2021.             destReg = REGISTER_B;
  2022.             break;
  2023.         case 0x04:
  2024.             destReg = REGISTER_C;
  2025.             break;
  2026.         case 0x05:
  2027.             destReg = REGISTER_D;
  2028.             break;
  2029.         case 0x06:
  2030.             destReg = REGISTER_E;
  2031.             break;
  2032.         case 0x07:
  2033.             destReg = REGISTER_F;
  2034.             break;
  2035.     }
  2036.  
  2037.     switch (source) {
  2038.         case 0x0A:
  2039.             sourceReg = REGISTER_A;
  2040.             break;
  2041.         case 0x0B:
  2042.             sourceReg = REGISTER_B;
  2043.             break;
  2044.         case 0x0C:
  2045.             sourceReg = REGISTER_C;
  2046.             break;
  2047.         case 0x0D:
  2048.             sourceReg = REGISTER_D;
  2049.             break;
  2050.         case 0x0E:
  2051.             sourceReg = REGISTER_E;
  2052.             break;
  2053.         case 0x0F:
  2054.             sourceReg = REGISTER_F;
  2055.             break;
  2056.     }
  2057.  
  2058.     Registers[sourceReg] = Registers[destReg]; //code to assign sourcereg to dest reg
  2059. }
  2060.  
  2061. void execute(BYTE opcode) {
  2062.     if (((opcode >= 0x2A) && (opcode <= 0x2F))
  2063.         || ((opcode >= 0x3A) && (opcode <= 0x3F))
  2064.         || ((opcode >= 0x4A) && (opcode <= 0x4F))
  2065.         || ((opcode >= 0x5A) && (opcode <= 0x5F))
  2066.         || ((opcode >= 0x6A) && (opcode <= 0x6F))
  2067.         || ((opcode >= 0x7A) && (opcode <= 0x7F)))
  2068.     {
  2069.         Group_2_Move(opcode);
  2070.     }
  2071.     else Group_1(opcode);
  2072. }
  2073.  
  2074. void emulate() {
  2075.     BYTE opcode;
  2076.     int sanity = 0;
  2077.  
  2078.     ProgramCounter = 0;
  2079.     halt = false;
  2080.     memory_in_range = true;
  2081.  
  2082.     printf("                    A  B  C  D  E  F  X  Y  SP\n");
  2083.  
  2084.     while ((!halt) && (memory_in_range)) {
  2085.         sanity++;
  2086.         if (sanity > 500) halt = true;
  2087.         printf("%04X ", ProgramCounter);           // Print current address
  2088.         opcode = fetch();
  2089.         execute(opcode);
  2090.  
  2091.         printf("%s  ", opcode_mneumonics[opcode]);  // Print current opcode
  2092.         printf("%02X ", Registers[REGISTER_A]);
  2093.         printf("%02X ", Registers[REGISTER_B]);
  2094.         printf("%02X ", Registers[REGISTER_C]);
  2095.         printf("%02X ", Registers[REGISTER_D]);
  2096.         printf("%02X ", Registers[REGISTER_E]);
  2097.         printf("%02X ", Registers[REGISTER_F]);
  2098.         printf("%02X ", Index_Registers[REGISTER_X]);
  2099.         printf("%02X ", Index_Registers[REGISTER_Y]);
  2100.         printf("%04X ", StackPointer);              // Print Stack Pointer
  2101.  
  2102.         if ((Flags & FLAG_I) == FLAG_I) printf("I = 1, ");
  2103.         else printf("I = 0, ");
  2104.  
  2105.         if ((Flags & FLAG_V) == FLAG_V) printf("V = 1, ");
  2106.         else printf("V = 0, ");
  2107.  
  2108.         if ((Flags & FLAG_N) == FLAG_N) printf("N = 1, ");
  2109.         else printf("N = 0, ");
  2110.  
  2111.         if ((Flags & FLAG_Z) == FLAG_Z) printf("Z = 1, ");
  2112.         else printf("Z = 0, ");
  2113.  
  2114.         if ((Flags & FLAG_C) == FLAG_C) printf("C = 1 ");
  2115.         else printf("C = 0 ");
  2116.        
  2117.         printf("\n");
  2118.     }
  2119.     printf("\n");
  2120. }
  2121.  
  2122.  
  2123. ////////////////////////////////////////////////////////////////////////////////
  2124. //                                Emulator (End)                              //
  2125. ////////////////////////////////////////////////////////////////////////////////
  2126.  
  2127. void initialise_filenames() {
  2128.     int i;
  2129.  
  2130.     for (i=0; i<MAX_FILENAME_SIZE; i++) {
  2131.         hex_file [i] = '\0';
  2132.         trc_file [i] = '\0';
  2133.     }
  2134. }
  2135.  
  2136. int find_dot_position(char *filename) {
  2137.     int  dot_position;
  2138.     int  i;
  2139.     char chr;
  2140.  
  2141.     dot_position = 0;
  2142.     i = 0;
  2143.     chr = filename[i];
  2144.  
  2145.     while (chr != '\0') {
  2146.         if (chr == '.') dot_position = i;
  2147.  
  2148.         i++;
  2149.         chr = filename[i];
  2150.     }
  2151.  
  2152.     return dot_position;
  2153. }
  2154.  
  2155. int find_end_position(char *filename) {
  2156.     int  end_position;
  2157.     int  i;
  2158.     char chr;
  2159.  
  2160.     end_position = 0;
  2161.     i = 0;
  2162.     chr = filename[i];
  2163.  
  2164.     while (chr != '\0') {
  2165.         end_position = i;
  2166.         i++;
  2167.         chr = filename[i];
  2168.     }
  2169.  
  2170.     return end_position;
  2171. }
  2172.  
  2173. bool file_exists(char *filename) {
  2174.     bool exists;
  2175.     FILE *ifp;
  2176.  
  2177.     exists = false;
  2178.  
  2179.     if ((ifp = fopen(filename, "r")) != NULL) {
  2180.         exists = true;
  2181.  
  2182.         fclose(ifp);
  2183.     }
  2184.  
  2185.     return exists;
  2186. }
  2187.  
  2188. void create_file(char *filename) {
  2189.     FILE *ofp;
  2190.  
  2191.     if ((ofp = fopen(filename, "w")) != NULL) fclose(ofp);
  2192. }
  2193.  
  2194. bool getline(FILE *fp, char *buffer) {
  2195.     bool rc;
  2196.     bool collect;
  2197.     char c;
  2198.     int  i;
  2199.  
  2200.     rc = false;
  2201.     collect = true;
  2202.  
  2203.     i = 0;
  2204.     while (collect) {
  2205.         c = getc(fp);
  2206.  
  2207.         switch (c) {
  2208.             case EOF:
  2209.                 if (i > 0) rc = true;
  2210.  
  2211.                 collect = false;
  2212.                 break;
  2213.             case '\n':
  2214.                 if (i > 0) {
  2215.                     rc = true;
  2216.                     collect = false;
  2217.                     buffer[i] = '\0';
  2218.                 }
  2219.                 break;
  2220.             default:
  2221.                 buffer[i] = c;
  2222.                 i++;
  2223.         }
  2224.     }
  2225.  
  2226.     return rc;
  2227. }
  2228.  
  2229. void load_and_run(int args,_TCHAR** argv) {
  2230.     char chr;
  2231.     int  ln;
  2232.     int  dot_position;
  2233.     int  end_position;
  2234.     long i;
  2235.     FILE *ifp;
  2236.     long address;
  2237.     long load_at;
  2238.     int  code;
  2239.  
  2240.     // Prompt for the .hex file
  2241.  
  2242.     printf("\n");
  2243.     printf("Enter the hex filename (.hex): ");
  2244.  
  2245.     if(args == 2) {
  2246.         ln = 0;
  2247.         chr = argv[1][ln];
  2248.         while (chr != '\0') {
  2249.             if (ln < MAX_FILENAME_SIZE) {
  2250.                 hex_file [ln] = chr;
  2251.                 trc_file [ln] = chr;
  2252.                 ln++;
  2253.             }
  2254.             chr = argv[1][ln];
  2255.         }
  2256.     } else {
  2257.         ln = 0;
  2258.         chr = '\0';
  2259.         while (chr != '\n') {
  2260.             chr = getchar();
  2261.  
  2262.             switch(chr) {
  2263.             case '\n':
  2264.                 break;
  2265.             default:
  2266.                 if (ln < MAX_FILENAME_SIZE) {
  2267.                     hex_file [ln] = chr;
  2268.                     trc_file [ln] = chr;
  2269.                     ln++;
  2270.                 }
  2271.                 break;
  2272.             }
  2273.         }
  2274.     }
  2275.     // Tidy up the file names
  2276.  
  2277.     dot_position = find_dot_position(hex_file);
  2278.     if (dot_position == 0) {
  2279.         end_position = find_end_position(hex_file);
  2280.  
  2281.         hex_file[end_position + 1] = '.';
  2282.         hex_file[end_position + 2] = 'h';
  2283.         hex_file[end_position + 3] = 'e';
  2284.         hex_file[end_position + 4] = 'x';
  2285.         hex_file[end_position + 5] = '\0';
  2286.     } else {
  2287.         hex_file[dot_position + 0] = '.';
  2288.         hex_file[dot_position + 1] = 'h';
  2289.         hex_file[dot_position + 2] = 'e';
  2290.         hex_file[dot_position + 3] = 'x';
  2291.         hex_file[dot_position + 4] = '\0';
  2292.     }
  2293.  
  2294.     dot_position = find_dot_position(trc_file);
  2295.     if (dot_position == 0) {
  2296.         end_position = find_end_position(trc_file);
  2297.  
  2298.         trc_file[end_position + 1] = '.';
  2299.         trc_file[end_position + 2] = 't';
  2300.         trc_file[end_position + 3] = 'r';
  2301.         trc_file[end_position + 4] = 'c';
  2302.         trc_file[end_position + 5] = '\0';
  2303.     } else {
  2304.         trc_file[dot_position + 0] = '.';
  2305.         trc_file[dot_position + 1] = 't';
  2306.         trc_file[dot_position + 2] = 'r';
  2307.         trc_file[dot_position + 3] = 'c';
  2308.         trc_file[dot_position + 4] = '\0';
  2309.     }
  2310.  
  2311.     if (file_exists(hex_file)) {
  2312.         // Clear Registers and Memory
  2313.         Registers[REGISTER_A] = 0;
  2314.         Registers[REGISTER_B] = 0;
  2315.         Registers[REGISTER_C] = 0;
  2316.         Registers[REGISTER_D] = 0;
  2317.         Registers[REGISTER_E] = 0;
  2318.         Registers[REGISTER_F] = 0;
  2319.         Index_Registers[REGISTER_X] = 0;
  2320.         Index_Registers[REGISTER_Y] = 0;
  2321.         Flags = 0;
  2322.         ProgramCounter = 0;
  2323.         StackPointer = 0;
  2324.  
  2325.         for (i = 0; i < MEMORY_SIZE; i++) Memory[i] = 0x00;
  2326.  
  2327.         // Load hex file
  2328.         if ((ifp = fopen(hex_file, "r")) != NULL) {
  2329.             printf("Loading file...\n\n");
  2330.  
  2331.             load_at = 0;
  2332.  
  2333.             while (getline(ifp, InputBuffer)) {
  2334.                 if (sscanf(InputBuffer, "L=%x", &address) == 1) load_at = address;
  2335.                 else if (sscanf(InputBuffer, "%x", &code) == 1) {
  2336.                     if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) Memory[load_at] = (BYTE)code;
  2337.  
  2338.                     load_at++;
  2339.                 } else printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
  2340.             }
  2341.  
  2342.             fclose(ifp);
  2343.         }
  2344.  
  2345.         emulate();
  2346.     } else {
  2347.         printf("\n");
  2348.         printf("ERROR> Input file %s does not exist!\n", hex_file);
  2349.         printf("\n");
  2350.     }
  2351. }
  2352.  
  2353. void building(int args,_TCHAR** argv){
  2354.     char buffer[1024];
  2355.     load_and_run(args,argv);
  2356.     sprintf(buffer, "0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X",
  2357.         Memory[TEST_ADDRESS_1],
  2358.         Memory[TEST_ADDRESS_2],
  2359.         Memory[TEST_ADDRESS_3],
  2360.         Memory[TEST_ADDRESS_4],
  2361.         Memory[TEST_ADDRESS_5],
  2362.         Memory[TEST_ADDRESS_6],
  2363.         Memory[TEST_ADDRESS_7],
  2364.         Memory[TEST_ADDRESS_8],
  2365.         Memory[TEST_ADDRESS_9],
  2366.         Memory[TEST_ADDRESS_10],
  2367.         Memory[TEST_ADDRESS_11],
  2368.         Memory[TEST_ADDRESS_12]
  2369.         );
  2370.     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
  2371. }
  2372.  
  2373. void test_and_mark() {
  2374.     char buffer[1024];
  2375.     bool testing_complete;
  2376.     int  len = sizeof(SOCKADDR);
  2377.     char chr;
  2378.     int  i;
  2379.     int  j;
  2380.     bool end_of_program;
  2381.     long address;
  2382.     long load_at;
  2383.     int  code;
  2384.     int  mark;
  2385.     int  passed;
  2386.  
  2387.     printf("Automatic Testing and Marking\n");
  2388.     printf("\n");
  2389.  
  2390.     testing_complete = false;
  2391.  
  2392.     sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
  2393.     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
  2394.  
  2395.     while (!testing_complete) {
  2396.         memset(buffer, '\0', sizeof(buffer));
  2397.  
  2398.         if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
  2399.             printf("Incoming Data: %s \n", buffer);
  2400.  
  2401.             //if (strcmp(buffer, "Testing complete") == 1)
  2402.             if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
  2403.                 testing_complete = true;
  2404.                 printf("Current mark = %d\n", mark);
  2405.             }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
  2406.                 //testing_complete = true;
  2407.                 printf("Passed = %d\n", passed);
  2408.             } else if (strcmp(buffer, "Error") == 0) {
  2409.                 printf("ERROR> Testing abnormally terminated\n");
  2410.                 testing_complete = true;
  2411.             } else {
  2412.                 // Clear Registers and Memory
  2413.                 Registers[REGISTER_A] = 0;
  2414.                 Registers[REGISTER_B] = 0;
  2415.                 Registers[REGISTER_C] = 0;
  2416.                 Registers[REGISTER_D] = 0;
  2417.                 Registers[REGISTER_E] = 0;
  2418.                 Registers[REGISTER_F] = 0;
  2419.                 Index_Registers[REGISTER_X] = 0;
  2420.                 Index_Registers[REGISTER_Y] = 0;
  2421.                 Flags = 0;
  2422.                 ProgramCounter = 0;
  2423.                 StackPointer = 0;
  2424.                 for (i = 0; i < MEMORY_SIZE; i++) Memory[i] = 0;
  2425.  
  2426.                 // Load hex file
  2427.                 i = 0;
  2428.                 j = 0;
  2429.                 load_at = 0;
  2430.                 end_of_program = false;
  2431.                 FILE *ofp;
  2432.                 fopen_s(&ofp ,"branch.txt", "a");
  2433.  
  2434.                 while (!end_of_program) {
  2435.                     chr = buffer[i];
  2436.                     switch (chr) {
  2437.                     case '\0':
  2438.                         end_of_program = true;
  2439.                     case ',':
  2440.                         if (sscanf(InputBuffer, "L=%x", &address) == 1) load_at = address;
  2441.                         else if (sscanf(InputBuffer, "%x", &code) == 1) {
  2442.                             if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
  2443.                                 Memory[load_at] = (BYTE)code;
  2444.                                 fprintf(ofp, "%02X\n", (BYTE)code);
  2445.                             }
  2446.                             load_at++;
  2447.                         } else printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
  2448.                        
  2449.                         j = 0;
  2450.                         break;
  2451.                     default:
  2452.                         InputBuffer[j] = chr;
  2453.                         j++;
  2454.                         break;
  2455.                     }
  2456.                     i++;
  2457.                 }
  2458.                 fclose(ofp);
  2459.                 // Emulate
  2460.  
  2461.                 if (load_at > 1) {
  2462.                     emulate();
  2463.                     // Send and store results
  2464.                     sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
  2465.                         Memory[TEST_ADDRESS_1],
  2466.                         Memory[TEST_ADDRESS_2],
  2467.                         Memory[TEST_ADDRESS_3],
  2468.                         Memory[TEST_ADDRESS_4],
  2469.                         Memory[TEST_ADDRESS_5],
  2470.                         Memory[TEST_ADDRESS_6],
  2471.                         Memory[TEST_ADDRESS_7],
  2472.                         Memory[TEST_ADDRESS_8],
  2473.                         Memory[TEST_ADDRESS_9],
  2474.                         Memory[TEST_ADDRESS_10],
  2475.                         Memory[TEST_ADDRESS_11],
  2476.                         Memory[TEST_ADDRESS_12]
  2477.                         );
  2478.                     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
  2479.                 }
  2480.             }
  2481.         }
  2482.     }
  2483. }
  2484.  
  2485. int _tmain(int argc, _TCHAR* argv[]) {
  2486.     char chr;
  2487.     char dummy;
  2488.  
  2489.     printf("Microprocessor Emulator\n");
  2490.     printf("UWE Computer and Network Systems Assignment 1\n");
  2491.     printf("\n");
  2492.  
  2493.     initialise_filenames();
  2494.  
  2495.     if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
  2496.  
  2497.     sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
  2498.     if (!sock) {   
  2499.         //Creation failed!
  2500.     }
  2501.  
  2502.     memset(&server_addr, 0, sizeof(SOCKADDR_IN));
  2503.     server_addr.sin_family = AF_INET;
  2504.     server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
  2505.     server_addr.sin_port = htons(PORT_SERVER);
  2506.  
  2507.     memset(&client_addr, 0, sizeof(SOCKADDR_IN));
  2508.     client_addr.sin_family = AF_INET;
  2509.     client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  2510.     client_addr.sin_port = htons(PORT_CLIENT);
  2511.  
  2512.     chr = '\0';
  2513.     while ((chr != 'e') && (chr != 'E')) {
  2514.         printf("\nPlease select option\n");
  2515.         printf("L - Load and run a hex file\n");
  2516.         printf("T - Have the server test and mark your emulator\n");
  2517.         printf("E - Exit\n");
  2518.         if(argc == 2){ building(argc,argv); exit(0);}
  2519.         printf("Enter option: ");
  2520.         chr = getchar();
  2521.         if (chr != 0x0A) dummy = getchar();  // read in the <CR>
  2522.        
  2523.         printf("\n");
  2524.  
  2525.         switch (chr) {
  2526.             case 'L': case 'l':
  2527.                 load_and_run(argc,argv);
  2528.                 break;
  2529.             case 'T': case 't':
  2530.                 test_and_mark();
  2531.                 break; 
  2532.         }
  2533.     }
  2534.  
  2535.     closesocket(sock);
  2536.     WSACleanup();
  2537.  
  2538.     return 0;
  2539. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement