Advertisement
Guest User

Untitled

a guest
Feb 20th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 70.43 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
  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. void set_flags_nz(BYTE inReg) {
  405.     set_flag_n(inReg);
  406.     set_flag_z(inReg);
  407. }
  408. void set_flag_c(WORD inWord) {
  409.     if (inWord >= 0x100) Flags = Flags | FLAG_C;
  410.     else Flags = Flags & (0xFF - FLAG_C);
  411. }
  412.  
  413. //functions that return the address for different addressing modes
  414. WORD address_abs() {
  415.     BYTE HB = fetch();
  416.     BYTE LB = fetch();
  417.     WORD address = (WORD)((WORD)HB << 8) + LB;
  418.     return address;
  419. }
  420. WORD address_absX() {
  421.     BYTE HB = fetch();
  422.     BYTE LB = fetch();
  423.     WORD address = Index_Registers[REGISTER_X];
  424.     address += (WORD)((WORD)HB << 8) + LB;
  425.     return address;
  426. }
  427. WORD address_absY() {
  428.     BYTE HB = fetch();
  429.     BYTE LB = fetch();
  430.     WORD address = Index_Registers[REGISTER_Y];
  431.     address += (WORD)((WORD)HB << 8) + LB;
  432.     return address;
  433. }
  434. WORD address_absXY() {
  435.     BYTE HB = fetch();
  436.     BYTE LB = fetch();
  437.     WORD address = (WORD)((WORD)Index_Registers[REGISTER_Y] << 8) + Index_Registers[REGISTER_X];
  438.     address += (WORD)((WORD)HB << 8) + LB;
  439.     return address;
  440. }
  441. WORD address_indXY() {
  442.     BYTE HB = fetch();
  443.     BYTE LB = fetch();
  444.     WORD address = (WORD)((WORD)HB << 8) + LB;
  445.     HB = Memory[address];
  446.     LB = Memory[address + 1];
  447.     address = (WORD)((WORD)HB << 8) + LB;
  448.     address += Index_Registers[REGISTER_X] + (WORD)((WORD)Index_Registers[REGISTER_Y] << 8);
  449.     return address;
  450. }
  451.  
  452. void Group_1(BYTE opcode) {
  453.     BYTE LB = 0, HB = 0, saved_flags = 0;
  454.     WORD address = 0;
  455.     WORD data = 0;
  456.     WORD temp_word = 0;
  457.     WORD offset = 0;
  458.  
  459.     switch (opcode) {
  460.         ////////////////////////////////////////////////// NOP (no operation) //////////////////////////////////////////////////
  461.         case 0x73: //NOP impl
  462.             //nothing
  463.             break;
  464.         ////////////////////////////////////////////////// HLT (wait for interrupt) //////////////////////////////////////////////////
  465.         case 0x74: //HLT impl
  466.             halt = true;
  467.             break;
  468.         ////////////////////////////////////////////////// LDA (loads memory into accumulator) //////////////////////////////////////////////////
  469.         case 0x90: //LDA #
  470.             Registers[REGISTER_A] = fetch();
  471.             set_flags_nz((BYTE)Registers[REGISTER_A]);
  472.             break;
  473.         case 0xA0: //LDA abs
  474.             address = address_abs();
  475.             if (address >= 0 && address < MEMORY_SIZE) {
  476.                 Registers[REGISTER_A] = Memory[address];
  477.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  478.             }
  479.             break;
  480.         case 0xB0: //LDA abs,X
  481.             address = address_absX();
  482.             if (address >= 0 && address < MEMORY_SIZE) {
  483.                 Registers[REGISTER_A] = Memory[address];
  484.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  485.             }
  486.             break;
  487.         case 0xC0: //LDA abs,Y
  488.             address = address_absY();
  489.             if (address >= 0 && address < MEMORY_SIZE) {
  490.                 Registers[REGISTER_A] = Memory[address];
  491.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  492.             }
  493.             break;
  494.         case 0xD0: //LDA abs,XY
  495.             address = address_absXY();
  496.             if (address >= 0 && address < MEMORY_SIZE) {
  497.                 Registers[REGISTER_A] = Memory[address];
  498.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  499.             }
  500.             break;
  501.         case 0xE0: //LDA (ind),XY
  502.             address = address_indXY();
  503.             if (address >= 0 && address < MEMORY_SIZE) {
  504.                 Registers[REGISTER_A] = Memory[address];
  505.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  506.             }
  507.             break;
  508.         ////////////////////////////////////////////////// STO (stores accumulator into memory) //////////////////////////////////////////////////
  509.         case 0xAC: //STO abs
  510.             address = address_abs();
  511.             if (address >= 0 && address < MEMORY_SIZE) {
  512.                 Memory[address] = Registers[REGISTER_A];
  513.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  514.             }
  515.             break;
  516.         case 0xBC: //STO abs,X
  517.             address = address_absX();
  518.             if (address >= 0 && address < MEMORY_SIZE) {
  519.                 Memory[address] = Registers[REGISTER_A];
  520.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  521.             }
  522.             break;
  523.         case 0xCC: //STO abs,Y
  524.             address = address_absY();
  525.             if (address >= 0 && address < MEMORY_SIZE) {
  526.                 Memory[address] = Registers[REGISTER_A];
  527.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  528.             }
  529.             break;
  530.         case 0xDC: //STO abs,XY
  531.             address = address_absXY();
  532.             if (address >= 0 && address < MEMORY_SIZE) {
  533.                 Memory[address] = Registers[REGISTER_A];
  534.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  535.             }
  536.             break;
  537.         case 0xEC: //STO (ind),XY
  538.             address = address_indXY();
  539.             if (address >= 0 && address < MEMORY_SIZE) {
  540.                 Memory[address] = Registers[REGISTER_A];
  541.                 set_flags_nz((BYTE)Registers[REGISTER_A]);
  542.             }
  543.             break;
  544.         ////////////////////////////////////////////////// MV (loads memory into register) //////////////////////////////////////////////////
  545.         case 0x07: //MV B,#
  546.             Registers[REGISTER_B] = fetch();
  547.             set_flags_nz((BYTE)Registers[REGISTER_B]);
  548.             break;
  549.         case 0x08: //MV C,#
  550.             Registers[REGISTER_C] = fetch();
  551.             set_flags_nz((BYTE)Registers[REGISTER_C]);
  552.             break;
  553.         case 0x09: //MV D,#
  554.             Registers[REGISTER_D] = fetch();
  555.             set_flags_nz((BYTE)Registers[REGISTER_D]);
  556.             break;
  557.         case 0x0A: //MV E,#
  558.             Registers[REGISTER_E] = fetch();
  559.             set_flags_nz((BYTE)Registers[REGISTER_E]);
  560.             break;
  561.         case 0x0B: //MV F,#
  562.             Registers[REGISTER_F] = fetch();
  563.             set_flags_nz((BYTE)Registers[REGISTER_F]);
  564.             break;
  565.         ////////////////////////////////////////////////// LODS (loads memory into stackpointer) //////////////////////////////////////////////////
  566.         case 0x9D: //LODS #
  567.             data = fetch();
  568.             StackPointer = data << 8;
  569.             StackPointer += fetch();
  570.             set_flags_nz((BYTE)StackPointer);
  571.             break;
  572.         case 0xAD: //LODS abs
  573.             address = address_abs();
  574.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  575.                 StackPointer = (WORD)Memory[address] << 8;
  576.                 StackPointer += Memory[address + 1];
  577.                 set_flags_nz((BYTE)StackPointer);
  578.             }
  579.             break;
  580.         case 0xBD: //LODS abs,X
  581.             address = address_absX();
  582.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  583.                 StackPointer = (WORD)Memory[address] << 8;
  584.                 StackPointer += Memory[address + 1];
  585.                 set_flags_nz((BYTE)StackPointer);
  586.             }
  587.             break;
  588.         case 0xCD: //LODS abs,Y
  589.             address = address_absY();
  590.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  591.                 StackPointer = (WORD)Memory[address] << 8;
  592.                 StackPointer += Memory[address + 1];
  593.                 set_flags_nz((BYTE)StackPointer);
  594.             }
  595.             break;
  596.         case 0xDD: //LODS abs,XY
  597.             address = address_absXY();
  598.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  599.                 StackPointer = (WORD)Memory[address] << 8;
  600.                 StackPointer += Memory[address + 1];
  601.                 set_flags_nz((BYTE)StackPointer);
  602.             }
  603.             break;
  604.         case 0xED: //LODS (ind),XY
  605.             address = address_indXY();
  606.             if (address >= 0 && address < MEMORY_SIZE - 1) {
  607.                 StackPointer = (WORD)Memory[address] << 8;
  608.                 StackPointer += Memory[address + 1];
  609.                 set_flags_nz((BYTE)StackPointer);
  610.             }
  611.             break;
  612.         ////////////////////////////////////////////////// ADD (register added to accumulator with carry) //////////////////////////////////////////////////
  613.         case 0x23: //ADD A,B
  614.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
  615.             if ((Flags & FLAG_C) != 0) temp_word++;
  616.            
  617.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_B], (BYTE)temp_word);
  618.             set_flags_nz((BYTE)temp_word);
  619.             set_flag_c((WORD)temp_word);
  620.  
  621.             Registers[REGISTER_A] = (BYTE)temp_word;
  622.             break;
  623.         case 0x33: //ADD A,C
  624.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
  625.             if ((Flags & FLAG_C) != 0) temp_word++;
  626.            
  627.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_C], (BYTE)temp_word);
  628.             set_flags_nz((BYTE)temp_word);
  629.             set_flag_c((WORD)temp_word);
  630.  
  631.             Registers[REGISTER_A] = (BYTE)temp_word;
  632.             break;
  633.         case 0x43: //ADD A,D
  634.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_D];
  635.             if ((Flags & FLAG_C) != 0) temp_word++;
  636.  
  637.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_D], (BYTE)temp_word);
  638.             set_flags_nz((BYTE)temp_word);
  639.             set_flag_c((WORD)temp_word);
  640.  
  641.             Registers[REGISTER_A] = (BYTE)temp_word;
  642.             break;
  643.         case 0x53: //ADD A,E
  644.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_E];
  645.             if ((Flags & FLAG_C) != 0) temp_word++;
  646.  
  647.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_E], (BYTE)temp_word);
  648.             set_flags_nz((BYTE)temp_word);
  649.             set_flag_c((WORD)temp_word);
  650.  
  651.             Registers[REGISTER_A] = (BYTE)temp_word;
  652.             break;
  653.         case 0x63: //ADD A,F
  654.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_F];
  655.             if ((Flags & FLAG_C) != 0) temp_word++;
  656.  
  657.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)Registers[REGISTER_F], (BYTE)temp_word);
  658.             set_flags_nz((BYTE)temp_word);
  659.             set_flag_c((WORD)temp_word);
  660.  
  661.             Registers[REGISTER_A] = (BYTE)temp_word;
  662.             break;
  663.         ////////////////////////////////////////////////// SUB (register subtracted to accumulator with carry) //////////////////////////////////////////////////
  664.         case 0x24: //SUB A,B
  665.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
  666.             if ((Flags & FLAG_C) != 0) temp_word--;
  667.  
  668.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_B]), (BYTE)temp_word);
  669.             set_flags_nz((BYTE)temp_word);
  670.             set_flag_c((WORD)temp_word);
  671.  
  672.             Registers[REGISTER_A] = (BYTE)temp_word;
  673.             break;
  674.         case 0x34: //SUB A,C
  675.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
  676.             if ((Flags & FLAG_C) != 0) temp_word--;
  677.  
  678.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_C]), (BYTE)temp_word);
  679.             set_flags_nz((BYTE)temp_word);
  680.             set_flag_c((WORD)temp_word);
  681.  
  682.             Registers[REGISTER_A] = (BYTE)temp_word;
  683.             break;
  684.         case 0x44: //SUB A,D
  685.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
  686.             if ((Flags & FLAG_C) != 0) temp_word--;
  687.  
  688.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_D]), (BYTE)temp_word);
  689.             set_flags_nz((BYTE)temp_word);
  690.             set_flag_c((WORD)temp_word);
  691.  
  692.             Registers[REGISTER_A] = (BYTE)temp_word;
  693.             break;
  694.         case 0x54: //SUB A,E
  695.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
  696.             if ((Flags & FLAG_C) != 0) temp_word--;
  697.  
  698.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_E]), (BYTE)temp_word);
  699.             set_flags_nz((BYTE)temp_word);
  700.             set_flag_c((WORD)temp_word);
  701.  
  702.             Registers[REGISTER_A] = (BYTE)temp_word;
  703.             break;
  704.         case 0x64: //SUB A,F
  705.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_F];
  706.             if ((Flags & FLAG_C) != 0) temp_word--;
  707.  
  708.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_F]), (BYTE)temp_word);
  709.             set_flags_nz((BYTE)temp_word);
  710.             set_flag_c((WORD)temp_word);
  711.  
  712.             Registers[REGISTER_A] = (BYTE)temp_word;
  713.             break;
  714.         ////////////////////////////////////////////////// ADI (data added to accumulator with carry) //////////////////////////////////////////////////
  715.         case 0x82: //ADI #
  716.             data = fetch();
  717.             temp_word = (WORD)Registers[REGISTER_A] + (WORD)data;
  718.             if ((Flags & FLAG_C) != 0) temp_word++;
  719.            
  720.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)data, (BYTE)temp_word);
  721.             set_flags_nz((BYTE)temp_word);
  722.             set_flag_c((WORD)temp_word);
  723.  
  724.             Registers[REGISTER_A] = (BYTE)temp_word;
  725.             break;
  726.         ////////////////////////////////////////////////// SBI (data subtracted to accumulator with carry) //////////////////////////////////////////////////
  727.         case 0x83: //SBI #
  728.             data = fetch();
  729.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)data;
  730.             if ((Flags & FLAG_C) != 0) temp_word--;
  731.  
  732.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-data), (BYTE)temp_word);
  733.             set_flags_nz((BYTE)temp_word);
  734.             set_flag_c((WORD)temp_word);
  735.  
  736.             Registers[REGISTER_A] = (BYTE)temp_word;
  737.             break;
  738.         ////////////////////////////////////////////////// AND (register bitwise AND with accumulator) //////////////////////////////////////////////////
  739.         case 0x27: //AND A,B
  740.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
  741.             set_flags_nz((BYTE)temp_word);
  742.             Registers[REGISTER_A] = (BYTE)temp_word;
  743.             break;
  744.         case 0x37: //AND A,C
  745.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
  746.             set_flags_nz((BYTE)temp_word);
  747.             Registers[REGISTER_A] = (BYTE)temp_word;
  748.             break;
  749.         case 0x47: //AND A,D
  750.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_D];
  751.             set_flags_nz((BYTE)temp_word);
  752.             Registers[REGISTER_A] = (BYTE)temp_word;
  753.             break;
  754.         case 0x57: //AND A,E
  755.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_E];
  756.             set_flags_nz((BYTE)temp_word);
  757.             Registers[REGISTER_A] = (BYTE)temp_word;
  758.             break;
  759.         case 0x67: //AND A,F
  760.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_F];
  761.             set_flags_nz((BYTE)temp_word);
  762.             Registers[REGISTER_A] = (BYTE)temp_word;
  763.             break;
  764.         ////////////////////////////////////////////////// OR (register bitwise OR with accumulator) //////////////////////////////////////////////////
  765.         case 0x26: //OR A,B
  766.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_B];
  767.             set_flags_nz((BYTE)temp_word);
  768.             Registers[REGISTER_A] = (BYTE)temp_word;
  769.             break;
  770.         case 0x36: //OR A,C
  771.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_C];
  772.             set_flags_nz((BYTE)temp_word);
  773.             Registers[REGISTER_A] = (BYTE)temp_word;
  774.             break;
  775.         case 0x46: //OR A,D
  776.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_D];
  777.             set_flags_nz((BYTE)temp_word);
  778.             Registers[REGISTER_A] = (BYTE)temp_word;
  779.             break;
  780.         case 0x56: //OR A,E
  781.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_E];
  782.             set_flags_nz((BYTE)temp_word);
  783.             Registers[REGISTER_A] = (BYTE)temp_word;
  784.             break;
  785.         case 0x66: //OR A,F
  786.             temp_word = (WORD)Registers[REGISTER_A] | (WORD)Registers[REGISTER_F];
  787.             set_flags_nz((BYTE)temp_word);
  788.             Registers[REGISTER_A] = (BYTE)temp_word;
  789.             break;
  790.         ////////////////////////////////////////////////// EOR (register bitwise XOR with accumulator) //////////////////////////////////////////////////
  791.         case 0x28: //EOR A,B
  792.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_B];
  793.             set_flags_nz((BYTE)temp_word);
  794.             Registers[REGISTER_A] = (BYTE)temp_word;
  795.             break;
  796.         case 0x38: //EOR A,C
  797.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_C];
  798.             set_flags_nz((BYTE)temp_word);
  799.             Registers[REGISTER_A] = (BYTE)temp_word;
  800.             break;
  801.         case 0x48: //EOR A,D
  802.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_D];
  803.             set_flags_nz((BYTE)temp_word);
  804.             Registers[REGISTER_A] = (BYTE)temp_word;
  805.             break;
  806.         case 0x58: //EOR A,E
  807.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_E];
  808.             set_flags_nz((BYTE)temp_word);
  809.             Registers[REGISTER_A] = (BYTE)temp_word;
  810.             break;
  811.         case 0x68: //EOR A,F
  812.             temp_word = (WORD)Registers[REGISTER_A] ^ (WORD)Registers[REGISTER_F];
  813.             set_flags_nz((BYTE)temp_word);
  814.             Registers[REGISTER_A] = (BYTE)temp_word;
  815.             break;
  816.         ////////////////////////////////////////////////// BT (register bit tested with accumulator) //////////////////////////////////////////////////
  817.         case 0x29: //BT A,B
  818.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_B];
  819.             set_flags_nz((BYTE)temp_word);
  820.             break;
  821.         case 0x39: //BT A,C
  822.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_C];
  823.             set_flags_nz((BYTE)temp_word);
  824.             break;
  825.         case 0x49: //BT A,D
  826.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_D];
  827.             set_flags_nz((BYTE)temp_word);
  828.             break;
  829.         case 0x59: //BT A,E
  830.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_E];
  831.             set_flags_nz((BYTE)temp_word);
  832.             break;
  833.         case 0x69: //BT A,F
  834.             temp_word = (WORD)Registers[REGISTER_A] & (WORD)Registers[REGISTER_F];
  835.             set_flags_nz((BYTE)temp_word);
  836.             break;
  837.         ////////////////////////////////////////////////// CMP (register compared to accumulator) //////////////////////////////////////////////////
  838.         case 0x25: //CMP A,B
  839.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
  840.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_B]), (BYTE)temp_word);
  841.             set_flags_nz((BYTE)temp_word);
  842.             set_flag_c((WORD)temp_word);
  843.             break;
  844.         case 0x35: //CMP A,C
  845.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
  846.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_C]), (BYTE)temp_word);
  847.             set_flags_nz((BYTE)temp_word);
  848.             set_flag_c((WORD)temp_word);
  849.             break;
  850.         case 0x45: //CMP A,D
  851.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
  852.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_D]), (BYTE)temp_word);
  853.             set_flags_nz((BYTE)temp_word);
  854.             set_flag_c((WORD)temp_word);
  855.             break;
  856.         case 0x55: //CMP A,E
  857.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
  858.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_E]), (BYTE)temp_word);
  859.             set_flags_nz((BYTE)temp_word);
  860.             set_flag_c((WORD)temp_word);
  861.             break;
  862.         case 0x65: //CMP A,F
  863.             temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_F];
  864.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-Registers[REGISTER_F]), (BYTE)temp_word);
  865.             set_flags_nz((BYTE)temp_word);
  866.             set_flag_c((WORD)temp_word);
  867.             break;
  868.         ////////////////////////////////////////////////// CPI (data compared to accumulator) //////////////////////////////////////////////////
  869.         case 0x84: //CPI #
  870.             data = fetch();
  871.             temp_word = (WORD)Registers[REGISTER_A] - data;
  872.             set_flag_v((BYTE)Registers[REGISTER_A], (BYTE)(-data), (BYTE)temp_word);
  873.             set_flags_nz((BYTE)temp_word);
  874.             set_flag_c((WORD)temp_word);
  875.             break;
  876.         ////////////////////////////////////////////////// ANI (data bitwise AND with accumulator) //////////////////////////////////////////////////
  877.         case 0x86: //ANI #
  878.             data = fetch();
  879.             temp_word = (WORD)data & (WORD)Registers[REGISTER_A];
  880.             set_flags_nz((BYTE)temp_word);
  881.             Registers[REGISTER_A] = (BYTE)temp_word;
  882.             break;
  883.         ////////////////////////////////////////////////// ORI (data bitwise OR with accumulator) //////////////////////////////////////////////////
  884.         case 0x85: //ORI #
  885.             data = fetch();
  886.             temp_word = (WORD)data | (WORD)Registers[REGISTER_A];
  887.             set_flags_nz((BYTE)temp_word);
  888.             Registers[REGISTER_A] = (BYTE)temp_word;
  889.             break;
  890.         ////////////////////////////////////////////////// XRI (data bitwise XOR with accumulator) //////////////////////////////////////////////////
  891.         case 0x87: //XRI #
  892.             data = fetch();
  893.             temp_word = (WORD)data ^ (WORD)Registers[REGISTER_A];
  894.             set_flags_nz((BYTE)temp_word);
  895.             Registers[REGISTER_A] = (BYTE)temp_word;
  896.             break;
  897.         ////////////////////////////////////////////////// CSA (transfers status register to accumulator) //////////////////////////////////////////////////
  898.         case 0x0F: //CSA impl
  899.             Registers[REGISTER_A] = Flags;
  900.             break;
  901.         ////////////////////////////////////////////////// LDX (loads memory into register X) //////////////////////////////////////////////////
  902.         case 0x31: //LDX #
  903.             Index_Registers[REGISTER_X] = fetch();
  904.             set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  905.             break;
  906.         case 0x41: //LDX abs
  907.             address = address_abs();
  908.             if (address >= 0 && address < MEMORY_SIZE) {
  909.                 Index_Registers[REGISTER_X] = Memory[address];
  910.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  911.             }
  912.             break;
  913.         case 0x51: //LDX abs,X
  914.             address = address_absX();
  915.             if (address >= 0 && address < MEMORY_SIZE) {
  916.                 Index_Registers[REGISTER_X] = Memory[address];
  917.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  918.             }
  919.             break;
  920.         case 0x61: //LDX abs,Y
  921.             address = address_absY();
  922.             if (address >= 0 && address < MEMORY_SIZE) {
  923.                 Index_Registers[REGISTER_X] = Memory[address];
  924.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  925.             }
  926.             break;
  927.         case 0x71: //LDX abs,XY
  928.             address = address_absXY();
  929.             if (address >= 0 && address < MEMORY_SIZE) {
  930.                 Index_Registers[REGISTER_X] = Memory[address];
  931.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  932.             }
  933.             break;
  934.         case 0x81: //LDX (ind),XY
  935.             address = address_indXY();
  936.             if (address >= 0 && address < MEMORY_SIZE) {
  937.                 Index_Registers[REGISTER_A] = Memory[address];
  938.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  939.             }
  940.             break;
  941.         ////////////////////////////////////////////////// STX (stores register X into memory) //////////////////////////////////////////////////
  942.         case 0x02: //STX abs
  943.             address = address_abs();
  944.             if (address >= 0 && address < MEMORY_SIZE) {
  945.                 Memory[address] = Index_Registers[REGISTER_X];
  946.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  947.             }
  948.             break;
  949.         case 0x12: //STX abs,X
  950.             address = address_absX();
  951.             if (address >= 0 && address < MEMORY_SIZE) {
  952.                 Memory[address] = Index_Registers[REGISTER_X];
  953.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  954.             }
  955.             break;
  956.         case 0x22: //STX abs,Y
  957.             address = address_absY();
  958.             if (address >= 0 && address < MEMORY_SIZE) {
  959.                 Memory[address] = Index_Registers[REGISTER_X];
  960.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  961.             }
  962.             break;
  963.         case 0x32: //STX abs,XY
  964.             address = address_absXY();
  965.             if (address >= 0 && address < MEMORY_SIZE) {
  966.                 Memory[address] = Index_Registers[REGISTER_X];
  967.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  968.             }
  969.             break;
  970.         case 0x42: //STX (ind),XY
  971.             address = address_indXY();
  972.             if (address >= 0 && address < MEMORY_SIZE) {
  973.                 Memory[address] = Index_Registers[REGISTER_X];
  974.                 set_flags_nz((BYTE)Index_Registers[REGISTER_X]);
  975.             }
  976.             break;
  977.         ////////////////////////////////////////////////// MAY (transfers accumulator into register Y) //////////////////////////////////////////////////
  978.         case 0x0C: //MAY impl
  979.             Index_Registers[REGISTER_Y] = Registers[REGISTER_A];
  980.             set_flag_n((BYTE)Registers[REGISTER_A]);
  981.             break;
  982.         ////////////////////////////////////////////////// MYA (transfers register Y to accumulator) //////////////////////////////////////////////////
  983.         case 0x0D: //MYA impl
  984.             Registers[REGISTER_A] = Index_Registers[REGISTER_Y];
  985.             set_flags_nz((BYTE)Index_Registers[REGISTER_Y]);
  986.             break;
  987.         ////////////////////////////////////////////////// MAS (transfers accumulator to status register) //////////////////////////////////////////////////
  988.         case 0x0E: //MAS impl
  989.             Flags = Registers[REGISTER_A];
  990.             break;
  991.         ////////////////////////////////////////////////// INC (increment memory or accumulator) //////////////////////////////////////////////////
  992.         case 0x92: //INC abs
  993.             address = address_abs();
  994.             if (address >= 0 && address < MEMORY_SIZE) {
  995.                 Memory[address]++;
  996.                 set_flags_nz((BYTE)Memory[address]);
  997.             }
  998.             break;
  999.         case 0xA2: //INC abs,X
  1000.             address = address_absX();
  1001.             if (address >= 0 && address < MEMORY_SIZE) {
  1002.                 Memory[address]++;
  1003.                 set_flags_nz((BYTE)Memory[address]);
  1004.             }
  1005.             break;
  1006.         case 0xB2: //INC abs,Y
  1007.             address = address_absY();
  1008.             if (address >= 0 && address < MEMORY_SIZE) {
  1009.                 Memory[address]++;
  1010.                 set_flags_nz((BYTE)Memory[address]);
  1011.             }
  1012.             break;
  1013.         case 0xC2: //INC abs,XY
  1014.             address = address_absXY();
  1015.             if (address >= 0 && address < MEMORY_SIZE) {
  1016.                 Memory[address]++;
  1017.                 set_flags_nz((BYTE)Memory[address]);
  1018.             }
  1019.             break;
  1020.         ////////////////////////////////////////////////// DEC (decrement memory or accumulator) //////////////////////////////////////////////////
  1021.         case 0x93: //DEC abs
  1022.             address = address_abs();
  1023.             if (address >= 0 && address < MEMORY_SIZE) {
  1024.                 Memory[address]--;
  1025.                 set_flags_nz((BYTE)Memory[address]);
  1026.             }
  1027.             break;
  1028.         case 0xA3: //DEC abs,X
  1029.             address = address_absX();
  1030.             if (address >= 0 && address < MEMORY_SIZE) {
  1031.                 Memory[address]--;
  1032.                 set_flags_nz((BYTE)Memory[address]);
  1033.             }
  1034.             break;
  1035.         case 0xB3: //DEC abs,Y
  1036.             address = address_absY();
  1037.             if (address >= 0 && address < MEMORY_SIZE) {
  1038.                 Memory[address]--;
  1039.                 set_flags_nz((BYTE)Memory[address]);
  1040.             }
  1041.             break;
  1042.         case 0xC3: //DEC abs,XY
  1043.             address = address_absXY();
  1044.             if (address >= 0 && address < MEMORY_SIZE) {
  1045.                 Memory[address]--;
  1046.                 set_flags_nz((BYTE)Memory[address]);
  1047.             }
  1048.             break;
  1049.         ////////////////////////////////////////////////// TST (bit test memory or accumulator) //////////////////////////////////////////////////
  1050.         case 0x91: //TST abs
  1051.             address = address_abs();
  1052.             if (address >= 0 && address < MEMORY_SIZE) {
  1053.                 temp_word = (WORD)Memory[address];
  1054.                 Memory[address] = (BYTE)temp_word;
  1055.                 set_flags_nz((BYTE)temp_word);
  1056.             }
  1057.             break;
  1058.         case 0xA1: //TST abs,X
  1059.             address = address_absX();
  1060.             if (address >= 0 && address < MEMORY_SIZE) {
  1061.                 temp_word = (WORD)Memory[address];
  1062.                 Memory[address] = (BYTE)temp_word;
  1063.                 set_flags_nz((BYTE)temp_word);
  1064.             }
  1065.             break;
  1066.         case 0xB1: //TST abs,Y
  1067.             address = address_absY();
  1068.             if (address >= 0 && address < MEMORY_SIZE) {
  1069.                 temp_word = (WORD)Memory[address];
  1070.                 Memory[address] = (BYTE)temp_word;
  1071.                 set_flags_nz((BYTE)temp_word);
  1072.             }
  1073.             break;
  1074.         case 0xC1: //TST abs,XY
  1075.             address = address_absXY();
  1076.             if (address >= 0 && address < MEMORY_SIZE) {
  1077.                 temp_word = (WORD)Memory[address];
  1078.                 Memory[address] = (BYTE)temp_word;
  1079.                 set_flags_nz((BYTE)temp_word);
  1080.             }
  1081.             break;
  1082.         ////////////////////////////////////////////////// TSTA (bit test memory or accumulator) //////////////////////////////////////////////////
  1083.         case 0xD1: //TSTA A
  1084.             temp_word = (WORD)Registers[REGISTER_A];
  1085.             set_flags_nz((BYTE)temp_word);
  1086.             Registers[REGISTER_A] = (BYTE)temp_word;
  1087.             break;
  1088.         ////////////////////////////////////////////////// INCA (increment memory or accumulator) //////////////////////////////////////////////////
  1089.         case 0xD2: //INCA A
  1090.             Registers[REGISTER_A]++;
  1091.             set_flags_nz((BYTE)Registers[REGISTER_A]);
  1092.             break;
  1093.         ////////////////////////////////////////////////// DECA (decrement memory or accumulator) //////////////////////////////////////////////////
  1094.         case 0xD3: //DECA A
  1095.             Registers[REGISTER_A]--;
  1096.             set_flags_nz((BYTE)Registers[REGISTER_A]);
  1097.             break;
  1098.         ////////////////////////////////////////////////// INX (increment register X) //////////////////////////////////////////////////
  1099.         case 0xE2: //INX impl
  1100.             Index_Registers[REGISTER_X]++;
  1101.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1102.             break;
  1103.         ////////////////////////////////////////////////// DEX (decrement register X) //////////////////////////////////////////////////
  1104.         case 0xE1: //DEX impl
  1105.             Index_Registers[REGISTER_X]--;
  1106.             set_flag_z((BYTE)Index_Registers[REGISTER_X]);
  1107.             break;
  1108.         ////////////////////////////////////////////////// INCY (increment register Y) //////////////////////////////////////////////////
  1109.         case 0xE4: //INCY impl
  1110.             Index_Registers[REGISTER_Y]++;
  1111.             set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
  1112.             break;
  1113.         ////////////////////////////////////////////////// DEY (decrement register Y) //////////////////////////////////////////////////
  1114.         case 0xE3: //DEY impl
  1115.             Index_Registers[REGISTER_Y]--;
  1116.             set_flag_z((BYTE)Index_Registers[REGISTER_Y]);
  1117.             break;
  1118.         ////////////////////////////////////////////////// ASL (arithmetic shift left memory or accumulator) //////////////////////////////////////////////////
  1119.         case 0x96: //ASL abs
  1120.             address = address_abs();
  1121.             if (address >= 0 && address < MEMORY_SIZE) {
  1122.                 temp_word = Memory[address] << 1;
  1123.                 Memory[address] = (BYTE)temp_word;
  1124.                 set_flags_nz((BYTE)temp_word);
  1125.                 set_flag_c((WORD)temp_word);
  1126.             }
  1127.             break;
  1128.         case 0xA6: //ASL abs,X
  1129.             address = address_absX();
  1130.             if (address >= 0 && address < MEMORY_SIZE) {
  1131.                 temp_word = Memory[address] << 1;
  1132.                 Memory[address] = (BYTE)temp_word;
  1133.                 set_flags_nz((BYTE)temp_word);
  1134.                 set_flag_c((WORD)temp_word);
  1135.             }
  1136.             break;
  1137.         case 0xB6: //ASL abs,Y
  1138.             address = address_absY();
  1139.             if (address >= 0 && address < MEMORY_SIZE) {
  1140.                 temp_word = Memory[address] << 1;
  1141.                 Memory[address] = (BYTE)temp_word;
  1142.                 set_flags_nz((BYTE)temp_word);
  1143.                 set_flag_c((WORD)temp_word);
  1144.             }
  1145.             break;
  1146.         case 0xC6: //ASL abs,XY
  1147.             address = address_absXY();
  1148.             if (address >= 0 && address < MEMORY_SIZE) {
  1149.                 temp_word = Memory[address] << 1;
  1150.                 Memory[address] = (BYTE)temp_word;
  1151.                 set_flags_nz((BYTE)temp_word);
  1152.                 set_flag_c((WORD)temp_word);
  1153.             }
  1154.             break;
  1155.         ////////////////////////////////////////////////// ASLA (arithmetic shift left memory or accumulator) //////////////////////////////////////////////////
  1156.         case 0xD6: //ASLA A
  1157.             temp_word = Registers[REGISTER_A] << 1;
  1158.             Registers[REGISTER_A] = (BYTE)temp_word;
  1159.             set_flags_nz((BYTE)temp_word);
  1160.             set_flag_c((WORD)temp_word);
  1161.             break;
  1162.         ////////////////////////////////////////////////// SAR (arithmetic shift right memory or accumulator) //////////////////////////////////////////////////
  1163.         case 0x97: //SAR abs
  1164.             address = address_abs();
  1165.             if (address >= 0 && address < MEMORY_SIZE) {
  1166.                 temp_word = Memory[address] >> 1;
  1167.                 Memory[address] = (BYTE)temp_word;
  1168.                 set_flags_nz((BYTE)temp_word);
  1169.                 set_flag_c((WORD)temp_word);
  1170.             }
  1171.             break;
  1172.         case 0xA7: //SAR abs,X
  1173.             address = address_absX();
  1174.             if (address >= 0 && address < MEMORY_SIZE) {
  1175.                 temp_word = Memory[address] >> 1;
  1176.                 Memory[address] = (BYTE)temp_word;
  1177.                 set_flags_nz((BYTE)temp_word);
  1178.                 set_flag_c((WORD)temp_word);
  1179.             }
  1180.             break;
  1181.         case 0xB7: //SAR abs,Y
  1182.             address = address_absY();
  1183.             if (address >= 0 && address < MEMORY_SIZE) {
  1184.                 temp_word = Memory[address] >> 1;
  1185.                 Memory[address] = (BYTE)temp_word;
  1186.                 set_flags_nz((BYTE)temp_word);
  1187.                 set_flag_c((WORD)temp_word);
  1188.             }
  1189.             break;
  1190.         case 0xC7: //SAR abs,XY
  1191.             address = address_absXY();
  1192.             if (address >= 0 && address < MEMORY_SIZE) {
  1193.                 temp_word = Memory[address] >> 1;
  1194.                 Memory[address] = (BYTE)temp_word;
  1195.                 set_flags_nz((BYTE)temp_word);
  1196.                 set_flag_c((WORD)temp_word);
  1197.             }
  1198.             break;
  1199.         ////////////////////////////////////////////////// SARA (arithmetic shift right memory or accumulator) //////////////////////////////////////////////////
  1200.         case 0xD7: //SARA A
  1201.             temp_word = Registers[REGISTER_A] >> 1;
  1202.             Registers[REGISTER_A] = (BYTE)temp_word;
  1203.             set_flags_nz((BYTE)temp_word);
  1204.             set_flag_c((WORD)temp_word);
  1205.             break;
  1206.         ////////////////////////////////////////////////// RCR (rotate right through carry memory or accumulator) //////////////////////////////////////////////////
  1207.         case 0x94: //RCR abs
  1208.             address = address_abs();
  1209.             if (address >= 0 && address < MEMORY_SIZE) {
  1210.                 saved_flags = Flags;
  1211.                 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1212.                 else Flags = Flags & (0xFF - FLAG_C);
  1213.                 Memory[address] = (Memory[address] >> 1) & 0x7F;
  1214.                 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
  1215.                 set_flags_nz((BYTE)Memory[address]);
  1216.             }
  1217.             break;
  1218.         case 0xA4: //RCR abs,X
  1219.             address = address_absX();
  1220.             if (address >= 0 && address < MEMORY_SIZE) {
  1221.                 saved_flags = Flags;
  1222.                 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1223.                 else Flags = Flags & (0xFF - FLAG_C);
  1224.                 Memory[address] = (Memory[address] >> 1) & 0x7F;
  1225.                 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
  1226.                 set_flags_nz((BYTE)Memory[address]);
  1227.             }
  1228.             break;
  1229.         case 0xB4: //RCR abs,Y
  1230.             address = address_absY();
  1231.             if (address >= 0 && address < MEMORY_SIZE) {
  1232.                 saved_flags = Flags;
  1233.                 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1234.                 else Flags = Flags & (0xFF - FLAG_C);
  1235.                 Memory[address] = (Memory[address] >> 1) & 0x7F;
  1236.                 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
  1237.                 set_flags_nz((BYTE)Memory[address]);
  1238.             }
  1239.             break;
  1240.         case 0xC4: //RCR abs,XY
  1241.             address = address_absXY();
  1242.             if (address >= 0 && address < MEMORY_SIZE) {
  1243.                 saved_flags = Flags;
  1244.                 if ((Memory[address] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1245.                 else Flags = Flags & (0xFF - FLAG_C);
  1246.                 Memory[address] = (Memory[address] >> 1) & 0x7F;
  1247.                 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x80;
  1248.                 set_flags_nz((BYTE)Memory[address]);
  1249.             }
  1250.             break;
  1251.         ////////////////////////////////////////////////// RCRA (rotate right through carry memory or accumulator) //////////////////////////////////////////////////
  1252.         case 0xD4: //RCRA A
  1253.             if ((Registers[REGISTER_A] & 0x01) == 0x01) Flags = Flags | FLAG_C;
  1254.             else Flags = Flags & (0xFF - FLAG_C);
  1255.             Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
  1256.             if ((Flags & FLAG_C) == FLAG_C) Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
  1257.             set_flags_nz((BYTE)Registers[REGISTER_A]);
  1258.             break;
  1259.         ////////////////////////////////////////////////// RLC (rotate left through carry memory or accumulator) //////////////////////////////////////////////////
  1260.         case 0x95: //RLC abs
  1261.             address = address_abs();
  1262.             if (address >= 0 && address < MEMORY_SIZE) {
  1263.                 saved_flags = Flags;
  1264.                 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1265.                 else Flags = Flags & (0xFF - FLAG_C);
  1266.                 Memory[address] = (Memory[address] << 1) & 0xFE;
  1267.                 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
  1268.                 set_flags_nz((BYTE)Memory[address]);
  1269.             }
  1270.             break;
  1271.         case 0xA5: //RLC abs,X
  1272.             address = address_absX();
  1273.             if (address >= 0 && address < MEMORY_SIZE) {
  1274.                 saved_flags = Flags;
  1275.                 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1276.                 else Flags = Flags & (0xFF - FLAG_C);
  1277.                 Memory[address] = (Memory[address] << 1) & 0xFE;
  1278.                 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
  1279.                 set_flags_nz((BYTE)Memory[address]);
  1280.             }
  1281.             break;
  1282.         case 0xB5: //RLC abs,Y
  1283.             address = address_absY();
  1284.             if (address >= 0 && address < MEMORY_SIZE) {
  1285.                 saved_flags = Flags;
  1286.                 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1287.                 else Flags = Flags & (0xFF - FLAG_C);
  1288.                 Memory[address] = (Memory[address] << 1) & 0xFE;
  1289.                 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
  1290.                 set_flags_nz((BYTE)Memory[address]);
  1291.             }
  1292.             break;
  1293.         case 0xC5: //RLC abs,XY
  1294.             address = address_absXY();
  1295.             if (address >= 0 && address < MEMORY_SIZE) {
  1296.                 saved_flags = Flags;
  1297.                 if ((Memory[address] & 0x80) == 0x80) Flags = Flags | FLAG_C;
  1298.                 else Flags = Flags & (0xFF - FLAG_C);
  1299.                 Memory[address] = (Memory[address] << 1) & 0xFE;
  1300.                 if ((saved_flags & FLAG_C) == FLAG_C) Memory[address] = Memory[address] | 0x01;
  1301.                 set_flags_nz((BYTE)Memory[address]);
  1302.             }
  1303.             break;
  1304.         ////////////////////////////////////////////////// RLCA (rotate left through carry memory or accumulator) //////////////////////////////////////////////////
  1305.         case 0xD5: //RLCA A
  1306.             if ((Registers[REGISTER_A] & 0x80) == 0x80) Flags = Flags | FLAG_C; //set carry based on MSB of A
  1307.             else Flags = Flags & (0xFF - FLAG_C);
  1308.            
  1309.             Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
  1310.             if ((Flags & FLAG_C) == FLAG_C) Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
  1311.            
  1312.             set_flags_nz((BYTE)Registers[REGISTER_A]);
  1313.             break;
  1314.         ////////////////////////////////////////////////// RAL (rotate left without carry memory or accumulator) //////////////////////////////////////////////////
  1315.         case 0x99: //RAL abs
  1316.             address = address_abs();
  1317.             if (address >= 0 && address < MEMORY_SIZE) {
  1318.                 temp_word = (Memory[address] << 1);
  1319.                 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1320.                 Memory[address] = (BYTE)temp_word;
  1321.                 set_flags_nz((BYTE)Memory[address]);
  1322.             }
  1323.             break;
  1324.         case 0xA9: //RAL abs,X
  1325.             address = address_absX();
  1326.             if (address >= 0 && address < MEMORY_SIZE) {
  1327.                 temp_word = (Memory[address] << 1);
  1328.                 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1329.                 Memory[address] = (BYTE)temp_word;
  1330.                 set_flags_nz((BYTE)Memory[address]);
  1331.             }
  1332.             break;
  1333.         case 0xB9: //RAL abs,Y
  1334.             address = address_absY();
  1335.             if (address >= 0 && address < MEMORY_SIZE) {
  1336.                 temp_word = (Memory[address] << 1);
  1337.                 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1338.                 Memory[address] = (BYTE)temp_word;
  1339.                 set_flags_nz((BYTE)Memory[address]);
  1340.             }
  1341.             break;
  1342.         case 0xC9: //RAL abs,XY
  1343.             address = address_absXY();
  1344.             if (address >= 0 && address < MEMORY_SIZE) {
  1345.                 temp_word = (Memory[address] << 1);
  1346.                 if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1347.                 Memory[address] = (BYTE)temp_word;
  1348.                 set_flags_nz((BYTE)Memory[address]);
  1349.             }
  1350.             break;
  1351.         ////////////////////////////////////////////////// RALA (rotate left without carry memory or accumulator) //////////////////////////////////////////////////
  1352.         case 0xD9: //RALA A
  1353.             temp_word = (Registers[REGISTER_A] << 1);
  1354.             if (temp_word >= 0x100) temp_word = temp_word | 0x01;
  1355.             Registers[REGISTER_A] = (BYTE)temp_word;
  1356.             set_flags_nz((BYTE)Registers[REGISTER_A]);
  1357.             break;
  1358.         ////////////////////////////////////////////////// ROR (rotate right without carry memory or accumulator) //////////////////////////////////////////////////
  1359.         case 0x9A: //ROR abs
  1360.             address = address_abs();
  1361.             if (address >= 0 && address < MEMORY_SIZE) {
  1362.                 temp_word = (Memory[address] >> 1);
  1363.                 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
  1364.                 Memory[address] = (BYTE)temp_word;
  1365.                 set_flags_nz((BYTE)Memory[address]);
  1366.             }
  1367.             break;
  1368.         case 0xAA: //ROR abs,X
  1369.             address = address_absX();
  1370.             if (address >= 0 && address < MEMORY_SIZE) {
  1371.                 temp_word = (Memory[address] >> 1);
  1372.                 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
  1373.                 Memory[address] = (BYTE)temp_word;
  1374.                 set_flags_nz((BYTE)Memory[address]);
  1375.             }
  1376.             break;
  1377.         case 0xBA: //ROR abs,Y
  1378.             address = address_absY();
  1379.             if (address >= 0 && address < MEMORY_SIZE) {
  1380.                 temp_word = (Memory[address] >> 1);
  1381.                 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
  1382.                 Memory[address] = (BYTE)temp_word;
  1383.                 set_flags_nz((BYTE)Memory[address]);
  1384.             }
  1385.             break;
  1386.         case 0xCA: //ROR abs,XY
  1387.             address = address_absXY();
  1388.             if (address >= 0 && address < MEMORY_SIZE) {
  1389.                 temp_word = (Memory[address] >> 1);
  1390.                 if ((Memory[address] & 0x01) != 0) temp_word = temp_word | 0x80;
  1391.                 Memory[address] = (BYTE)temp_word;
  1392.                 set_flags_nz((BYTE)Memory[address]);
  1393.             }
  1394.             break;
  1395.         ////////////////////////////////////////////////// RORA (rotate right without carry memory or accumulator) //////////////////////////////////////////////////
  1396.         case 0xDA: //RORA A
  1397.             temp_word = (Registers[REGISTER_A] >> 1);
  1398.             if ((Registers[REGISTER_A] & 0x01) != 0) temp_word = temp_word | 0x80;
  1399.             Registers[REGISTER_A] = (BYTE)temp_word;
  1400.             set_flags_nz((BYTE)Registers[REGISTER_A]);
  1401.             break;
  1402.         ////////////////////////////////////////////////// COM (negate memory or accumulator) //////////////////////////////////////////////////
  1403.         case 0x98: //COM abs
  1404.             address = address_abs();
  1405.             if (address >= 0 && address < MEMORY_SIZE) {
  1406.                 temp_word = ~Memory[address]; // ~ is the bitwise complement
  1407.                 set_flag_c((WORD)temp_word);
  1408.                 Memory[address] = (BYTE)temp_word;
  1409.                 set_flags_nz((BYTE)Memory[address]);
  1410.             }
  1411.             break;
  1412.         case 0xA8: //COM abs,X
  1413.             address = address_absX();
  1414.             if (address >= 0 && address < MEMORY_SIZE) {
  1415.                 temp_word = ~Memory[address];
  1416.                 set_flag_c((WORD)temp_word);
  1417.                 Memory[address] = (BYTE)temp_word;
  1418.                 set_flags_nz((BYTE)Memory[address]);
  1419.             }
  1420.             break;
  1421.         case 0xB8: //COM abs,Y
  1422.             address = address_absY();
  1423.             if (address >= 0 && address < MEMORY_SIZE) {
  1424.                 temp_word = ~Memory[address];
  1425.                 set_flag_c((WORD)temp_word);
  1426.                 Memory[address] = (BYTE)temp_word;
  1427.                 set_flags_nz((BYTE)Memory[address]);
  1428.             }
  1429.             break;
  1430.         case 0xC8: //COM abs,XY
  1431.             address = address_absXY();
  1432.             if (address >= 0 && address < MEMORY_SIZE) {
  1433.                 temp_word = ~Memory[address];
  1434.                 set_flag_c((WORD)temp_word);
  1435.                 Memory[address] = (BYTE)temp_word;
  1436.                 set_flags_nz((BYTE)Memory[address]);
  1437.             }
  1438.             break;
  1439.         ////////////////////////////////////////////////// COMA (negate memory or accumulator) //////////////////////////////////////////////////
  1440.         case 0xD8: //COMA A
  1441.             temp_word = ~Registers[REGISTER_A];
  1442.             set_flags_nz((BYTE)temp_word);
  1443.             set_flag_c((WORD)temp_word);
  1444.             Registers[REGISTER_A] = (BYTE)temp_word;
  1445.             break;
  1446.         ////////////////////////////////////////////////// LX (loads memory into register pair) //////////////////////////////////////////////////
  1447.         case 0x9B: //LX AB,#
  1448.             HB = fetch();
  1449.             LB = fetch();
  1450.             Registers[REGISTER_A] = LB;
  1451.             Registers[REGISTER_B] = HB;
  1452.             temp_word = ((WORD)LB << 8) + (WORD)HB;
  1453.             set_flags_nz((BYTE)temp_word);
  1454.             break;
  1455.         ////////////////////////////////////////////////// JMP (loads memory into ProgramCounter) //////////////////////////////////////////////////
  1456.         case 0xEA: //JMP abs
  1457.             address = address_abs();
  1458.             ProgramCounter = address;
  1459.             break;
  1460.         ////////////////////////////////////////////////// JSR (jump to subroutine) //////////////////////////////////////////////////
  1461.         case 0xE9: //JSR abs
  1462.             address = address_abs();
  1463.             if ((StackPointer >= 2) && (StackPointer < MEMORY_SIZE)) {
  1464.                 Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1465.                 StackPointer--;
  1466.                 Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1467.                 StackPointer--;
  1468.             }
  1469.             ProgramCounter = address;
  1470.             break;
  1471.         ////////////////////////////////////////////////// RTN (return from subroutine) //////////////////////////////////////////////////
  1472.         case 0xDB: //RTN impl
  1473.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 2)) {
  1474.                 StackPointer++;
  1475.                 HB = Memory[StackPointer];
  1476.                 StackPointer++;
  1477.                 LB = Memory[StackPointer];
  1478.             }
  1479.             ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
  1480.             break;
  1481.         ////////////////////////////////////////////////// BRA (branch always) //////////////////////////////////////////////////
  1482.         case 0xF0: //BRA rel
  1483.             LB = fetch();
  1484.             offset = (WORD)LB;
  1485.             if ((offset & 0x80) != 0) offset += 0xFF00;
  1486.             address = ProgramCounter + offset;
  1487.             ProgramCounter = address;
  1488.             break;
  1489.         ////////////////////////////////////////////////// BCC (branch on carry clear) //////////////////////////////////////////////////
  1490.         case 0xF1: //BCC rel
  1491.             LB = fetch();
  1492.             if (FLAG_C == 0x00) {
  1493.                 offset = (WORD)LB;
  1494.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1495.                 address = ProgramCounter + offset;
  1496.                 ProgramCounter = address;
  1497.             } else fetch();
  1498.             break;
  1499.         ////////////////////////////////////////////////// BCS (branch on carry set) //////////////////////////////////////////////////
  1500.         case 0xF2: //BCS rel
  1501.             LB = fetch();
  1502.             if (FLAG_C == 0x01) {
  1503.                 offset = (WORD)LB;
  1504.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1505.                 address = ProgramCounter + offset;
  1506.                 ProgramCounter = address;
  1507.             } else fetch();
  1508.             break;
  1509.         ////////////////////////////////////////////////// BNE (branch on result not zero) //////////////////////////////////////////////////
  1510.         case 0xF3: //BNE rel
  1511.             LB = fetch();
  1512.             if (FLAG_Z == 0x00) {
  1513.                 offset = (WORD)LB;
  1514.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1515.                 address = ProgramCounter + offset;
  1516.                 ProgramCounter = address;
  1517.             } else fetch();
  1518.             break;
  1519.         ////////////////////////////////////////////////// BEQ (branch on result equal to zero) //////////////////////////////////////////////////
  1520.         case 0xF4: //BEQ rel
  1521.             LB = fetch();
  1522.             if (FLAG_Z == 0x01) {
  1523.                 offset = (WORD)LB;
  1524.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1525.                 address = ProgramCounter + offset;
  1526.                 ProgramCounter = address;
  1527.             } else fetch();
  1528.             break;
  1529.         ////////////////////////////////////////////////// BVC (branch on overflow clear) //////////////////////////////////////////////////
  1530.         case 0xF5: //BVC rel
  1531.             LB = fetch();
  1532.             if (FLAG_V == 0x00) {
  1533.                 offset = (WORD)LB;
  1534.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1535.                 address = ProgramCounter + offset;
  1536.                 ProgramCounter = address;
  1537.             } else fetch();
  1538.             break;
  1539.         ////////////////////////////////////////////////// BVS (branch on overflow set) //////////////////////////////////////////////////
  1540.         case 0xF6: //BVS rel
  1541.             LB = fetch();
  1542.             if (FLAG_V == 0x01) {
  1543.                 offset = (WORD)LB;
  1544.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1545.                 address = ProgramCounter + offset;
  1546.                 ProgramCounter = address;
  1547.             } else fetch();
  1548.             break;
  1549.         ////////////////////////////////////////////////// BMI (branch on negative result) //////////////////////////////////////////////////
  1550.         case 0xF7: //BMI rel
  1551.             LB = fetch();
  1552.             if (FLAG_N == 0x01) {
  1553.                 offset = (WORD)LB;
  1554.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1555.                 address = ProgramCounter + offset;
  1556.                 ProgramCounter = address;
  1557.             } else fetch();
  1558.             break;
  1559.         ////////////////////////////////////////////////// BPL (branch on positive result) //////////////////////////////////////////////////
  1560.         case 0xF8: //BPL rel
  1561.             LB = fetch();
  1562.             if (FLAG_N == 0x00) {
  1563.                 offset = (WORD)LB;
  1564.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1565.                 address = ProgramCounter + offset;
  1566.                 ProgramCounter = address;
  1567.             } else fetch();
  1568.             break;
  1569.         ////////////////////////////////////////////////// BGE (branch on result <= 0) //////////////////////////////////////////////////
  1570.         case 0xF9: //BGE rel
  1571.             LB = fetch();
  1572.             if ((FLAG_N ^ FLAG_V) == 0x00) {
  1573.                 offset = (WORD)LB;
  1574.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1575.                 address = ProgramCounter + offset;
  1576.                 ProgramCounter = address;
  1577.             } else fetch();
  1578.             break;
  1579.         ////////////////////////////////////////////////// BLE (branch on result >= 0) //////////////////////////////////////////////////
  1580.         case 0xFA: //BLE rel
  1581.             LB = fetch();
  1582.             if ((FLAG_Z | FLAG_N ^ FLAG_V) == 0x01) {
  1583.                 offset = (WORD)LB;
  1584.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1585.                 address = ProgramCounter + offset;
  1586.                 ProgramCounter = address;
  1587.             } else fetch();
  1588.             break;
  1589.         ////////////////////////////////////////////////// BGT (branch on result < 0) //////////////////////////////////////////////////
  1590.         case 0xFB: //BGT rel
  1591.             LB = fetch();
  1592.             if ((FLAG_Z | FLAG_N ^ FLAG_V) == 0x00) {
  1593.                 offset = (WORD)LB;
  1594.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1595.                 address = ProgramCounter + offset;
  1596.                 ProgramCounter = address;
  1597.             } else fetch();
  1598.             break;
  1599.         ////////////////////////////////////////////////// BLT (branch on result > 0) //////////////////////////////////////////////////
  1600.         case 0xFC: //BLT rel
  1601.             LB = fetch();
  1602.             if ((FLAG_N ^ FLAG_V) == 0x01) {
  1603.                 offset = (WORD)LB;
  1604.                 if ((offset & 0x80) != 0) offset += 0xFF00;
  1605.                 address = ProgramCounter + offset;
  1606.                 ProgramCounter = address;
  1607.             } else fetch();
  1608.             break;
  1609.         ////////////////////////////////////////////////// PUSH (pushes register onto stack) //////////////////////////////////////////////////
  1610.         case 0x9E: //PUSH A
  1611.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1612.                 Memory[StackPointer] = Registers[REGISTER_A];
  1613.                 StackPointer--;
  1614.             }
  1615.             break;
  1616.         case 0xAE: //PUSH FL
  1617.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1618.                 Memory[StackPointer] = Flags;
  1619.                 StackPointer--;
  1620.             }
  1621.             break;
  1622.         case 0xBE: //PUSH B
  1623.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1624.                 Memory[StackPointer] = Registers[REGISTER_B];
  1625.                 StackPointer--;
  1626.             }
  1627.             break;
  1628.         case 0xCE: //PUSH C
  1629.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1630.                 Memory[StackPointer] = Registers[REGISTER_C];
  1631.                 StackPointer--;
  1632.             }
  1633.             break;
  1634.         case 0xDE: //PUSH D
  1635.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1636.                 Memory[StackPointer] = Registers[REGISTER_D];
  1637.                 StackPointer--;
  1638.             }
  1639.             break;
  1640.         case 0xEE: //PUSH E
  1641.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1642.                 Memory[StackPointer] = Registers[REGISTER_E];
  1643.                 StackPointer--;
  1644.             }
  1645.             break;
  1646.         case 0xFE: //PUSH F
  1647.             if ((StackPointer >= 1) && (StackPointer < MEMORY_SIZE)) {
  1648.                 Memory[StackPointer] = Registers[REGISTER_F];
  1649.                 StackPointer--;
  1650.             }
  1651.             break;
  1652.         ////////////////////////////////////////////////// POP (pop top of stack into register) //////////////////////////////////////////////////
  1653.         case 0x9F: //POP A
  1654.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1655.                 StackPointer++;
  1656.                 Registers[REGISTER_A] = Memory[StackPointer];
  1657.             }
  1658.             break;
  1659.         case 0xAF: //POP FL
  1660.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1661.                 StackPointer++;
  1662.                 Flags = Memory[StackPointer];
  1663.             }
  1664.             break;
  1665.         case 0xBF: //POP B
  1666.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1667.                 StackPointer++;
  1668.                 Registers[REGISTER_B] = Memory[StackPointer];
  1669.             }
  1670.             break;
  1671.         case 0xCF: //POP C
  1672.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1673.                 StackPointer++;
  1674.                 Registers[REGISTER_C] = Memory[StackPointer];
  1675.             }
  1676.             break;
  1677.         case 0xDF: //POP D
  1678.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1679.                 StackPointer++;
  1680.                 Registers[REGISTER_D] = Memory[StackPointer];
  1681.             }
  1682.             break;
  1683.         case 0xEF: //POP E
  1684.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE -1 )) {
  1685.                 StackPointer++;
  1686.                 Registers[REGISTER_E] = Memory[StackPointer];
  1687.             }
  1688.             break;
  1689.         case 0xFF: //POP F
  1690.             if ((StackPointer >= 0) && (StackPointer < MEMORY_SIZE - 1)) {
  1691.                 StackPointer++;
  1692.                 Registers[REGISTER_F] = Memory[StackPointer];
  1693.             }
  1694.             break;
  1695.         ////////////////////////////////////////////////// SWI (software interrupt) //////////////////////////////////////////////////
  1696.         case 0x16: //SWI impl
  1697.            
  1698.             break;
  1699.         ////////////////////////////////////////////////// RTN (return from software interrupt) //////////////////////////////////////////////////
  1700.         case 0x17: //RTN impl
  1701.            
  1702.             break;
  1703.         ////////////////////////////////////////////////// SEC (set carry flag) //////////////////////////////////////////////////
  1704.         case 0x19: //SEC impl
  1705.             Flags = Flags | FLAG_C;
  1706.             break;
  1707.         ////////////////////////////////////////////////// CLC (clear carry flag) //////////////////////////////////////////////////
  1708.         case 0x18: //CLC impl
  1709.             Flags = Flags & (0xFF - FLAG_C);
  1710.             break;
  1711.         ////////////////////////////////////////////////// STI (set interrupt flag) //////////////////////////////////////////////////
  1712.         case 0x1B: //STI impl
  1713.             Flags = Flags | FLAG_I;
  1714.             break;
  1715.         ////////////////////////////////////////////////// CLI (clear interrupt flag) //////////////////////////////////////////////////
  1716.         case 0x1A: //CLI impl
  1717.             Flags = Flags & (0xFF - FLAG_I);
  1718.             break;
  1719.         ////////////////////////////////////////////////// STV (set overflow flag) //////////////////////////////////////////////////
  1720.         case 0x1C: //STV impl
  1721.             Flags = Flags | FLAG_V;
  1722.             break;
  1723.         ////////////////////////////////////////////////// CLV (clear overflow flag) //////////////////////////////////////////////////
  1724.         case 0x1D: //CLV impl
  1725.             Flags = Flags & (0xFF - FLAG_V);
  1726.             break;
  1727.     }
  1728. }
  1729.  
  1730. //LD function
  1731. void Group_2_Move(BYTE opcode) {
  1732.     BYTE destination = opcode >> 4; //top four bits point at one register....shift right to keep only top four
  1733.     BYTE source = opcode & 0x0F;//takes bottom four bits
  1734.     int destReg = 0, sourceReg = 0;
  1735.  
  1736.     switch (destination) { //COMBO OF DEST AND SOURCE GIVE REGISTERS ADDRESSES TO FOR MEMORY ADRESSER AT BOTTOM
  1737.         case 0x02://top four bits from op code
  1738.             destReg = REGISTER_A;
  1739.             break;
  1740.         case 0x03:
  1741.             destReg = REGISTER_B;
  1742.             break;
  1743.         case 0x04:
  1744.             destReg = REGISTER_C;
  1745.             break;
  1746.         case 0x05:
  1747.             destReg = REGISTER_D;
  1748.             break;
  1749.         case 0x06:
  1750.             destReg = REGISTER_E;
  1751.             break;
  1752.         case 0x07:
  1753.             destReg = REGISTER_F;
  1754.             break;
  1755.     }
  1756.  
  1757.     switch (source) {
  1758.         case 0x0A:
  1759.             sourceReg = REGISTER_A;
  1760.             break;
  1761.         case 0x0B:
  1762.             sourceReg = REGISTER_B;
  1763.             break;
  1764.         case 0x0C:
  1765.             sourceReg = REGISTER_C;
  1766.             break;
  1767.         case 0x0D:
  1768.             sourceReg = REGISTER_D;
  1769.             break;
  1770.         case 0x0E:
  1771.             sourceReg = REGISTER_E;
  1772.             break;
  1773.         case 0x0F:
  1774.             sourceReg = REGISTER_F;
  1775.             break;
  1776.     }
  1777.  
  1778.     Registers[sourceReg] = Registers[destReg]; //code to assign sourcereg to dest reg
  1779. }
  1780.  
  1781. void execute(BYTE opcode) {
  1782.     if (((opcode >= 0x2A) && (opcode <= 0x2F))
  1783.         || ((opcode >= 0x3A) && (opcode <= 0x3F))
  1784.         || ((opcode >= 0x4A) && (opcode <= 0x4F))
  1785.         || ((opcode >= 0x5A) && (opcode <= 0x5F))
  1786.         || ((opcode >= 0x6A) && (opcode <= 0x6F))
  1787.         || ((opcode >= 0x7A) && (opcode <= 0x7F)))
  1788.     {
  1789.         Group_2_Move(opcode);
  1790.     }
  1791.     else Group_1(opcode);
  1792. }
  1793.  
  1794. void emulate() {
  1795.     BYTE opcode;
  1796.     int sanity = 0;
  1797.  
  1798.     ProgramCounter = 0;
  1799.     halt = false;
  1800.     memory_in_range = true;
  1801.  
  1802.     printf("                    A  B  C  D  E  F  X  Y  SP\n");
  1803.  
  1804.     while ((!halt) && (memory_in_range)) {
  1805.         sanity++;
  1806.         if (sanity > 500) halt = true;
  1807.         printf("%04X ", ProgramCounter);           // Print current address
  1808.         opcode = fetch();
  1809.         execute(opcode);
  1810.  
  1811.         printf("%s  ", opcode_mneumonics[opcode]);  // Print current opcode
  1812.         printf("%02X ", Registers[REGISTER_A]);
  1813.         printf("%02X ", Registers[REGISTER_B]);
  1814.         printf("%02X ", Registers[REGISTER_C]);
  1815.         printf("%02X ", Registers[REGISTER_D]);
  1816.         printf("%02X ", Registers[REGISTER_E]);
  1817.         printf("%02X ", Registers[REGISTER_F]);
  1818.         printf("%02X ", Index_Registers[REGISTER_X]);
  1819.         printf("%02X ", Index_Registers[REGISTER_Y]);
  1820.         printf("%04X ", StackPointer);              // Print Stack Pointer
  1821.  
  1822.         if ((Flags & FLAG_I) == FLAG_I) printf("I = 1, ");
  1823.         else printf("I = 0, ");
  1824.  
  1825.         if ((Flags & FLAG_V) == FLAG_V) printf("V = 1, ");
  1826.         else printf("V = 0, ");
  1827.  
  1828.         if ((Flags & FLAG_N) == FLAG_N) printf("N = 1, ");
  1829.         else printf("N = 0, ");
  1830.  
  1831.         if ((Flags & FLAG_Z) == FLAG_Z) printf("Z = 1, ");
  1832.         else printf("Z = 0, ");
  1833.  
  1834.         if ((Flags & FLAG_C) == FLAG_C) printf("C = 1 ");
  1835.         else printf("C = 0 ");
  1836.        
  1837.         printf("\n");
  1838.     }
  1839.     printf("\n");
  1840. }
  1841.  
  1842.  
  1843. ////////////////////////////////////////////////////////////////////////////////
  1844. //                                Emulator (End)                              //
  1845. ////////////////////////////////////////////////////////////////////////////////
  1846.  
  1847. void initialise_filenames() {
  1848.     int i;
  1849.  
  1850.     for (i=0; i<MAX_FILENAME_SIZE; i++) {
  1851.         hex_file [i] = '\0';
  1852.         trc_file [i] = '\0';
  1853.     }
  1854. }
  1855.  
  1856. int find_dot_position(char *filename) {
  1857.     int  dot_position;
  1858.     int  i;
  1859.     char chr;
  1860.  
  1861.     dot_position = 0;
  1862.     i = 0;
  1863.     chr = filename[i];
  1864.  
  1865.     while (chr != '\0') {
  1866.         if (chr == '.') dot_position = i;
  1867.  
  1868.         i++;
  1869.         chr = filename[i];
  1870.     }
  1871.  
  1872.     return dot_position;
  1873. }
  1874.  
  1875. int find_end_position(char *filename) {
  1876.     int  end_position;
  1877.     int  i;
  1878.     char chr;
  1879.  
  1880.     end_position = 0;
  1881.     i = 0;
  1882.     chr = filename[i];
  1883.  
  1884.     while (chr != '\0') {
  1885.         end_position = i;
  1886.         i++;
  1887.         chr = filename[i];
  1888.     }
  1889.  
  1890.     return end_position;
  1891. }
  1892.  
  1893. bool file_exists(char *filename) {
  1894.     bool exists;
  1895.     FILE *ifp;
  1896.  
  1897.     exists = false;
  1898.  
  1899.     if ((ifp = fopen(filename, "r")) != NULL) {
  1900.         exists = true;
  1901.  
  1902.         fclose(ifp);
  1903.     }
  1904.  
  1905.     return exists;
  1906. }
  1907.  
  1908. void create_file(char *filename) {
  1909.     FILE *ofp;
  1910.  
  1911.     if ((ofp = fopen(filename, "w")) != NULL) fclose(ofp);
  1912. }
  1913.  
  1914. bool getline(FILE *fp, char *buffer) {
  1915.     bool rc;
  1916.     bool collect;
  1917.     char c;
  1918.     int  i;
  1919.  
  1920.     rc = false;
  1921.     collect = true;
  1922.  
  1923.     i = 0;
  1924.     while (collect) {
  1925.         c = getc(fp);
  1926.  
  1927.         switch (c) {
  1928.             case EOF:
  1929.                 if (i > 0) rc = true;
  1930.  
  1931.                 collect = false;
  1932.                 break;
  1933.             case '\n':
  1934.                 if (i > 0) {
  1935.                     rc = true;
  1936.                     collect = false;
  1937.                     buffer[i] = '\0';
  1938.                 }
  1939.                 break;
  1940.             default:
  1941.                 buffer[i] = c;
  1942.                 i++;
  1943.         }
  1944.     }
  1945.  
  1946.     return rc;
  1947. }
  1948.  
  1949. void load_and_run(int args,_TCHAR** argv) {
  1950.     char chr;
  1951.     int  ln;
  1952.     int  dot_position;
  1953.     int  end_position;
  1954.     long i;
  1955.     FILE *ifp;
  1956.     long address;
  1957.     long load_at;
  1958.     int  code;
  1959.  
  1960.     // Prompt for the .hex file
  1961.  
  1962.     printf("\n");
  1963.     printf("Enter the hex filename (.hex): ");
  1964.  
  1965.     if(args == 2) {
  1966.         ln = 0;
  1967.         chr = argv[1][ln];
  1968.         while (chr != '\0') {
  1969.             if (ln < MAX_FILENAME_SIZE) {
  1970.                 hex_file [ln] = chr;
  1971.                 trc_file [ln] = chr;
  1972.                 ln++;
  1973.             }
  1974.             chr = argv[1][ln];
  1975.         }
  1976.     } else {
  1977.         ln = 0;
  1978.         chr = '\0';
  1979.         while (chr != '\n') {
  1980.             chr = getchar();
  1981.  
  1982.             switch(chr) {
  1983.             case '\n':
  1984.                 break;
  1985.             default:
  1986.                 if (ln < MAX_FILENAME_SIZE) {
  1987.                     hex_file [ln] = chr;
  1988.                     trc_file [ln] = chr;
  1989.                     ln++;
  1990.                 }
  1991.                 break;
  1992.             }
  1993.         }
  1994.     }
  1995.     // Tidy up the file names
  1996.  
  1997.     dot_position = find_dot_position(hex_file);
  1998.     if (dot_position == 0) {
  1999.         end_position = find_end_position(hex_file);
  2000.  
  2001.         hex_file[end_position + 1] = '.';
  2002.         hex_file[end_position + 2] = 'h';
  2003.         hex_file[end_position + 3] = 'e';
  2004.         hex_file[end_position + 4] = 'x';
  2005.         hex_file[end_position + 5] = '\0';
  2006.     } else {
  2007.         hex_file[dot_position + 0] = '.';
  2008.         hex_file[dot_position + 1] = 'h';
  2009.         hex_file[dot_position + 2] = 'e';
  2010.         hex_file[dot_position + 3] = 'x';
  2011.         hex_file[dot_position + 4] = '\0';
  2012.     }
  2013.  
  2014.     dot_position = find_dot_position(trc_file);
  2015.     if (dot_position == 0) {
  2016.         end_position = find_end_position(trc_file);
  2017.  
  2018.         trc_file[end_position + 1] = '.';
  2019.         trc_file[end_position + 2] = 't';
  2020.         trc_file[end_position + 3] = 'r';
  2021.         trc_file[end_position + 4] = 'c';
  2022.         trc_file[end_position + 5] = '\0';
  2023.     } else {
  2024.         trc_file[dot_position + 0] = '.';
  2025.         trc_file[dot_position + 1] = 't';
  2026.         trc_file[dot_position + 2] = 'r';
  2027.         trc_file[dot_position + 3] = 'c';
  2028.         trc_file[dot_position + 4] = '\0';
  2029.     }
  2030.  
  2031.     if (file_exists(hex_file)) {
  2032.         // Clear Registers and Memory
  2033.         Registers[REGISTER_A] = 0;
  2034.         Registers[REGISTER_B] = 0;
  2035.         Registers[REGISTER_C] = 0;
  2036.         Registers[REGISTER_D] = 0;
  2037.         Registers[REGISTER_E] = 0;
  2038.         Registers[REGISTER_F] = 0;
  2039.         Index_Registers[REGISTER_X] = 0;
  2040.         Index_Registers[REGISTER_Y] = 0;
  2041.         Flags = 0;
  2042.         ProgramCounter = 0;
  2043.         StackPointer = 0;
  2044.  
  2045.         for (i = 0; i < MEMORY_SIZE; i++) Memory[i] = 0x00;
  2046.  
  2047.         // Load hex file
  2048.         if ((ifp = fopen(hex_file, "r")) != NULL) {
  2049.             printf("Loading file...\n\n");
  2050.  
  2051.             load_at = 0;
  2052.  
  2053.             while (getline(ifp, InputBuffer)) {
  2054.                 if (sscanf(InputBuffer, "L=%x", &address) == 1) load_at = address;
  2055.                 else if (sscanf(InputBuffer, "%x", &code) == 1) {
  2056.                     if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) Memory[load_at] = (BYTE)code;
  2057.  
  2058.                     load_at++;
  2059.                 } else printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
  2060.             }
  2061.  
  2062.             fclose(ifp);
  2063.         }
  2064.  
  2065.         emulate();
  2066.     } else {
  2067.         printf("\n");
  2068.         printf("ERROR> Input file %s does not exist!\n", hex_file);
  2069.         printf("\n");
  2070.     }
  2071. }
  2072.  
  2073. void building(int args,_TCHAR** argv){
  2074.     char buffer[1024];
  2075.     load_and_run(args,argv);
  2076.     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",
  2077.         Memory[TEST_ADDRESS_1],
  2078.         Memory[TEST_ADDRESS_2],
  2079.         Memory[TEST_ADDRESS_3],
  2080.         Memory[TEST_ADDRESS_4],
  2081.         Memory[TEST_ADDRESS_5],
  2082.         Memory[TEST_ADDRESS_6],
  2083.         Memory[TEST_ADDRESS_7],
  2084.         Memory[TEST_ADDRESS_8],
  2085.         Memory[TEST_ADDRESS_9],
  2086.         Memory[TEST_ADDRESS_10],
  2087.         Memory[TEST_ADDRESS_11],
  2088.         Memory[TEST_ADDRESS_12]
  2089.         );
  2090.     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
  2091. }
  2092.  
  2093. void test_and_mark() {
  2094.     char buffer[1024];
  2095.     bool testing_complete;
  2096.     int  len = sizeof(SOCKADDR);
  2097.     char chr;
  2098.     int  i;
  2099.     int  j;
  2100.     bool end_of_program;
  2101.     long address;
  2102.     long load_at;
  2103.     int  code;
  2104.     int  mark;
  2105.     int  passed;
  2106.  
  2107.     printf("Automatic Testing and Marking\n");
  2108.     printf("\n");
  2109.  
  2110.     testing_complete = false;
  2111.  
  2112.     sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
  2113.     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
  2114.  
  2115.     while (!testing_complete) {
  2116.         memset(buffer, '\0', sizeof(buffer));
  2117.  
  2118.         if (recvfrom(sock, buffer, sizeof(buffer)-1, 0, (SOCKADDR *)&client_addr, &len) != SOCKET_ERROR) {
  2119.             printf("Incoming Data: %s \n", buffer);
  2120.  
  2121.             //if (strcmp(buffer, "Testing complete") == 1)
  2122.             if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
  2123.                 testing_complete = true;
  2124.                 printf("Current mark = %d\n", mark);
  2125.             }else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
  2126.                 //testing_complete = true;
  2127.                 printf("Passed = %d\n", passed);
  2128.             } else if (strcmp(buffer, "Error") == 0) {
  2129.                 printf("ERROR> Testing abnormally terminated\n");
  2130.                 testing_complete = true;
  2131.             } else {
  2132.                 // Clear Registers and Memory
  2133.                 Registers[REGISTER_A] = 0;
  2134.                 Registers[REGISTER_B] = 0;
  2135.                 Registers[REGISTER_C] = 0;
  2136.                 Registers[REGISTER_D] = 0;
  2137.                 Registers[REGISTER_E] = 0;
  2138.                 Registers[REGISTER_F] = 0;
  2139.                 Index_Registers[REGISTER_X] = 0;
  2140.                 Index_Registers[REGISTER_Y] = 0;
  2141.                 Flags = 0;
  2142.                 ProgramCounter = 0;
  2143.                 StackPointer = 0;
  2144.                 for (i = 0; i < MEMORY_SIZE; i++) Memory[i] = 0;
  2145.  
  2146.                 // Load hex file
  2147.                 i = 0;
  2148.                 j = 0;
  2149.                 load_at = 0;
  2150.                 end_of_program = false;
  2151.                 FILE *ofp;
  2152.                 fopen_s(&ofp ,"branch.txt", "a");
  2153.  
  2154.                 while (!end_of_program) {
  2155.                     chr = buffer[i];
  2156.                     switch (chr) {
  2157.                     case '\0':
  2158.                         end_of_program = true;
  2159.                     case ',':
  2160.                         if (sscanf(InputBuffer, "L=%x", &address) == 1) load_at = address;
  2161.                         else if (sscanf(InputBuffer, "%x", &code) == 1) {
  2162.                             if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
  2163.                                 Memory[load_at] = (BYTE)code;
  2164.                                 fprintf(ofp, "%02X\n", (BYTE)code);
  2165.                             }
  2166.                             load_at++;
  2167.                         } else printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
  2168.                        
  2169.                         j = 0;
  2170.                         break;
  2171.                     default:
  2172.                         InputBuffer[j] = chr;
  2173.                         j++;
  2174.                         break;
  2175.                     }
  2176.                     i++;
  2177.                 }
  2178.                 fclose(ofp);
  2179.                 // Emulate
  2180.  
  2181.                 if (load_at > 1) {
  2182.                     emulate();
  2183.                     // Send and store results
  2184.                     sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
  2185.                         Memory[TEST_ADDRESS_1],
  2186.                         Memory[TEST_ADDRESS_2],
  2187.                         Memory[TEST_ADDRESS_3],
  2188.                         Memory[TEST_ADDRESS_4],
  2189.                         Memory[TEST_ADDRESS_5],
  2190.                         Memory[TEST_ADDRESS_6],
  2191.                         Memory[TEST_ADDRESS_7],
  2192.                         Memory[TEST_ADDRESS_8],
  2193.                         Memory[TEST_ADDRESS_9],
  2194.                         Memory[TEST_ADDRESS_10],
  2195.                         Memory[TEST_ADDRESS_11],
  2196.                         Memory[TEST_ADDRESS_12]
  2197.                         );
  2198.                     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
  2199.                 }
  2200.             }
  2201.         }
  2202.     }
  2203. }
  2204.  
  2205. int _tmain(int argc, _TCHAR* argv[]) {
  2206.     char chr;
  2207.     char dummy;
  2208.  
  2209.     printf("Microprocessor Emulator\n");
  2210.     printf("UWE Computer and Network Systems Assignment 1\n");
  2211.     printf("\n");
  2212.  
  2213.     initialise_filenames();
  2214.  
  2215.     if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
  2216.  
  2217.     sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
  2218.     if (!sock) {   
  2219.         //Creation failed!
  2220.     }
  2221.  
  2222.     memset(&server_addr, 0, sizeof(SOCKADDR_IN));
  2223.     server_addr.sin_family = AF_INET;
  2224.     server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
  2225.     server_addr.sin_port = htons(PORT_SERVER);
  2226.  
  2227.     memset(&client_addr, 0, sizeof(SOCKADDR_IN));
  2228.     client_addr.sin_family = AF_INET;
  2229.     client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  2230.     client_addr.sin_port = htons(PORT_CLIENT);
  2231.  
  2232.     chr = '\0';
  2233.     while ((chr != 'e') && (chr != 'E')) {
  2234.         printf("\nPlease select option\n");
  2235.         printf("L - Load and run a hex file\n");
  2236.         printf("T - Have the server test and mark your emulator\n");
  2237.         printf("E - Exit\n");
  2238.         if(argc == 2){ building(argc,argv); exit(0);}
  2239.         printf("Enter option: ");
  2240.         chr = getchar();
  2241.         if (chr != 0x0A) dummy = getchar();  // read in the <CR>
  2242.        
  2243.         printf("\n");
  2244.  
  2245.         switch (chr) {
  2246.             case 'L': case 'l':
  2247.                 load_and_run(argc,argv);
  2248.                 break;
  2249.             case 'T': case 't':
  2250.                 test_and_mark();
  2251.                 break; 
  2252.         }
  2253.     }
  2254.  
  2255.     closesocket(sock);
  2256.     WSACleanup();
  2257.  
  2258.     return 0;
  2259. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement