Advertisement
Guest User

Untitled

a guest
Feb 27th, 2020
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 92.81 KB | None | 0 0
  1.  
  2.  
  3. #include "stdafx.h"
  4. #include <winsock2.h>
  5.  
  6. #pragma comment(lib, "wsock32.lib")
  7.  
  8.  
  9. #define STUDENT_NUMBER    "18022288"
  10.  
  11. #define IP_ADDRESS_SERVER "127.0.0.1"
  12.  
  13. #define PORT_SERVER 0x1984 // We define a port that we are going to use.
  14. #define PORT_CLIENT 0x1985 // We define a port that we are going to use.
  15.  
  16. #define WORD  unsigned short
  17. #define DWORD unsigned long
  18. #define BYTE  unsigned char
  19.  
  20. #define MAX_FILENAME_SIZE 500
  21. #define MAX_BUFFER_SIZE   500
  22.  
  23. SOCKADDR_IN server_addr;
  24. SOCKADDR_IN client_addr;
  25.  
  26. SOCKET sock;  // This is our socket, it is the handle to the IO address to read/write packets
  27.  
  28. WSADATA data;
  29.  
  30. char InputBuffer[MAX_BUFFER_SIZE];
  31.  
  32. char hex_file[MAX_BUFFER_SIZE];
  33. char trc_file[MAX_BUFFER_SIZE];
  34.  
  35. //////////////////////////
  36. //   Registers          //
  37. //////////////////////////
  38.  
  39. #define FLAG_I  0x80
  40. #define FLAG_N  0x20
  41. #define FLAG_V  0x10
  42. #define FLAG_Z  0x08
  43. #define FLAG_C  0x01
  44. #define REGISTER_M  7 //Add memory register
  45. #define REGISTER_A  6
  46. #define REGISTER_H  5
  47. #define REGISTER_L  4
  48. #define REGISTER_E  3
  49. #define REGISTER_D  2
  50. #define REGISTER_C  1
  51. #define REGISTER_B  0
  52. WORD IndexRegister;
  53.  
  54. BYTE Registers[8]; //Changed from 7 to 8
  55. BYTE Flags;
  56. WORD ProgramCounter;
  57. WORD StackPointer;
  58.  
  59.  
  60. ////////////
  61. // Memory //
  62. ////////////
  63.  
  64. #define MEMORY_SIZE 65536
  65.  
  66. BYTE Memory[MEMORY_SIZE];
  67.  
  68. #define TEST_ADDRESS_1  0x01FA
  69. #define TEST_ADDRESS_2  0x01FB
  70. #define TEST_ADDRESS_3  0x01FC
  71. #define TEST_ADDRESS_4  0x01FD
  72. #define TEST_ADDRESS_5  0x01FE
  73. #define TEST_ADDRESS_6  0x01FF
  74. #define TEST_ADDRESS_7  0x0200
  75. #define TEST_ADDRESS_8  0x0201
  76. #define TEST_ADDRESS_9  0x0202
  77. #define TEST_ADDRESS_10  0x0203
  78. #define TEST_ADDRESS_11  0x0204
  79. #define TEST_ADDRESS_12  0x0205
  80.  
  81.  
  82. ///////////////////////
  83. // Control variables //
  84. ///////////////////////
  85.  
  86. bool memory_in_range = true;
  87. bool halt = false;
  88.  
  89.  
  90. ///////////////////////
  91. // Disassembly table //
  92. ///////////////////////
  93.  
  94. char opcode_mneumonics[][14] =
  95. {
  96. "BRA rel      ",
  97. "BCC rel      ",
  98. "BCS rel      ",
  99. "BNE rel      ",
  100. "BEQ rel      ",
  101. "BVC rel      ",
  102. "BVS rel      ",
  103. "BMI rel      ",
  104. "BPL rel      ",
  105. "BGE rel      ",
  106. "BLE rel      ",
  107. "BLS rel      ",
  108. "BHI rel      ",
  109. "ILLEGAL     ",
  110. "RTN impl     ",
  111. "ILLEGAL     ",
  112.  
  113. "ST abs       ",
  114. "PSH  ,A      ",
  115. "POP A,       ",
  116. "ILLEGAL     ",
  117. "ILLEGAL     ",
  118. "CLC impl     ",
  119. "SEC impl     ",
  120. "CLI impl     ",
  121. "STI impl     ",
  122. "SEV impl     ",
  123. "CLV impl     ",
  124. "DEX impl     ",
  125. "INX impl     ",
  126. "NOP impl     ",
  127. "WAI impl     ",
  128. "ILLEGAL     ",
  129.  
  130. "ST abs,X     ",
  131. "PSH  ,s      ",
  132. "POP s,       ",
  133. "ILLEGAL     ",
  134. "ILLEGAL     ",
  135. "ADI  #       ",
  136. "SBI  #       ",
  137. "CPI  #       ",
  138. "ANI  #       ",
  139. "XRI  #       ",
  140. "MVI  #,B     ",
  141. "MVI  #,C     ",
  142. "MVI  #,D     ",
  143. "MVI  #,E     ",
  144. "MVI  #,L     ",
  145. "MVI  #,H     ",
  146.  
  147. "ILLEGAL     ",
  148. "PSH  ,B      ",
  149. "POP B,       ",
  150. "JPR abs      ",
  151. "CCC abs      ",
  152. "CCS abs      ",
  153. "CNE abs      ",
  154. "CEQ abs      ",
  155. "CVC abs      ",
  156. "CVS abs      ",
  157. "CMI abs      ",
  158. "CPL abs      ",
  159. "CHI abs      ",
  160. "CLE abs      ",
  161. "ILLEGAL     ",
  162. "ILLEGAL     ",
  163.  
  164. "ILLEGAL     ",
  165. "PSH  ,C      ",
  166. "POP C,       ",
  167. "TST abs      ",
  168. "INC abs      ",
  169. "DEC abs      ",
  170. "RCR abs      ",
  171. "RCL abs      ",
  172. "SAL abs      ",
  173. "ASR abs      ",
  174. "NOT abs      ",
  175. "ROL abs      ",
  176. "ROR abs      ",
  177. "ILLEGAL     ",
  178. "LDX  #       ",
  179. "LODS  #      ",
  180.  
  181. "STOX abs     ",
  182. "PSH  ,D      ",
  183. "POP D,       ",
  184. "TST abs,X    ",
  185. "INC abs,X    ",
  186. "DEC abs,X    ",
  187. "RCR abs,X    ",
  188. "RCL abs,X    ",
  189. "SAL abs,X    ",
  190. "ASR abs,X    ",
  191. "NOT abs,X    ",
  192. "ROL abs,X    ",
  193. "ROR abs,X    ",
  194. "ILLEGAL     ",
  195. "LDX abs      ",
  196. "LODS abs     ",
  197.  
  198. "STOX abs,X   ",
  199. "PSH  ,E      ",
  200. "POP E,       ",
  201. "TSTA A,A     ",
  202. "INCA A,A     ",
  203. "DECA A,A     ",
  204. "RCRA A,A     ",
  205. "RCLA A,A     ",
  206. "SALA A,A     ",
  207. "ASRA A,A     ",
  208. "NOTA A,A     ",
  209. "ROLA A,A     ",
  210. "RORA A,A     ",
  211. "ILLEGAL     ",
  212. "LDX abs,X    ",
  213. "LODS abs,X   ",
  214.  
  215. "ILLEGAL     ",
  216. "PSH  ,L      ",
  217. "POP L,       ",
  218. "ILLEGAL     ",
  219. "TAS impl     ",
  220. "TSA impl     ",
  221. "ILLEGAL     ",
  222. "ILLEGAL     ",
  223. "MOVE A,A     ",
  224. "MOVE B,A     ",
  225. "MOVE C,A     ",
  226. "MOVE D,A     ",
  227. "MOVE E,A     ",
  228. "MOVE L,A     ",
  229. "MOVE H,A     ",
  230. "MOVE M,A     ",
  231.  
  232. "ILLEGAL     ",
  233. "PSH  ,H      ",
  234. "POP H,       ",
  235. "ILLEGAL     ",
  236. "ILLEGAL     ",
  237. "SWI impl     ",
  238. "RTI impl     ",
  239. "ILLEGAL     ",
  240. "MOVE A,B     ",
  241. "MOVE B,B     ",
  242. "MOVE C,B     ",
  243. "MOVE D,B     ",
  244. "MOVE E,B     ",
  245. "MOVE L,B     ",
  246. "MOVE H,B     ",
  247. "MOVE M,B     ",
  248.  
  249. "ADC A,B      ",
  250. "SBC A,B      ",
  251. "CMP A,B      ",
  252. "IOR A,B      ",
  253. "AND A,B      ",
  254. "XOR A,B      ",
  255. "BT A,B       ",
  256. "ILLEGAL     ",
  257. "MOVE A,C     ",
  258. "MOVE B,C     ",
  259. "MOVE C,C     ",
  260. "MOVE D,C     ",
  261. "MOVE E,C     ",
  262. "MOVE L,C     ",
  263. "MOVE H,C     ",
  264. "MOVE M,C     ",
  265.  
  266. "ADC A,C      ",
  267. "SBC A,C      ",
  268. "CMP A,C      ",
  269. "IOR A,C      ",
  270. "AND A,C      ",
  271. "XOR A,C      ",
  272. "BT A,C       ",
  273. "ILLEGAL     ",
  274. "MOVE A,D     ",
  275. "MOVE B,D     ",
  276. "MOVE C,D     ",
  277. "MOVE D,D     ",
  278. "MOVE E,D     ",
  279. "MOVE L,D     ",
  280. "MOVE H,D     ",
  281. "MOVE M,D     ",
  282.  
  283. "ADC A,D      ",
  284. "SBC A,D      ",
  285. "CMP A,D      ",
  286. "IOR A,D      ",
  287. "AND A,D      ",
  288. "XOR A,D      ",
  289. "BT A,D       ",
  290. "LD  #        ",
  291. "MOVE A,E     ",
  292. "MOVE B,E     ",
  293. "MOVE C,E     ",
  294. "MOVE D,E     ",
  295. "MOVE E,E     ",
  296. "MOVE L,E     ",
  297. "MOVE H,E     ",
  298. "MOVE M,E     ",
  299.  
  300. "ADC A,E      ",
  301. "SBC A,E      ",
  302. "CMP A,E      ",
  303. "IOR A,E      ",
  304. "AND A,E      ",
  305. "XOR A,E      ",
  306. "BT A,E       ",
  307. "LD abs       ",
  308. "MOVE A,L     ",
  309. "MOVE B,L     ",
  310. "MOVE C,L     ",
  311. "MOVE D,L     ",
  312. "MOVE E,L     ",
  313. "MOVE L,L     ",
  314. "MOVE H,L     ",
  315. "MOVE M,L     ",
  316.  
  317. "ADC A,L      ",
  318. "SBC A,L      ",
  319. "CMP A,L      ",
  320. "IOR A,L      ",
  321. "AND A,L      ",
  322. "XOR A,L      ",
  323. "BT A,L       ",
  324. "LD abs,X     ",
  325. "MOVE A,H     ",
  326. "MOVE B,H     ",
  327. "MOVE C,H     ",
  328. "MOVE D,H     ",
  329. "MOVE E,H     ",
  330. "MOVE L,H     ",
  331. "MOVE H,H     ",
  332. "MOVE M,H     ",
  333.  
  334. "ADC A,H      ",
  335. "SBC A,H      ",
  336. "CMP A,H      ",
  337. "IOR A,H      ",
  338. "AND A,H      ",
  339. "XOR A,H      ",
  340. "BT A,H       ",
  341. "ILLEGAL     ",
  342. "MOVE A,M     ",
  343. "MOVE B,M     ",
  344. "MOVE C,M     ",
  345. "MOVE D,M     ",
  346. "MOVE E,M     ",
  347. "MOVE L,M     ",
  348. "MOVE H,M     ",
  349. "MOVE -,-     ",
  350.  
  351. "ADC A,M      ",
  352. "SBC A,M      ",
  353. "CMP A,M      ",
  354. "IOR A,M      ",
  355. "AND A,M      ",
  356. "XOR A,M      ",
  357. "BT A,M       ",
  358. "ILLEGAL     ",
  359. "ILLEGAL     ",
  360. "ILLEGAL     ",
  361. "JMP abs      ",
  362. "ILLEGAL     ",
  363. "ILLEGAL     ",
  364. "ILLEGAL     ",
  365. "ILLEGAL     ",
  366. "ILLEGAL     ",
  367.  
  368. };
  369.  
  370. ////////////////////////////////////////////////////////////////////////////////
  371. //                           Simulator/Emulator (Start)                       //
  372. ////////////////////////////////////////////////////////////////////////////////
  373.  
  374.  
  375. //=============================== FETCH FUNCTION ===============================//
  376.  
  377.  
  378. BYTE fetch() {
  379.     BYTE byte = 0;
  380.  
  381.     if (0 <= ProgramCounter <= MEMORY_SIZE) {
  382.         memory_in_range = true;
  383.         byte = Memory[ProgramCounter];
  384.         ProgramCounter++;
  385.     }
  386.     else {
  387.         memory_in_range = false;
  388.     }
  389.     return byte;
  390. }
  391.  
  392.  
  393. //===============================  FLAG FUNCTIONS  ===============================//
  394.  
  395.  
  396. void set_flag_n(BYTE inReg) {
  397.     BYTE reg;
  398.     reg = inReg;
  399.  
  400.     if ((reg & 0x80) != 0) //msbit set
  401.     {
  402.         Flags = Flags | FLAG_N;
  403.     }
  404.     else {
  405.         Flags = Flags & (0xFF - FLAG_N);
  406.     }
  407. }
  408.  
  409. void set_flag_v(BYTE in1, BYTE in2, BYTE out1) {
  410.     BYTE reg1in;
  411.     BYTE reg2in;
  412.     BYTE regOut;
  413.  
  414.     reg1in = in1;
  415.     reg2in = in2;
  416.     regOut = out1;
  417.  
  418.     if ((((reg1in & 0x80) == 0x80) && ((reg2in & 0x80) == 0x80) && ((regOut & 0x80) != 0x80)) ||
  419.         (((reg1in & 0x80) != 0x80) && ((reg2in & 0x80) != 0x80) && ((regOut & 0x80) == 0x80))) {
  420.         Flags = Flags | FLAG_V;
  421.     }
  422.     else {
  423.         Flags = Flags & (0xFF - FLAG_V);
  424.     }
  425. }
  426.  
  427. void set_flag_z(BYTE inReg) {
  428.     BYTE reg;
  429.     reg = inReg;
  430.  
  431.     if (reg == 0) //zero set
  432.     {
  433.         Flags = Flags | FLAG_Z;
  434.     }
  435.     else {
  436.         Flags = Flags & (0xFF - FLAG_Z);
  437.     }
  438. }
  439.  
  440.  
  441. //===============================  FUNCTIONS  ===============================//
  442.  
  443.  
  444. void Group_1(BYTE opcode) {
  445.     BYTE LB = 0;
  446.     BYTE HB = 0;
  447.     WORD address = 0;
  448.     WORD data = 0;
  449.  
  450.     WORD temp_word;
  451.     WORD param1;
  452.     WORD param2;
  453.     WORD offset;
  454.     WORD saved_flags;
  455.  
  456.     BYTE CF; // C FLAG CHECK
  457.     if ((Flags & FLAG_C) == FLAG_C) { // If flag c is set
  458.         CF = 1; // Return 1
  459.     }
  460.     else {
  461.         CF = 0; // Return 0
  462.     }
  463.  
  464.     BYTE NF; // N FLAG CHECK
  465.     if ((Flags & FLAG_N) == FLAG_N) {
  466.         NF = 1; // Return 1
  467.     }
  468.     else {
  469.         NF = 0; // Return 0
  470.     }
  471.  
  472.     BYTE ZF; // Z FLAG CHECK
  473.     if ((Flags & FLAG_Z) == FLAG_Z) {
  474.         ZF = 1; // Return 1
  475.     }
  476.     else {
  477.         ZF = 0; // Return 0
  478.     }
  479.  
  480.     BYTE VF; // V FLAG CHECK
  481.     if ((Flags & FLAG_V) == FLAG_V) {
  482.         VF = 1; // Return 1
  483.     }
  484.     else {
  485.         VF = 0; // Return 0
  486.     }
  487.  
  488.     switch (opcode) {
  489.  
  490.  
  491.         //===============================  LOADING AND STORING  ===============================//
  492.  
  493.  
  494.             /*
  495.             *   Opcode: LD
  496.             *   Addressing mode(s): #, abs, abs X
  497.             *   Description: Loads Memory into Accumulator
  498.             *   Flags: - - T - T - - 0
  499.             */
  500.  
  501.  
  502.     case 0xB7: //LD (#)
  503.         data = fetch();
  504.         Registers[REGISTER_A] = data;
  505.  
  506.         set_flag_n(Registers[REGISTER_A]);
  507.         set_flag_z(Registers[REGISTER_A]);
  508.         Flags = Flags & (0xFF - FLAG_C);
  509.         break;
  510.  
  511.     case 0xC7: //LD (abs)
  512.         HB = fetch();
  513.         LB = fetch();
  514.         address += (WORD)((WORD)HB << 8) + LB;
  515.  
  516.         if (0 <=  address < MEMORY_SIZE) {
  517.             Registers[REGISTER_A] = Memory[address];
  518.         }
  519.  
  520.         set_flag_n(Registers[REGISTER_A]);
  521.         set_flag_z(Registers[REGISTER_A]);
  522.         Flags = Flags & (0xFF - FLAG_C);
  523.         break;
  524.  
  525.     case 0xD7: //LD (abs, X)
  526.         address += IndexRegister;
  527.         HB = fetch();
  528.         LB = fetch();
  529.         address += (WORD)((WORD)HB << 8) + LB;
  530.  
  531.         if (0 <= address < MEMORY_SIZE) {
  532.             Registers[REGISTER_A] = Memory[address];
  533.         }
  534.  
  535.         set_flag_n(Registers[REGISTER_A]);
  536.         set_flag_z(Registers[REGISTER_A]);
  537.         Flags = Flags & (0xFF - FLAG_C);
  538.         break;
  539.  
  540.  
  541.  
  542.         /*
  543.         *   Opcode: ST
  544.         *   Description: Stores Accumulator into Memory
  545.         *   Addressing mode(s): abs, abs X
  546.         *   Flags: - - T - T - - 0
  547.         */
  548.  
  549.     case 0x10: //ST (abs)
  550.         HB = fetch();
  551.         LB = fetch();
  552.         address += (WORD)((WORD)HB << 8) + LB;
  553.  
  554.         if (0 <= address < MEMORY_SIZE) {
  555.             Memory[address] = Registers[REGISTER_A];
  556.         }
  557.  
  558.         set_flag_n(Registers[REGISTER_A]);
  559.         set_flag_z(Registers[REGISTER_A]);
  560.         Flags = Flags & (0xFF - FLAG_C);
  561.         break;
  562.  
  563.     case 0x20: //ST (abs, X)
  564.         address += IndexRegister;
  565.         HB = fetch();
  566.         LB = fetch();
  567.         address += (WORD)((WORD)HB << 8) + LB;
  568.  
  569.         if (0 <= address < MEMORY_SIZE) {
  570.             Memory[address] = Registers[REGISTER_A];
  571.         }
  572.  
  573.         set_flag_n(Registers[REGISTER_A]);
  574.         set_flag_z(Registers[REGISTER_A]);
  575.         Flags = Flags & (0xFF - FLAG_C);
  576.         break;
  577.  
  578.  
  579.  
  580.         /*
  581.         *   Opcode: MVI
  582.         *   Addressing mode(s): #
  583.         *   Description: Loads Memory into register
  584.         *   Flags: - - T - T - - 0
  585.         */
  586.  
  587.     case 0x2A: //MVI (#, B)
  588.         data = fetch();
  589.         Registers[REGISTER_B] = data;
  590.  
  591.         set_flag_n(Registers[REGISTER_B]);
  592.         set_flag_z(Registers[REGISTER_B]);
  593.         Flags = Flags & (0xFF - FLAG_C);
  594.         break;
  595.  
  596.     case 0x2B: //MVI (#, C)
  597.         data = fetch();
  598.         Registers[REGISTER_C] = data;
  599.  
  600.         set_flag_n(Registers[REGISTER_C]);
  601.         set_flag_z(Registers[REGISTER_C]);
  602.         Flags = Flags & (0xFF - FLAG_C);
  603.         break;
  604.  
  605.     case 0x2C: //MVI (#, D)
  606.         data = fetch();
  607.         Registers[REGISTER_D] = data;
  608.  
  609.         set_flag_n(Registers[REGISTER_D]);
  610.         set_flag_z(Registers[REGISTER_D]);
  611.         Flags = Flags & (0xFF - FLAG_C);
  612.         break;
  613.  
  614.     case 0x2D: //MVI (#, E)
  615.         data = fetch();
  616.         Registers[REGISTER_E] = data;
  617.  
  618.         set_flag_n(Registers[REGISTER_E]);
  619.         set_flag_z(Registers[REGISTER_E]);
  620.         Flags = Flags & (0xFF - FLAG_C);
  621.         break;
  622.  
  623.     case 0x2E: //MVI (#, L)
  624.         data = fetch();
  625.         Registers[REGISTER_L] = data;
  626.  
  627.         set_flag_n(Registers[REGISTER_L]);
  628.         set_flag_z(Registers[REGISTER_L]);
  629.         Flags = Flags & (0xFF - FLAG_C);
  630.         break;
  631.  
  632.     case 0x2F: //MVI (#, H)
  633.         data = fetch();
  634.         Registers[REGISTER_H] = data;
  635.  
  636.         set_flag_n(Registers[REGISTER_H]);
  637.         set_flag_z(Registers[REGISTER_H]);
  638.         Flags = Flags & (0xFF - FLAG_C);
  639.         break;
  640.  
  641.  
  642.  
  643.         /*
  644.         *   Opcode: LODS
  645.         *   Addressing mode(s) : #, abs, abs X
  646.         *   Description: Loads Memory into Stackpointer
  647.         *   Flags: - - T - T - - 0
  648.         */
  649.  
  650.     case 0x4F: //LODS (#)
  651.         data = fetch();
  652.  
  653.         StackPointer = data << 8;
  654.         StackPointer += fetch();
  655.  
  656.         set_flag_n(Registers[REGISTER_A]);
  657.         set_flag_z(Registers[REGISTER_A]);
  658.         Flags = Flags & (0xFF - FLAG_C);
  659.         break;
  660.  
  661.     case 0x5F: //LODS (abs)
  662.         HB = fetch();
  663.         LB = fetch();
  664.         address += (WORD)((WORD)HB << 8) + LB;
  665.  
  666.         if (0 <= address < MEMORY_SIZE - 1) {
  667.             StackPointer = (WORD)Memory[address] << 8;
  668.             StackPointer += Memory[address + 1];
  669.         }
  670.  
  671.         set_flag_n(Registers[REGISTER_A]);
  672.         set_flag_z(Registers[REGISTER_A]);
  673.         Flags = Flags & (0xFF - FLAG_C);
  674.         break;
  675.  
  676.     case 0x6F: //LODS (abs, X)
  677.         address += IndexRegister;
  678.         HB = fetch();
  679.         LB = fetch();
  680.         address += (WORD)((WORD)HB << 8) + LB;
  681.  
  682.         if (0 <= address < MEMORY_SIZE - 1) {
  683.             StackPointer = (WORD)Memory[address] << 8;
  684.             StackPointer += Memory[address + 1];
  685.         }
  686.  
  687.         set_flag_n(Registers[REGISTER_A]);
  688.         set_flag_z(Registers[REGISTER_A]);
  689.         Flags = Flags & (0xFF - FLAG_C);
  690.         break;
  691.  
  692.  
  693.  
  694.         /*
  695.         *   Opcode: LDX
  696.         *   Addressing mode(s) : #, abs, abs X
  697.         *   Description: Loads Memory into register X
  698.         *   Flags: - - T - T - - 0
  699.         */
  700.  
  701.     case 0x4E: //LDX (#)
  702.         data = fetch();
  703.         Registers[IndexRegister] = data;
  704.  
  705.         set_flag_n(Registers[IndexRegister]);
  706.         set_flag_z(Registers[IndexRegister]);
  707.         Flags = Flags & (0xFF - FLAG_C);
  708.         break;
  709.  
  710.     case 0x5E: //LDX (abs)
  711.         HB = fetch();
  712.         LB = fetch();
  713.         address += (WORD)((WORD)HB << 8) + LB;
  714.  
  715.         if (0 <= address < MEMORY_SIZE) {
  716.             Registers[IndexRegister] = Memory[address];
  717.         }
  718.  
  719.         set_flag_n(Registers[IndexRegister]);
  720.         set_flag_z(Registers[IndexRegister]);
  721.         Flags = Flags & (0xFF - FLAG_C);
  722.         break;
  723.  
  724.     case 0x6E: //LDX (abs, X)
  725.         address += IndexRegister;
  726.         HB = fetch();
  727.         LB = fetch();
  728.         address += (WORD)((WORD)HB << 8) + LB;
  729.  
  730.         if (0 <= address < MEMORY_SIZE) {
  731.             Registers[IndexRegister] = Memory[address];
  732.         }
  733.  
  734.         set_flag_n(Registers[IndexRegister]);
  735.         set_flag_z(Registers[IndexRegister]);
  736.         Flags = Flags & (0xFF - FLAG_C);
  737.         break;
  738.  
  739.  
  740.  
  741.         /*
  742.         *   Opcode: STOX
  743.         *   Addressing mode(s) : abs, abs X
  744.         *   Description: Stores register X into Memory
  745.         *   Flags: - - T - T - - 0
  746.         */
  747.  
  748.     case 0x50: //STOX (abs)
  749.         address += IndexRegister;
  750.         HB = fetch();
  751.         LB = fetch();
  752.         address += (WORD)((WORD)HB << 8) + LB;
  753.  
  754.         if (0 <= address < MEMORY_SIZE) {
  755.             Memory[address] = Registers[IndexRegister];
  756.         }
  757.  
  758.         set_flag_n(Registers[IndexRegister]);
  759.         set_flag_z(Registers[IndexRegister]);
  760.         Flags = Flags & (0xFF - FLAG_C);
  761.         break;
  762.  
  763.     case 0x60: //STOX (abs, X)
  764.         address += IndexRegister;
  765.         HB = fetch();
  766.         LB = fetch();
  767.         address += (WORD)((WORD)HB << 8) + LB;
  768.  
  769.         if (0 <= address < MEMORY_SIZE) {
  770.             Memory[address] = Registers[IndexRegister];
  771.         }
  772.  
  773.         set_flag_n(Registers[IndexRegister]);
  774.         set_flag_z(Registers[IndexRegister]);
  775.         Flags = Flags & (0xFF - FLAG_C);
  776.         break;
  777.  
  778.  
  779.         //=============================== FLAGS ===============================//
  780.  
  781.  
  782.             /*
  783.             *   Opcode: ADC
  784.             *   Description: Register added to Accumulator with Carry
  785.             *   Flags: - - T T T - - T
  786.             */
  787.  
  788.     case 0x90: //ADC (A, B)
  789.         temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_B];
  790.  
  791.         if ((Flags & FLAG_C) != 0) {
  792.             temp_word++;
  793.         }
  794.  
  795.         if (temp_word >= 0x100) {
  796.             Flags = Flags | FLAG_C; //Set carry flag
  797.         }
  798.         else {
  799.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  800.         }
  801.  
  802.         set_flag_n((BYTE)temp_word);
  803.         set_flag_z((BYTE)temp_word);
  804.         set_flag_v(Registers[REGISTER_A], Registers[REGISTER_B], (BYTE)temp_word);
  805.         Registers[REGISTER_A] = (BYTE)temp_word;
  806.         break;
  807.  
  808.     case 0xA0: //ADC (A, C)
  809.         temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_C];
  810.  
  811.         if ((Flags & FLAG_C) != 0) {
  812.             temp_word++;
  813.         }
  814.  
  815.         if (temp_word >= 0x100) {
  816.             Flags = Flags | FLAG_C; //Set carry flag
  817.         }
  818.         else {
  819.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  820.         }
  821.  
  822.         set_flag_n((BYTE)temp_word);
  823.         set_flag_z((BYTE)temp_word);
  824.         set_flag_v(Registers[REGISTER_A], Registers[REGISTER_C], (BYTE)temp_word);
  825.         Registers[REGISTER_A] = (BYTE)temp_word;
  826.         break;
  827.  
  828.     case 0xB0: //ADC (A, D)
  829.         temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_D];
  830.  
  831.         if ((Flags & FLAG_C) != 0) {
  832.             temp_word++;
  833.         }
  834.  
  835.         if (temp_word >= 0x100) {
  836.             Flags = Flags | FLAG_C; //Set carry flag
  837.         }
  838.         else {
  839.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  840.         }
  841.  
  842.         set_flag_n((BYTE)temp_word);
  843.         set_flag_z((BYTE)temp_word);
  844.         set_flag_v(Registers[REGISTER_A], Registers[REGISTER_D], (BYTE)temp_word);
  845.         Registers[REGISTER_A] = (BYTE)temp_word;
  846.         break;
  847.  
  848.     case 0xC0: //ADC (A, E)
  849.         temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_E];
  850.  
  851.         if ((Flags & FLAG_C) != 0) {
  852.             temp_word++;
  853.         }
  854.  
  855.         if (temp_word >= 0x100) {
  856.             Flags = Flags | FLAG_C; //Set carry flag
  857.         }
  858.         else {
  859.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  860.         }
  861.  
  862.         set_flag_n((BYTE)temp_word);
  863.         set_flag_z((BYTE)temp_word);
  864.         set_flag_v(Registers[REGISTER_A], Registers[REGISTER_E], (BYTE)temp_word);
  865.         Registers[REGISTER_A] = (BYTE)temp_word;
  866.         break;
  867.  
  868.     case 0xD0: //ADC (A, L)
  869.         temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_L];
  870.  
  871.         if ((Flags & FLAG_C) != 0) {
  872.             temp_word++;
  873.         }
  874.  
  875.         if (temp_word >= 0x100) {
  876.             Flags = Flags | FLAG_C; //Set carry flag
  877.         }
  878.         else {
  879.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  880.         }
  881.  
  882.         set_flag_n((BYTE)temp_word);
  883.         set_flag_z((BYTE)temp_word);
  884.         set_flag_v(Registers[REGISTER_A], Registers[REGISTER_L], (BYTE)temp_word);
  885.         Registers[REGISTER_A] = (BYTE)temp_word;
  886.         break;
  887.  
  888.     case 0xE0: //ADC (A, H)
  889.         temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_H];
  890.  
  891.         if ((Flags & FLAG_C) != 0) {
  892.             temp_word++;
  893.         }
  894.  
  895.         if (temp_word >= 0x100) {
  896.             Flags = Flags | FLAG_C; //Set carry flag
  897.         }
  898.         else {
  899.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  900.         }
  901.  
  902.         set_flag_n((BYTE)temp_word);
  903.         set_flag_z((BYTE)temp_word);
  904.         set_flag_v(Registers[REGISTER_A], Registers[REGISTER_H], (BYTE)temp_word);
  905.         Registers[REGISTER_A] = (BYTE)temp_word;
  906.         break;
  907.  
  908.     case 0xF0: //ADC (A, M)
  909.         temp_word = (WORD)Registers[REGISTER_A] + (WORD)Registers[REGISTER_M];
  910.  
  911.         if ((Flags & FLAG_C) != 0) {
  912.             temp_word++;
  913.         }
  914.  
  915.         if (temp_word >= 0x100) {
  916.             Flags = Flags | FLAG_C; //Set carry flag
  917.         }
  918.         else {
  919.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  920.         }
  921.  
  922.         set_flag_n((BYTE)temp_word);
  923.         set_flag_z((BYTE)temp_word);
  924.         set_flag_v(Registers[REGISTER_A], Registers[REGISTER_M], (BYTE)temp_word);
  925.         Registers[REGISTER_A] = (BYTE)temp_word;
  926.         break;
  927.  
  928.  
  929.  
  930.         /*
  931.         *   Opcode: CMP
  932.         *   Description: Register compared to Accumulator
  933.         *   Flags: - - T T T - - T
  934.         */
  935.  
  936.     case 0x92: //CMP (A, B)
  937.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
  938.  
  939.         if (temp_word >= 0x100) {
  940.             Flags = Flags | FLAG_C; //Set carry flag
  941.         }
  942.         else {
  943.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  944.         }
  945.  
  946.         set_flag_n((BYTE)temp_word);
  947.         set_flag_z((BYTE)temp_word);
  948.         set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_B], (BYTE)temp_word);
  949.         break;
  950.  
  951.     case 0xA2: //CMP (A, C)
  952.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
  953.  
  954.         if (temp_word >= 0x100) {
  955.             Flags = Flags | FLAG_C; //Set carry flag
  956.         }
  957.         else {
  958.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  959.         }
  960.  
  961.         set_flag_n((BYTE)temp_word);
  962.         set_flag_z((BYTE)temp_word);
  963.         set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_C], (BYTE)temp_word);
  964.         break;
  965.  
  966.     case 0xB2: //CMP (A, D)
  967.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
  968.  
  969.         if (temp_word >= 0x100) {
  970.             Flags = Flags | FLAG_C; //Set carry flag
  971.         }
  972.         else {
  973.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  974.         }
  975.  
  976.         set_flag_n((BYTE)temp_word);
  977.         set_flag_z((BYTE)temp_word);
  978.         set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_D], (BYTE)temp_word);
  979.         break;
  980.  
  981.     case 0xC2: //CMP (A, E)
  982.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
  983.  
  984.         if (temp_word >= 0x100) {
  985.             Flags = Flags | FLAG_C; //Set carry flag
  986.         }
  987.         else {
  988.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  989.         }
  990.  
  991.         set_flag_n((BYTE)temp_word);
  992.         set_flag_z((BYTE)temp_word);
  993.         set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_E], (BYTE)temp_word);
  994.         break;
  995.  
  996.     case 0xD2: //CMP (A, L)
  997.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
  998.  
  999.         if (temp_word >= 0x100) {
  1000.             Flags = Flags | FLAG_C; //Set carry flag
  1001.         }
  1002.         else {
  1003.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  1004.         }
  1005.  
  1006.         set_flag_n((BYTE)temp_word);
  1007.         set_flag_z((BYTE)temp_word);
  1008.         set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_L], (BYTE)temp_word);
  1009.         break;
  1010.  
  1011.     case 0xE2: //CMP (A, H)
  1012.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
  1013.  
  1014.         if (temp_word >= 0x100) {
  1015.             Flags = Flags | FLAG_C; //Set carry flag
  1016.         }
  1017.         else {
  1018.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  1019.         }
  1020.  
  1021.         set_flag_n((BYTE)temp_word);
  1022.         set_flag_z((BYTE)temp_word);
  1023.         set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_H], (BYTE)temp_word);
  1024.         break;
  1025.  
  1026.     case 0xF2: //CMP (A, M)
  1027.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
  1028.  
  1029.         if (temp_word >= 0x100) {
  1030.             Flags = Flags | FLAG_C; //Set carry flag
  1031.         }
  1032.         else {
  1033.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  1034.         }
  1035.  
  1036.         set_flag_n((BYTE)temp_word);
  1037.         set_flag_z((BYTE)temp_word);
  1038.         set_flag_v(Registers[REGISTER_A], -Registers[REGISTER_M], (BYTE)temp_word);
  1039.         break;
  1040.  
  1041.  
  1042.  
  1043.         /*
  1044.         *   Opcode: TSA
  1045.         *   Addressing mode(s) : impl
  1046.         *   Description: Transfers Status register to Accumulator
  1047.         *   Flags: - - - - - - - -
  1048.         */
  1049.  
  1050.     case 0x75: //TSA (impl)
  1051.         Registers[REGISTER_A] = Flags;
  1052.         break;
  1053.  
  1054.  
  1055.  
  1056.         /*
  1057.         *   Opcode: TAS
  1058.         *   Addressing mode(s) : impl
  1059.         *   Description: Transfers Accumulator to Status register
  1060.         *   Flags: - - - - - - - -
  1061.         */
  1062.  
  1063.     case 0x74: //TAS (impl)
  1064.         Flags = Registers[REGISTER_A];
  1065.         break;
  1066.  
  1067.  
  1068.  
  1069.         /*
  1070.         *   Opcode: CLC
  1071.         *   Addressing mode(s) : impl
  1072.         *   Description: Clear Carry flag
  1073.         *   Flags: - - - - - - - 0
  1074.         */
  1075.  
  1076.     case 0x15: //CLC (impl)
  1077.         Flags = Flags & (0xFF - FLAG_C);
  1078.         break;
  1079.  
  1080.  
  1081.  
  1082.         /*
  1083.         *   Opcode: SEC
  1084.         *   Addressing mode(s) : impl
  1085.         *   Description: Set Carry flag
  1086.         *   Flags: - - - - - - - 1
  1087.         */
  1088.  
  1089.     case 0x16: //SEC (impl)
  1090.         Flags = Flags | FLAG_C;
  1091.         break;
  1092.  
  1093.  
  1094.  
  1095.         /*
  1096.         *   Opcode: CLI
  1097.         *   Addressing mode(s) : impl
  1098.         *   Description: Clear Interrupt flag
  1099.         *   Flags: 0 - - - - - - -
  1100.         */
  1101.  
  1102.     case 0x17: //CLI (impl)
  1103.         Flags = Flags & (0xFF - FLAG_I);
  1104.         break;
  1105.  
  1106.  
  1107.  
  1108.         /*
  1109.         *   Opcode: STI
  1110.         *   Addressing mode(s) : impl
  1111.         *   Description: Set Interrupt flag
  1112.         *   Flags: 1 - - - - - - -
  1113.         */
  1114.  
  1115.     case 0x18: //STI (impl)
  1116.         Flags = Flags | FLAG_I;
  1117.         break;
  1118.  
  1119.  
  1120.  
  1121.         /*
  1122.         *   Opcode: SEV
  1123.         *   Addressing mode(s) : impl
  1124.         *   Description: Set Overflow flag
  1125.         *   Flags: - - - 1 - - - -
  1126.         */
  1127.  
  1128.     case 0x19: //SEV (impl)
  1129.         Flags = Flags | FLAG_V;
  1130.         break;
  1131.  
  1132.  
  1133.  
  1134.         /*
  1135.         *   Opcode: CLV
  1136.         *   Addressing mode(s) : impl
  1137.         *   Description: Clear Overflow flag
  1138.         *   Flags: - - - 0 - - - -
  1139.         */
  1140.  
  1141.     case 0x1A: //CLV (impl)
  1142.         Flags = Flags & (0xFF - FLAG_V);
  1143.         break;
  1144.  
  1145.  
  1146.         //===============================  STACK  ===============================//
  1147.  
  1148.  
  1149.         /*
  1150.         *   Opcode: PSH
  1151.         *   Description: Pushes Register onto the Stack
  1152.         *   Flags: - - - - - - - -
  1153.         */
  1154.  
  1155.     case 0x11: //PSH (A)
  1156.         if ((1 <= StackPointer < MEMORY_SIZE)) {
  1157.             Memory[StackPointer] = Registers[REGISTER_A];
  1158.             StackPointer--;
  1159.         }
  1160.         break;
  1161.  
  1162.     case 0x21: //PSH (FL)
  1163.         if ((1 <= StackPointer < MEMORY_SIZE)) {
  1164.             Memory[StackPointer] = Flags;
  1165.             StackPointer--;
  1166.         }
  1167.         break;
  1168.  
  1169.     case 0x31: //PSH (B)
  1170.         if ((1 <= StackPointer < MEMORY_SIZE)) {
  1171.             Memory[StackPointer] = Registers[REGISTER_B];
  1172.             StackPointer--;
  1173.         }
  1174.         break;
  1175.  
  1176.     case 0x41: //PSH (C)
  1177.         if ((1 <= StackPointer < MEMORY_SIZE)) {
  1178.             Memory[StackPointer] = Registers[REGISTER_C];
  1179.             StackPointer--;
  1180.         }
  1181.         break;
  1182.  
  1183.     case 0x51: //PSH (D)
  1184.         if ((1 <= StackPointer < MEMORY_SIZE)) {
  1185.             Memory[StackPointer] = Registers[REGISTER_D];
  1186.             StackPointer--;
  1187.         }
  1188.         break;
  1189.  
  1190.     case 0x61: //PSH (E)
  1191.         if ((1 <= StackPointer < MEMORY_SIZE)) {
  1192.             Memory[StackPointer] = Registers[REGISTER_E];
  1193.             StackPointer--;
  1194.         }
  1195.         break;
  1196.  
  1197.     case 0x71: //PSH (L)
  1198.         if ((1 <= StackPointer < MEMORY_SIZE)) {
  1199.             Memory[StackPointer] = Registers[REGISTER_L];
  1200.             StackPointer--;
  1201.         }
  1202.         break;
  1203.  
  1204.     case 0x81: //PSH (H)
  1205.         if ((1 <= StackPointer < MEMORY_SIZE)) {
  1206.             Memory[StackPointer] = Registers[REGISTER_H];
  1207.             StackPointer--;
  1208.         }
  1209.         break;
  1210.  
  1211.  
  1212.  
  1213.         /*
  1214.         *   Opcode: POP
  1215.         *   Description: Pop the top of the Stack into the Register
  1216.         *   Flags: - - - - - - - -
  1217.         */
  1218.  
  1219.     case 0x12: //POP (A)
  1220.         if (0 <= StackPointer < (MEMORY_SIZE - 1)) {
  1221.             StackPointer++;
  1222.             Registers[REGISTER_A] = Memory[StackPointer];
  1223.         }
  1224.         break;
  1225.  
  1226.     case 0x22: //POP (FL)
  1227.         if (0 <= StackPointer < (MEMORY_SIZE - 1)) {
  1228.             StackPointer++;
  1229.             Flags = Memory[StackPointer];
  1230.         }
  1231.         break;
  1232.  
  1233.     case 0x32: //POP (B)
  1234.         if (0 <= StackPointer < (MEMORY_SIZE - 1)) {
  1235.             StackPointer++;
  1236.             Registers[REGISTER_B] = Memory[StackPointer];
  1237.         }
  1238.         break;
  1239.  
  1240.     case 0x42: //POP (C)
  1241.         if (0 <= StackPointer < (MEMORY_SIZE - 1)) {
  1242.             StackPointer++;
  1243.             Registers[REGISTER_C] = Memory[StackPointer];
  1244.         }
  1245.         break;
  1246.  
  1247.     case 0x52: //POP (D)
  1248.         if (0 <= StackPointer < (MEMORY_SIZE - 1)) {
  1249.             StackPointer++;
  1250.             Registers[REGISTER_D] = Memory[StackPointer];
  1251.         }
  1252.         break;
  1253.  
  1254.     case 0x62: //POP (E)
  1255.         if (0 <= StackPointer < (MEMORY_SIZE - 1)) {
  1256.             StackPointer++;
  1257.             Registers[REGISTER_E] = Memory[StackPointer];
  1258.         }
  1259.         break;
  1260.  
  1261.     case 0x72: //POP (L)
  1262.         if (0 <= StackPointer < (MEMORY_SIZE - 1)) {
  1263.             StackPointer++;
  1264.             Registers[REGISTER_L] = Memory[StackPointer];
  1265.         }
  1266.         break;
  1267.  
  1268.     case 0x82: //POP (H)
  1269.         if (0 <= StackPointer < (MEMORY_SIZE - 1)) {
  1270.             StackPointer++;
  1271.             Registers[REGISTER_H] = Memory[StackPointer];
  1272.         }
  1273.         break;
  1274.  
  1275.  
  1276.  
  1277.         /*
  1278.         *   Opcode: JMP
  1279.         *   Addressing mode(s) : abs
  1280.         *   Description: Load Memory into ProgramCounter
  1281.         *   Flags: - - - - - - - -
  1282.         */
  1283.  
  1284.     case 0xFA: //JMP (abs)
  1285.         HB = fetch();
  1286.         LB = fetch();
  1287.         address = ((WORD)HB << 8) + (WORD)LB;
  1288.  
  1289.         if (0 <= address < MEMORY_SIZE) {
  1290.             ProgramCounter = address;
  1291.         }
  1292.         break;
  1293.  
  1294.  
  1295.  
  1296.         /*
  1297.         *   Opcode: JPR
  1298.         *   Addressing mode(s) : abs
  1299.         *   Description: Jump to subroutine
  1300.         *   Flags: - - - - - - - -
  1301.         */
  1302.  
  1303.     case 0x33: //JPR (abs)
  1304.         HB = fetch();
  1305.         LB = fetch();
  1306.         address = ((WORD)HB << 8) + (WORD)LB;
  1307.  
  1308.         if (2 <= StackPointer < MEMORY_SIZE) {
  1309.             Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1310.             StackPointer--;
  1311.             Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1312.             StackPointer--;
  1313.         }
  1314.         ProgramCounter = address;
  1315.         break;
  1316.  
  1317.  
  1318.  
  1319.         /*
  1320.         *   Opcode: RTN
  1321.         *   Addressing mode(s) : impl
  1322.         *   Description: Return from subroutine
  1323.         *   Flags: - - - - - - - -
  1324.         */
  1325.  
  1326.     case 0x0E: //RTN(impl)
  1327.         if (0 <= StackPointer < (MEMORY_SIZE - 2)) {
  1328.             StackPointer++;
  1329.             HB = Memory[StackPointer];
  1330.             StackPointer++;
  1331.         }
  1332.         ProgramCounter = ((WORD)HB << 8) + (WORD)LB;
  1333.         break;
  1334.  
  1335.  
  1336.  
  1337.         /*
  1338.         *   Opcode: BRA
  1339.         *   Addressing mode(s) : rel
  1340.         *   Description: Branch always
  1341.         *   Flags: - - - - - - - -
  1342.         */
  1343.  
  1344.     case 0x00: //BRA (rel)
  1345.         LB = fetch();
  1346.  
  1347.         offset = (WORD)LB;
  1348.         if ((offset & 0x80) != 0) {
  1349.             offset += 0xFF00;
  1350.         }
  1351.         address = ProgramCounter + offset;
  1352.         break;
  1353.  
  1354.  
  1355.  
  1356.         /*
  1357.         *   Opcode: BCC
  1358.         *   Addressing mode(s) : rel
  1359.         *   Description: Branch on Carry clear
  1360.         *   Flags: - - - - - - - -
  1361.         */
  1362.  
  1363.     case 0x01: //BCC (rel)
  1364.         LB = fetch();
  1365.  
  1366.         if (CF == 0) {
  1367.             offset = (WORD)LB;
  1368.             if ((offset & 0x80) != 0) {
  1369.                 offset += 0xFF00;
  1370.             }
  1371.             address = ProgramCounter + offset;
  1372.             ProgramCounter = address;
  1373.         }
  1374.         break;
  1375.  
  1376.  
  1377.  
  1378.         /*
  1379.         *   Opcode: BCS
  1380.         *   Addressing mode(s) : rel
  1381.         *   Description: Branch on Carry set
  1382.         *   Flags: - - - - - - - -
  1383.         */
  1384.  
  1385.     case 0x02: //BCS (rel)
  1386.         LB = fetch();
  1387.  
  1388.         if (CF == 1) {
  1389.             offset = (WORD)LB;
  1390.             if ((offset & 0x80) != 0) {
  1391.                 offset += 0xFF00;
  1392.             }
  1393.             address = ProgramCounter + offset;
  1394.             ProgramCounter = address;
  1395.         }
  1396.         break;
  1397.  
  1398.  
  1399.  
  1400.         /*
  1401.         *   Opcode: BNE
  1402.         *   Addressing mode(s) : rel
  1403.         *   Description: Branch on Result not Zero
  1404.         *   Flags: - - - - - - - -
  1405.         */
  1406.  
  1407.     case 0x03: //BNE (rel)
  1408.         LB = fetch();
  1409.  
  1410.         if (ZF == 0) {
  1411.             offset = (WORD)LB;
  1412.             if ((offset & 0x80) != 0) {
  1413.                 offset += 0xFF00;
  1414.             }
  1415.             address = ProgramCounter + offset;
  1416.             ProgramCounter = address;
  1417.         }
  1418.         break;
  1419.  
  1420.  
  1421.  
  1422.         /*
  1423.         *   Opcode: BEQ
  1424.         *   Addressing mode(s) : rel
  1425.         *   Description: Branch on Result equal to Zero
  1426.         *   Flags: - - - - - - - -
  1427.         */
  1428.  
  1429.     case 0x04: //BEQ (rel)
  1430.         LB = fetch();
  1431.  
  1432.         if (ZF == 1) {
  1433.             offset = (WORD)LB;
  1434.             if ((offset & 0x80) != 0) {
  1435.                 offset += 0xFF00;
  1436.             }
  1437.             address = ProgramCounter + offset;
  1438.             ProgramCounter = address;
  1439.         }
  1440.         break;
  1441.  
  1442.  
  1443.  
  1444.         /*
  1445.         *   Opcode: BVC
  1446.         *   Addressing mode(s) : rel
  1447.         *   Description: Branch on Overflow clear
  1448.         *   Flags: - - - - - - - -
  1449.         */
  1450.  
  1451.     case 0x05: //BVC (rel)
  1452.         LB = fetch();
  1453.  
  1454.         if (VF == 0) {
  1455.             offset = (WORD)LB;
  1456.             if ((offset & 0x80) != 0) {
  1457.                 offset += 0xFF00;
  1458.             }
  1459.             address = ProgramCounter + offset;
  1460.             ProgramCounter = address;
  1461.         }
  1462.         break;
  1463.  
  1464.  
  1465.  
  1466.         /*
  1467.         *   Opcode: BVS
  1468.         *   Addressing mode(s) : rel
  1469.         *   Description: Branch on Overflow set
  1470.         *   Flags: - - - - - - - -
  1471.         */
  1472.  
  1473.     case 0x06: //BVS (rel)
  1474.         LB = fetch();
  1475.  
  1476.         if (VF == 1) {
  1477.             offset = (WORD)LB;
  1478.             if ((offset & 0x80) != 0) {
  1479.                 offset += 0xFF00;
  1480.             }
  1481.             address = ProgramCounter + offset;
  1482.             ProgramCounter = address;
  1483.         }
  1484.         break;
  1485.  
  1486.  
  1487.  
  1488.         /*
  1489.         *   Opcode: BMI
  1490.         *   Addressing mode(s) : rel
  1491.         *   Description: Branch on negative result
  1492.         *   Flags: - - - - - - - -
  1493.         */
  1494.  
  1495.     case 0x07: //BMI (rel)
  1496.         LB = fetch();
  1497.  
  1498.         if (NF == 1) {
  1499.             offset = (WORD)LB;
  1500.             if ((offset & 0x80) != 0) {
  1501.                 offset += 0xFF00;
  1502.             }
  1503.             address = ProgramCounter + offset;
  1504.             ProgramCounter = address;
  1505.         }
  1506.         break;
  1507.  
  1508.  
  1509.  
  1510.         /*
  1511.         *   Opcode: BPL
  1512.         *   Addressing mode(s) : rel
  1513.         *   Description: Branch on positive result
  1514.         *   Flags: - - - - - - - -
  1515.         */
  1516.  
  1517.     case 0x08: //BPL (rel)
  1518.         LB = fetch();
  1519.  
  1520.         if (NF == 0) {
  1521.             offset = (WORD)LB;
  1522.             if ((offset & 0x80) != 0) {
  1523.                 offset += 0xFF00;
  1524.             }
  1525.             address = ProgramCounter + offset;
  1526.             ProgramCounter = address;
  1527.         }
  1528.         break;
  1529.  
  1530.  
  1531.  
  1532.         /*
  1533.         *   Opcode: BGE
  1534.         *   Addressing mode(s) : rel
  1535.         *   Description: Branch on result less than or equal to zero
  1536.         *   Flags: - - - - - - - -
  1537.         */
  1538.  
  1539.     case 0x09: //BGE (rel)
  1540.         LB = fetch();
  1541.  
  1542.         if ((NF ^ VF) == 0) {
  1543.             offset = (WORD)LB;
  1544.             if ((offset & 0x80) != 0) {
  1545.                 offset += 0xFF00;
  1546.             }
  1547.             address = ProgramCounter + offset;
  1548.             ProgramCounter = address;
  1549.         }
  1550.         break;
  1551.  
  1552.  
  1553.  
  1554.         /*
  1555.         *   Opcode: BLE
  1556.         *   Addressing mode(s) : rel
  1557.         *   Description: Branch on result greater than or equal to zero
  1558.         *   Flags: - - - - - - - -
  1559.         */
  1560.  
  1561.     case 0x0A: //BLE (rel)
  1562.         LB = fetch();
  1563.  
  1564.         if ((ZF | NF ^ VF) == 1) {
  1565.             offset = (WORD)LB;
  1566.             if ((offset & 0x80) != 0) {
  1567.                 offset += 0xFF00;
  1568.             }
  1569.             address = ProgramCounter + offset;
  1570.             ProgramCounter = address;
  1571.         }
  1572.         break;
  1573.  
  1574.  
  1575.  
  1576.         /*
  1577.         *   Opcode: BLS
  1578.         *   Addressing mode(s) : rel
  1579.         *   Description: Branch on result same or lower
  1580.         *   Flags: - - - - - - - -
  1581.         */
  1582.  
  1583.     case 0x0B: //BLS (rel)
  1584.         LB = fetch();
  1585.  
  1586.         if ((CF | ZF) == 1) {
  1587.             offset = (WORD)LB;
  1588.             if ((offset & 0x80) != 0) {
  1589.                 offset += 0xFF00;
  1590.             }
  1591.             address = ProgramCounter + offset;
  1592.             ProgramCounter = address;
  1593.         }
  1594.         break;
  1595.  
  1596.  
  1597.  
  1598.         /*
  1599.         *   Opcode: BHI
  1600.         *   Addressing mode(s) : rel
  1601.         *   Description: Branch on result higher
  1602.         *   Flags: - - - - - - - -
  1603.         */
  1604.  
  1605.     case 0x0C: //BHI (rel)
  1606.         LB = fetch();
  1607.  
  1608.         if ((CF | ZF) == 0) {
  1609.             offset = (WORD)LB;
  1610.             if ((offset & 0x80) != 0) {
  1611.                 offset += 0xFF00;
  1612.             }
  1613.             address = ProgramCounter + offset;
  1614.             ProgramCounter = address;
  1615.         }
  1616.         break;
  1617.  
  1618.  
  1619.  
  1620.         /*
  1621.         *   Opcode: CCC
  1622.         *   Addressing mode(s) : abs
  1623.         *   Description: Call on Carry clear
  1624.         *   Flags: - - - - - - - -
  1625.         */
  1626.  
  1627.     case 0x34: //CCC (abs)
  1628.         HB = fetch();
  1629.         LB = fetch();
  1630.  
  1631.         if (CF == 0) {
  1632.             address += (WORD)((WORD)HB << 8) + LB;
  1633.             if (0 <= address < MEMORY_SIZE) {
  1634.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1635.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1636.                     StackPointer--;
  1637.  
  1638.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1639.                     StackPointer--;
  1640.                 }
  1641.                 ProgramCounter = (WORD)address;
  1642.             }
  1643.         }
  1644.         break;
  1645.  
  1646.  
  1647.  
  1648.         /*
  1649.         *   Opcode: CCS
  1650.         *   Addressing mode(s) : abs
  1651.         *   Description: Call on Carry set
  1652.         *   Flags: - - - - - - - -
  1653.         */
  1654.  
  1655.     case 0x35: //CCS (abs)
  1656.         HB = fetch();
  1657.         LB = fetch();
  1658.  
  1659.         if (CF == 1) {
  1660.             address += (WORD)((WORD)HB << 8) + LB;
  1661.             if (0 <= address < MEMORY_SIZE) {
  1662.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1663.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1664.                     StackPointer--;
  1665.  
  1666.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1667.                     StackPointer--;
  1668.                 }
  1669.                 ProgramCounter = (WORD)address;
  1670.             }
  1671.         }
  1672.         break;
  1673.  
  1674.  
  1675.  
  1676.         /*
  1677.         *   Opcode: CNE
  1678.         *   Addressing mode(s) : abs
  1679.         *   Description: Call on result not Zero
  1680.         *   Flags: - - - - - - - -
  1681.         */
  1682.  
  1683.     case 0x36: //CNE (abs)
  1684.         HB = fetch();
  1685.         LB = fetch();
  1686.  
  1687.         if (ZF == 0) {
  1688.             address += (WORD)((WORD)HB << 8) + LB;
  1689.             if (0 <= address < MEMORY_SIZE) {
  1690.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1691.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1692.                     StackPointer--;
  1693.  
  1694.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1695.                     StackPointer--;
  1696.                 }
  1697.                 ProgramCounter = (WORD)address;
  1698.             }
  1699.         }
  1700.         break;
  1701.  
  1702.  
  1703.  
  1704.         /*
  1705.         *   Opcode: CEQ
  1706.         *   Addressing mode(s) : abs
  1707.         *   Description: Call on result equal to Zero
  1708.         *   Flags: - - - - - - - -
  1709.         */
  1710.  
  1711.     case 0x37: //CEQ (abs)
  1712.         HB = fetch();
  1713.         LB = fetch();
  1714.  
  1715.         if (ZF == 1) {
  1716.             address += (WORD)((WORD)HB << 8) + LB;
  1717.             if (0 <= address < MEMORY_SIZE) {
  1718.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1719.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1720.                     StackPointer--;
  1721.  
  1722.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1723.                     StackPointer--;
  1724.                 }
  1725.                 ProgramCounter = (WORD)address;
  1726.             }
  1727.         }
  1728.         break;
  1729.  
  1730.  
  1731.  
  1732.         /*
  1733.         *   Opcode: CVC
  1734.         *   Addressing mode(s) : abs
  1735.         *   Description: Call on Overflow clear
  1736.         *   Flags: - - - - - - - -
  1737.         */
  1738.  
  1739.     case 0x38: //CVC (abs)
  1740.         HB = fetch();
  1741.         LB = fetch();
  1742.  
  1743.         if (VF == 0) {
  1744.             address += (WORD)((WORD)HB << 8) + LB;
  1745.             if (0 <= address < MEMORY_SIZE) {
  1746.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1747.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1748.                     StackPointer--;
  1749.  
  1750.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1751.                     StackPointer--;
  1752.                 }
  1753.                 ProgramCounter = (WORD)address;
  1754.             }
  1755.         }
  1756.         break;
  1757.  
  1758.  
  1759.  
  1760.         /*
  1761.         *   Opcode: CVS
  1762.         *   Addressing mode(s) : abs
  1763.         *   Description: Call on Overflow set
  1764.         *   Flags: - - - - - - - -
  1765.         */
  1766.  
  1767.     case 0x39: //CVS (abs)
  1768.         HB = fetch();
  1769.         LB = fetch();
  1770.  
  1771.         if (VF == 1) {
  1772.             address += (WORD)((WORD)HB << 8) + LB;
  1773.             if (0 <= address < MEMORY_SIZE) {
  1774.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1775.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1776.                     StackPointer--;
  1777.  
  1778.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1779.                     StackPointer--;
  1780.                 }
  1781.                 ProgramCounter = (WORD)address;
  1782.             }
  1783.         }
  1784.         break;
  1785.  
  1786.  
  1787.  
  1788.         /*
  1789.         *   Opcode: CMI
  1790.         *   Addressing mode(s) : abs
  1791.         *   Description: Call on negative result
  1792.         *   Flags: - - - - - - - -
  1793.         */
  1794.  
  1795.     case 0x3A: //CMI (abs)
  1796.         HB = fetch();
  1797.         LB = fetch();
  1798.  
  1799.         if (NF == 1) {
  1800.             address += (WORD)((WORD)HB << 8) + LB;
  1801.             if (0 <= address < MEMORY_SIZE) {
  1802.                 if ((2 <= StackPointer < MEMORY_SIZE)) {
  1803.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1804.                     StackPointer--;
  1805.                    
  1806.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1807.                     StackPointer--;
  1808.                 }
  1809.                 ProgramCounter = (WORD)address;
  1810.             }
  1811.         }
  1812.         break;
  1813.  
  1814.  
  1815.  
  1816.         /*
  1817.         *   Opcode: CPL
  1818.         *   Addressing mode(s) : abs
  1819.         *   Description: Call on positive result
  1820.         *   Flags: - - - - - - - -
  1821.         */
  1822.  
  1823.     case 0x3B: //CPL (abs)
  1824.         HB = fetch();
  1825.         LB = fetch();
  1826.  
  1827.         if (NF == 0) {
  1828.             address += (WORD)((WORD)HB << 8) + LB;
  1829.             if (0 <= address < MEMORY_SIZE) {
  1830.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1831.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1832.                     StackPointer--;
  1833.  
  1834.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1835.                     StackPointer--;
  1836.                 }
  1837.                 ProgramCounter = (WORD)address;
  1838.             }
  1839.         }
  1840.         break;
  1841.  
  1842.  
  1843.  
  1844.         /*
  1845.         *   Opcode: CHI
  1846.         *   Addressing mode(s) : abs
  1847.         *   Description: Call on result same or lower
  1848.         *   Flags: - - - - - - - -
  1849.         */
  1850.  
  1851.     case 0x3C: //CHI (abs)
  1852.         HB = fetch();
  1853.         LB = fetch();
  1854.  
  1855.         if ((CF | ZF) == 1) {
  1856.             address += (WORD)((WORD)HB << 8) + LB;
  1857.             if (0 <= address < MEMORY_SIZE) {
  1858.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1859.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1860.                     StackPointer--;
  1861.  
  1862.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1863.                     StackPointer--;
  1864.                 }
  1865.                 ProgramCounter = (WORD)address;
  1866.             }
  1867.         }
  1868.         break;
  1869.  
  1870.  
  1871.  
  1872.         /*
  1873.         *   Opcode: CLE
  1874.         *   Addressing mode(s) : abs
  1875.         *   Description: Call on result higher
  1876.         *   Flags: - - - - - - - -
  1877.         */
  1878.  
  1879.     case 0x3D: //CLE (abs)
  1880.         HB = fetch();
  1881.         LB = fetch();
  1882.  
  1883.         if ((CF | ZF) == 0) {
  1884.             address += (WORD)((WORD)HB << 8) + LB;
  1885.             if (0 <= address < MEMORY_SIZE) {
  1886.                 if (2 <= StackPointer < MEMORY_SIZE) {
  1887.                     Memory[StackPointer] = (BYTE)(ProgramCounter & 0xFF);
  1888.                     StackPointer--;
  1889.  
  1890.                     Memory[StackPointer] = (BYTE)((ProgramCounter >> 8) & 0xFF);
  1891.                     StackPointer--;
  1892.                 }
  1893.                 ProgramCounter = (WORD)address;
  1894.             }
  1895.         }
  1896.         break;
  1897.  
  1898.  
  1899.         //===============================  INCRAMENT AND LOGIC  ===============================//
  1900.  
  1901.  
  1902.             /*
  1903.             *   Opcode: INC
  1904.             *   Addressing mode(s) : abs, abs X
  1905.             *   Description: Increment Memory or Accumulator
  1906.             *   Flags: - - T - T - - -
  1907.             */
  1908.  
  1909.     case 0x44: //INC (abs)
  1910.         HB = fetch();
  1911.         LB = fetch();
  1912.         address += (WORD)((WORD)HB << 8) + LB;
  1913.  
  1914.         if (0 <= address < MEMORY_SIZE) {
  1915.             Memory[address]++;
  1916.         }
  1917.         set_flag_n(Memory[address]);
  1918.         set_flag_z(Memory[address]);
  1919.         break;
  1920.  
  1921.     case 0x54: //INC (abs, X)
  1922.         address += IndexRegister;
  1923.         HB = fetch();
  1924.         LB = fetch();
  1925.         address += (WORD)((WORD)HB << 8) + LB;
  1926.  
  1927.         if (0 <= address < MEMORY_SIZE) {
  1928.             Memory[address]++;
  1929.         }
  1930.  
  1931.         set_flag_n(Memory[address]);
  1932.         set_flag_z(Memory[address]);
  1933.         break;
  1934.  
  1935.  
  1936.  
  1937.         /*
  1938.         *   Opcode: INCA
  1939.         *   Description: Increment Memory or Accumulator
  1940.         *   Flags: - - T - T - - -
  1941.         */
  1942.  
  1943.     case 0x64: //INCA (A)
  1944.         Registers[REGISTER_A]++;
  1945.  
  1946.         set_flag_n(Registers[REGISTER_A]);
  1947.         set_flag_z(Registers[REGISTER_A]);
  1948.         break;
  1949.  
  1950.  
  1951.  
  1952.         /*
  1953.         *   Opcode: INX
  1954.         *   Addressing mode(s) : impl
  1955.         *   Description: Increments register X
  1956.         *   Flags: - - - - T - - -
  1957.         */
  1958.  
  1959.     case 0x1C: //INX (impl)
  1960.         IndexRegister++;
  1961.         set_flag_z(IndexRegister);
  1962.         break;
  1963.  
  1964.  
  1965.  
  1966.         /*
  1967.         *   Opcode: DEX
  1968.         *   Addressing mode(s) : impl
  1969.         *   Description: Decrements register X
  1970.         *   Flags: - - - - T - - -
  1971.         */
  1972.  
  1973.     case 0x1B: //DEX (impl)
  1974.         IndexRegister--;
  1975.         set_flag_z(IndexRegister);
  1976.         break;
  1977.  
  1978.  
  1979.  
  1980.         /*
  1981.         *   Opcode: AND
  1982.         *   Description: Register bitwise and with Accumulator
  1983.         *   Flags: - - T - T - - -
  1984.         */
  1985.  
  1986.     case 0x94: //AND (A, B)
  1987.         Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_B];
  1988.         set_flag_n(Registers[REGISTER_A]);
  1989.         set_flag_z(Registers[REGISTER_A]);
  1990.         break;
  1991.  
  1992.     case 0xA4: //AND (A, C)
  1993.         Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_C];
  1994.         set_flag_n(Registers[REGISTER_A]);
  1995.         set_flag_z(Registers[REGISTER_A]);
  1996.         break;
  1997.  
  1998.     case 0xB4: //AND (A, D)
  1999.         Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_D];
  2000.         set_flag_n(Registers[REGISTER_A]);
  2001.         set_flag_z(Registers[REGISTER_A]);
  2002.         break;
  2003.  
  2004.     case 0xC4: //AND (A, E)
  2005.         Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_E];
  2006.         set_flag_n(Registers[REGISTER_A]);
  2007.         set_flag_z(Registers[REGISTER_A]);
  2008.         break;
  2009.  
  2010.     case 0xD4: //AND (A, L)
  2011.         Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_L];
  2012.         set_flag_n(Registers[REGISTER_A]);
  2013.         set_flag_z(Registers[REGISTER_A]);
  2014.         break;
  2015.  
  2016.     case 0xE4: //AND (A, H)
  2017.         Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_H];
  2018.         set_flag_n(Registers[REGISTER_A]);
  2019.         set_flag_z(Registers[REGISTER_A]);
  2020.         break;
  2021.  
  2022.     case 0xF4: //AND (A, M)
  2023.         Registers[REGISTER_A] = Registers[REGISTER_A] & Registers[REGISTER_M];
  2024.         set_flag_n(Registers[REGISTER_A]);
  2025.         set_flag_z(Registers[REGISTER_A]);
  2026.         break;
  2027.  
  2028.  
  2029.  
  2030.         /*
  2031.         *   Opcode: BT
  2032.         *   Description: Register Bit tested with Accumulator
  2033.         *   Flags: - - T - T - - -
  2034.         */
  2035.  
  2036.     case 0x96: //BT (A, B)
  2037.         data = Registers[REGISTER_A] & Registers[REGISTER_B];
  2038.         set_flag_n(data);
  2039.         set_flag_z(data);
  2040.         break;
  2041.  
  2042.     case 0xA6: //BT (A, C)
  2043.         data = Registers[REGISTER_A] & Registers[REGISTER_C];
  2044.         set_flag_n(data);
  2045.         set_flag_z(data);
  2046.         break;
  2047.  
  2048.     case 0xB6: //BT (A, D)
  2049.         data = Registers[REGISTER_A] & Registers[REGISTER_D];
  2050.         set_flag_n(data);
  2051.         set_flag_z(data);
  2052.         break;
  2053.  
  2054.     case 0xC6: //BT (A, E)
  2055.         data = Registers[REGISTER_A] & Registers[REGISTER_E];
  2056.         set_flag_n(data);
  2057.         set_flag_z(data);
  2058.         break;
  2059.  
  2060.     case 0xD6: //BT (A, L)
  2061.         data = Registers[REGISTER_A] & Registers[REGISTER_L];
  2062.         set_flag_n(data);
  2063.         set_flag_z(data);
  2064.         break;
  2065.  
  2066.     case 0xE6: //BT (A, H)
  2067.         data = Registers[REGISTER_A] & Registers[REGISTER_H];
  2068.         set_flag_n(data);
  2069.         set_flag_z(data);
  2070.         break;
  2071.  
  2072.     case 0xF6: //BT (A, M)
  2073.         data = Registers[REGISTER_A] & Registers[REGISTER_M];
  2074.         set_flag_n(data);
  2075.         set_flag_z(data);
  2076.         break;
  2077.  
  2078.  
  2079.         //===============================  MATHS  ===============================//
  2080.  
  2081.  
  2082.             /*
  2083.             *   Opcode: SBC
  2084.             *   Description: Register subtracted to Accumulator with Carry
  2085.             *   Flags: - - T T T - - T
  2086.             */
  2087.  
  2088.     case 0x91: //SBC (A, B)
  2089.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_B];
  2090.  
  2091.         if ((Flags & FLAG_C) != 0) {
  2092.             temp_word--;
  2093.         }
  2094.  
  2095.         if (temp_word >= 0x100) {
  2096.             Flags = Flags | FLAG_C; //Set carry flag
  2097.         }
  2098.         else {
  2099.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2100.         }
  2101.  
  2102.         set_flag_n((BYTE)temp_word);
  2103.         set_flag_z((BYTE)temp_word);
  2104.         set_flag_v(REGISTER_A, -REGISTER_B, (BYTE)temp_word);
  2105.         Registers[REGISTER_A] = (BYTE)temp_word;
  2106.         break;
  2107.  
  2108.     case 0xA1: //SBC (A, C)
  2109.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_C];
  2110.  
  2111.         if ((Flags & FLAG_C) != 0) {
  2112.             temp_word--;
  2113.         }
  2114.  
  2115.         if (temp_word >= 0x100) {
  2116.             Flags = Flags | FLAG_C; //Set carry flag
  2117.         }
  2118.         else {
  2119.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2120.         }
  2121.  
  2122.         set_flag_n((BYTE)temp_word);
  2123.         set_flag_z((BYTE)temp_word);
  2124.         set_flag_v(REGISTER_A, -REGISTER_C, (BYTE)temp_word);
  2125.         Registers[REGISTER_A] = (BYTE)temp_word;
  2126.         break;
  2127.  
  2128.     case 0xB1: //SBC (A, D)
  2129.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_D];
  2130.  
  2131.         if ((Flags & FLAG_C) != 0) {
  2132.             temp_word--;
  2133.         }
  2134.  
  2135.         if (temp_word >= 0x100) {
  2136.             Flags = Flags | FLAG_C; //Set carry flag
  2137.         }
  2138.         else {
  2139.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2140.         }
  2141.  
  2142.         set_flag_n((BYTE)temp_word);
  2143.         set_flag_z((BYTE)temp_word);
  2144.         set_flag_v(REGISTER_A, -REGISTER_D, (BYTE)temp_word);
  2145.         Registers[REGISTER_A] = (BYTE)temp_word;
  2146.         break;
  2147.  
  2148.     case 0xC1: //SBC (A, E)
  2149.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_E];
  2150.  
  2151.         if ((Flags & FLAG_C) != 0) {
  2152.             temp_word--;
  2153.         }
  2154.  
  2155.         if (temp_word >= 0x100) {
  2156.             Flags = Flags | FLAG_C; //Set carry flag
  2157.         }
  2158.         else {
  2159.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2160.         }
  2161.  
  2162.         set_flag_n((BYTE)temp_word);
  2163.         set_flag_z((BYTE)temp_word);
  2164.         set_flag_v(REGISTER_A, -REGISTER_E, (BYTE)temp_word);
  2165.         Registers[REGISTER_A] = (BYTE)temp_word;
  2166.         break;
  2167.  
  2168.     case 0xD1: //SBC (A, L)
  2169.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_L];
  2170.  
  2171.         if ((Flags & FLAG_C) != 0) {
  2172.             temp_word--;
  2173.         }
  2174.  
  2175.         if (temp_word >= 0x100) {
  2176.             Flags = Flags | FLAG_C; //Set carry flag
  2177.         }
  2178.         else {
  2179.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2180.         }
  2181.  
  2182.         set_flag_n((BYTE)temp_word);
  2183.         set_flag_z((BYTE)temp_word);
  2184.         set_flag_v(REGISTER_A, -REGISTER_L, (BYTE)temp_word);
  2185.         Registers[REGISTER_A] = (BYTE)temp_word;
  2186.         break;
  2187.  
  2188.     case 0xE1: //SBC (A, H)
  2189.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_H];
  2190.  
  2191.         if ((Flags & FLAG_C) != 0) {
  2192.             temp_word--;
  2193.         }
  2194.  
  2195.         if (temp_word >= 0x100) {
  2196.             Flags = Flags | FLAG_C; //Set carry flag
  2197.         }
  2198.         else {
  2199.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2200.         }
  2201.  
  2202.         set_flag_n((BYTE)temp_word);
  2203.         set_flag_z((BYTE)temp_word);
  2204.         set_flag_v(REGISTER_A, -REGISTER_H, (BYTE)temp_word);
  2205.         Registers[REGISTER_A] = (BYTE)temp_word;
  2206.         break;
  2207.  
  2208.     case 0xF1: //SBC (A, M)
  2209.         address = (WORD)Registers[REGISTER_H] << 8 + Registers[REGISTER_L];
  2210.         Registers[REGISTER_M] = Memory[address];
  2211.  
  2212.         temp_word = (WORD)Registers[REGISTER_A] - (WORD)Registers[REGISTER_M];
  2213.  
  2214.         if ((Flags & FLAG_C) != 0) {
  2215.             temp_word--;
  2216.         }
  2217.  
  2218.         if (temp_word >= 0x100) {
  2219.             Flags = Flags | FLAG_C; //Set carry flag
  2220.         }
  2221.         else {
  2222.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2223.         }
  2224.  
  2225.         set_flag_n((BYTE)temp_word);
  2226.         set_flag_z((BYTE)temp_word);
  2227.         set_flag_v(REGISTER_A, -REGISTER_M, (BYTE)temp_word);
  2228.         Registers[REGISTER_A] = (BYTE)temp_word;
  2229.         break;
  2230.  
  2231.  
  2232.  
  2233.         /*
  2234.         *   Opcode: IOR
  2235.         *   Description: Register bitwise inclusive or with Accumulator
  2236.         *   Flags: - - T - T - - -
  2237.         */
  2238.  
  2239.     case 0x93: //IOR (A, B)
  2240.         Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_B];
  2241.         set_flag_n(Registers[REGISTER_A]);
  2242.         set_flag_z(Registers[REGISTER_A]);
  2243.         break;
  2244.  
  2245.     case 0xA3: //IOR (A, C)
  2246.         Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_C];
  2247.         set_flag_n(Registers[REGISTER_A]);
  2248.         set_flag_z(Registers[REGISTER_A]);
  2249.         break;
  2250.  
  2251.     case 0xB3: //IOR (A, D)
  2252.         Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_D];
  2253.         set_flag_n(Registers[REGISTER_A]);
  2254.         set_flag_z(Registers[REGISTER_A]);
  2255.         break;
  2256.  
  2257.     case 0xC3: //IOR (A, E)
  2258.         Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_E];
  2259.         set_flag_n(Registers[REGISTER_A]);
  2260.         set_flag_z(Registers[REGISTER_A]);
  2261.         break;
  2262.  
  2263.     case 0xD3: //IOR (A, L)
  2264.         Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_L];
  2265.         set_flag_n(Registers[REGISTER_A]);
  2266.         set_flag_z(Registers[REGISTER_A]);
  2267.         break;
  2268.  
  2269.     case 0xE3: //IOR (A, H)
  2270.         Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_H];
  2271.         set_flag_n(Registers[REGISTER_A]);
  2272.         set_flag_z(Registers[REGISTER_A]);
  2273.         break;
  2274.  
  2275.     case 0xF3: //IOR (A, M)
  2276.         Registers[REGISTER_A] = Registers[REGISTER_A] | Registers[REGISTER_M];
  2277.         set_flag_n(Registers[REGISTER_A]);
  2278.         set_flag_z(Registers[REGISTER_A]);
  2279.         break;
  2280.  
  2281.  
  2282.  
  2283.        /*
  2284.        *   Opcode: XOR
  2285.        *   Description: Register bitwise exclusive or with accumulator
  2286.        *   Flags: - - T - T - - -
  2287.        */
  2288.  
  2289.     case 0x95: //XOR (A, B)
  2290.         Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_B];
  2291.         set_flag_n(Registers[REGISTER_A]);
  2292.         set_flag_z(Registers[REGISTER_A]);
  2293.         break;
  2294.  
  2295.     case 0xA5: //XOR (A, C)
  2296.         Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_C];
  2297.         set_flag_n(Registers[REGISTER_A]);
  2298.         set_flag_z(Registers[REGISTER_A]);
  2299.         break;
  2300.  
  2301.     case 0xB5: //XOR (A, D)
  2302.         Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_D];
  2303.         set_flag_n(Registers[REGISTER_A]);
  2304.         set_flag_z(Registers[REGISTER_A]);
  2305.         break;
  2306.  
  2307.     case 0xC5: //XOR (A, E)
  2308.         Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_E];
  2309.         set_flag_n(Registers[REGISTER_A]);
  2310.         set_flag_z(Registers[REGISTER_A]);
  2311.         break;
  2312.  
  2313.     case 0xD5: //XOR (A, L)
  2314.         Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_L];
  2315.         set_flag_n(Registers[REGISTER_A]);
  2316.         set_flag_z(Registers[REGISTER_A]);
  2317.         break;
  2318.  
  2319.     case 0xE5: //XOR (A, H)
  2320.         Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_H];
  2321.         set_flag_n(Registers[REGISTER_A]);
  2322.         set_flag_z(Registers[REGISTER_A]);
  2323.         break;
  2324.  
  2325.     case 0xF5: //XOR (A, M)
  2326.         Registers[REGISTER_A] = Registers[REGISTER_A] ^ Registers[REGISTER_M];
  2327.         set_flag_n(Registers[REGISTER_A]);
  2328.         set_flag_z(Registers[REGISTER_A]);
  2329.         break;
  2330.  
  2331.  
  2332.  
  2333.         /*
  2334.         *   Opcode: NOT
  2335.         *   Addressing mode(s) : abs, abs X,
  2336.         *   Description: Negate Memory or Accumulator
  2337.         *   Flags: - - T - T - - T
  2338.         */
  2339.  
  2340.     case 0x4A: //NOT (abs)
  2341.         HB = fetch();
  2342.         LB = fetch();
  2343.  
  2344.         if (0 <= address < MEMORY_SIZE) {
  2345.             Registers[REGISTER_A] = ~Memory[address];
  2346.         }
  2347.  
  2348.         if (Memory[address] >= 0x100) {
  2349.             Flags = Flags | FLAG_C; //Set carry flag
  2350.         }
  2351.         else {
  2352.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2353.         }
  2354.  
  2355.         set_flag_z(Memory[address]);
  2356.         set_flag_n(Memory[address]);
  2357.         break;
  2358.  
  2359.     case 0x5A: //NOT (abs, X)
  2360.         address += IndexRegister;
  2361.         HB = fetch();
  2362.         LB = fetch();
  2363.  
  2364.         if (0 <= address < MEMORY_SIZE) {
  2365.             Registers[REGISTER_A] = ~Memory[address];
  2366.         }
  2367.  
  2368.         if (Memory[address] >= 0x100) {
  2369.             Flags = Flags | FLAG_C; //Set carry flag
  2370.         }
  2371.         else {
  2372.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2373.         }
  2374.  
  2375.         set_flag_z(Memory[address]);
  2376.         set_flag_n(Memory[address]);
  2377.         break;
  2378.  
  2379.  
  2380.  
  2381.         /*
  2382.         *   Opcode: NOTA
  2383.         *   Description: Negate Memory or Accumulator
  2384.         *   Flags: - - T - T - - T
  2385.         */
  2386.  
  2387.     case 0x6A: //NOTA (A)
  2388.         Registers[REGISTER_A] = ~Registers[REGISTER_A];
  2389.  
  2390.         if (Registers[REGISTER_A] >= 0x100) {
  2391.             Flags = Flags | FLAG_C; //Set carry flag
  2392.         }
  2393.         else {
  2394.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2395.         }
  2396.  
  2397.         set_flag_z(Registers[REGISTER_A]);
  2398.         set_flag_n(Registers[REGISTER_A]);
  2399.         break;
  2400.  
  2401.  
  2402.  
  2403.         /*
  2404.         *   Opcode: DEC
  2405.         *   Addressing mode(s) : abs, abs X
  2406.         *   Description: Decrement Memory or Accumulator
  2407.         *   Flags: - - T - T - - -
  2408.         */
  2409.  
  2410.     case 0x45: //DEC (abs)
  2411.         HB = fetch();
  2412.         LB = fetch();
  2413.         address += (WORD)((WORD)HB << 8) + LB;
  2414.  
  2415.         if (0 <= address < MEMORY_SIZE) {
  2416.             Memory[address]--;
  2417.         }
  2418.  
  2419.         set_flag_n(Memory[address]);
  2420.         set_flag_z(Memory[address]);
  2421.         break;
  2422.  
  2423.     case 0x55: //DEC (abs, X)
  2424.         address += IndexRegister;
  2425.         HB = fetch();
  2426.         LB = fetch();
  2427.         address += (WORD)((WORD)HB << 8) + LB;
  2428.  
  2429.         if (0 <= address < MEMORY_SIZE) {
  2430.             Memory[address]--;
  2431.         }
  2432.  
  2433.         set_flag_n(Memory[address]);
  2434.         set_flag_z(Memory[address]);
  2435.         break;
  2436.  
  2437.  
  2438.  
  2439.         /*
  2440.         *   Opcode: DECA
  2441.         *   Description: Decrement Memory or Accumulator
  2442.         *   Flags: - - T - T - - -
  2443.         */
  2444.  
  2445.     case 0x65: //DECA (A)
  2446.         Registers[REGISTER_A]--;
  2447.         set_flag_z(Registers[REGISTER_A]);
  2448.         set_flag_n(Registers[REGISTER_A]);
  2449.         break;
  2450.  
  2451.  
  2452.  
  2453.         /*
  2454.         *   Opcode: SAL
  2455.         *   Addressing mode(s) : abs, abs X
  2456.         *   Description: Arithmetic shift left Memory or Accumulator
  2457.         *   Flags: - - T - T - - -
  2458.         */
  2459.  
  2460.     case 0x48: //SAL (abs)
  2461.         HB = fetch();
  2462.         LB = fetch();
  2463.         address += (WORD)((WORD)HB << 8) + LB;
  2464.  
  2465.         if (0 <= address < MEMORY_SIZE) {
  2466.             if ((Memory[address] & 0x01) == 0x01) {
  2467.                 Flags = Flags | FLAG_C;
  2468.             }
  2469.             else {
  2470.                 Flags = Flags & (0xFF - FLAG_C);
  2471.             }
  2472.  
  2473.             Memory[address] = (Memory[address] << 1) & 0x7F;
  2474.  
  2475.             if ((Flags & FLAG_N) == FLAG_N) {
  2476.                 Memory[address] = Memory[address] | 0x80;
  2477.             }
  2478.         }
  2479.  
  2480.         set_flag_z(Memory[address]);
  2481.         set_flag_n(Memory[address]);
  2482.         break;
  2483.  
  2484.     case 0x58: //SAL (abs, X)
  2485.         address += IndexRegister;
  2486.         HB = fetch();
  2487.         LB = fetch();
  2488.         address += (WORD)((WORD)HB << 8) + LB;
  2489.  
  2490.         if (0 <= address < MEMORY_SIZE) {
  2491.             if ((Memory[address] & 0x01) == 0x01) {
  2492.                 Flags = Flags | FLAG_C;
  2493.             }
  2494.             else {
  2495.                 Flags = Flags & (0xFF - FLAG_C);
  2496.             }
  2497.  
  2498.             Memory[address] = (Memory[address] << 1) & 0x7F;
  2499.  
  2500.             if ((Flags & FLAG_N) == FLAG_N) {
  2501.                 Memory[address] = Memory[address] | 0x80;
  2502.             }
  2503.         }
  2504.  
  2505.         set_flag_z(Memory[address]);
  2506.         set_flag_n(Memory[address]);
  2507.         break;
  2508.  
  2509.  
  2510.  
  2511.         /*
  2512.         *   Opcode: SALA
  2513.         *   Description: Arithmetic shift left Memory or Accumulator
  2514.         *   Flags: - - T - T - - T
  2515.         */
  2516.  
  2517.     case 0x68: //SALA (A)
  2518.         if ((Registers[REGISTER_A] & 0x01) == 0x01) {
  2519.             Flags = Flags | FLAG_C;
  2520.         }
  2521.         else {
  2522.             Flags = Flags & (0xFF - FLAG_C);
  2523.         }
  2524.  
  2525.         Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0x7F;
  2526.  
  2527.         if ((Flags & FLAG_N) == FLAG_N) {
  2528.             Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
  2529.         }
  2530.  
  2531.         if (Registers[REGISTER_A] >= 0x100) {
  2532.             Flags = Flags | FLAG_C; //Set carry flag
  2533.         }
  2534.         else {
  2535.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2536.         }
  2537.  
  2538.         set_flag_z(Registers[REGISTER_A]);
  2539.         set_flag_n(Registers[REGISTER_A]);
  2540.         break;
  2541.  
  2542.  
  2543.  
  2544.         /*
  2545.         *   Opcode: ASR
  2546.         *   Addressing mode(s) : abs, abs X
  2547.         *   Description: Arithmetic shift right Memory or Accumulator
  2548.         *   Flags: - - T - T - - -
  2549.         */
  2550.  
  2551.     case 0x49: //ASR (abs)
  2552.         HB = fetch();
  2553.         LB = fetch();
  2554.         address += (WORD)((WORD)HB << 8) + LB;
  2555.  
  2556.         if (0 <= address < MEMORY_SIZE) {
  2557.             if ((Memory[address] & 0x01) == 0x01) {
  2558.                 Flags = Flags | FLAG_C;
  2559.             }
  2560.             else {
  2561.                 Flags = Flags & (0xFF - FLAG_C);
  2562.             }
  2563.  
  2564.             Memory[address] = (Memory[address] >> 1) & 0x7F;
  2565.  
  2566.             if ((Flags & FLAG_N) == FLAG_N) {
  2567.                 Memory[address] = Memory[address] | 0x80;
  2568.             }
  2569.         }
  2570.         set_flag_n(Memory[address]);
  2571.         set_flag_z(Memory[address]);
  2572.         break;
  2573.  
  2574.     case 0x59: //ASR (abs, X)
  2575.         address += IndexRegister;
  2576.         HB = fetch();
  2577.         LB = fetch();
  2578.         address += (WORD)((WORD)HB << 8) + LB;
  2579.  
  2580.         if (0 <= address < MEMORY_SIZE) {
  2581.             if ((Memory[address] & 0x01) == 0x01) {
  2582.                 Flags = Flags | FLAG_C;
  2583.             }
  2584.             else {
  2585.                 Flags = Flags & (0xFF - FLAG_C);
  2586.             }
  2587.  
  2588.             Memory[address] = (Memory[address] >> 1) & 0x7F;
  2589.  
  2590.             if ((Flags & FLAG_N) == FLAG_N) {
  2591.                 Memory[address] = Memory[address] | 0x80;
  2592.             }
  2593.         }
  2594.         set_flag_n(Memory[address]);
  2595.         set_flag_z(Memory[address]);
  2596.         break;
  2597.  
  2598.  
  2599.  
  2600.         /*
  2601.         *   Opcode: ASRA
  2602.         *   Description: Arithmetic shift right Memory or Accumulator
  2603.         *   Flags: - - T - T - - T
  2604.         */
  2605.  
  2606.     case 0x69: //ASRA (A)
  2607.         if ((Registers[REGISTER_A] & 0x01) == 0x01) {
  2608.             Flags = Flags | FLAG_C;
  2609.         }
  2610.         else {
  2611.             Flags = Flags & (0xFF - FLAG_C);
  2612.         }
  2613.  
  2614.         Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0x7F;
  2615.  
  2616.         if ((Flags & FLAG_N) == FLAG_N) {
  2617.             Registers[REGISTER_A] = Registers[REGISTER_A] | 0x80;
  2618.         }
  2619.  
  2620.         set_flag_n(Registers[REGISTER_A]);
  2621.         set_flag_z(Registers[REGISTER_A]);
  2622.         break;
  2623.  
  2624.  
  2625.  
  2626.         /*
  2627.         *   Opcode: SWI
  2628.         *   Addressing mode(s) : impl
  2629.         *   Description: Pushes: Accumulator, ProgramCounter, Status register, General purpose registers (in order)
  2630.         *   Flags: 1 - - - - - - -
  2631.         */
  2632.  
  2633.     case 0x85: //SWI (impl)
  2634.         Flags = Flags | FLAG_I;
  2635.         if (7 <= StackPointer < MEMORY_SIZE) {
  2636.             Memory[StackPointer] = Registers[REGISTER_A];
  2637.             StackPointer--;
  2638.  
  2639.             Memory[StackPointer] = Registers[REGISTER_B];
  2640.             StackPointer--;
  2641.  
  2642.             Memory[StackPointer] = Registers[REGISTER_C];
  2643.             StackPointer--;
  2644.  
  2645.             Memory[StackPointer] = Registers[REGISTER_D];
  2646.             StackPointer--;
  2647.  
  2648.             Memory[StackPointer] = Registers[REGISTER_E];
  2649.             StackPointer--;
  2650.  
  2651.             Memory[StackPointer] = Registers[REGISTER_L];
  2652.             StackPointer--;
  2653.  
  2654.             Memory[StackPointer] = Registers[REGISTER_H];
  2655.             StackPointer--;
  2656.  
  2657.             Memory[StackPointer] = Registers[REGISTER_M];
  2658.             StackPointer--;
  2659.  
  2660.             Memory[StackPointer] = Flags;
  2661.             StackPointer--;
  2662.         }
  2663.         break;
  2664.  
  2665.  
  2666.  
  2667.         /*
  2668.         *   Opcode: RTI
  2669.         *   Addressing mode(s) : impl
  2670.         *   Description: Pops: General purpose registers (in order), Status register, ProgramCounter, Accumulator
  2671.         *   Flags: - - - - - - - -
  2672.         */
  2673.  
  2674.     case 0x86: //RTI (impl)
  2675.         if (0 <= StackPointer < MEMORY_SIZE) {
  2676.             StackPointer++;
  2677.             Flags = Memory[StackPointer];
  2678.  
  2679.             StackPointer++;
  2680.             Registers[REGISTER_M] = Memory[StackPointer];
  2681.  
  2682.             StackPointer++;
  2683.             Registers[REGISTER_H] = Memory[StackPointer];
  2684.  
  2685.             StackPointer++;
  2686.             Registers[REGISTER_L] = Memory[StackPointer];
  2687.  
  2688.             StackPointer++;
  2689.             Registers[REGISTER_E] = Memory[StackPointer];
  2690.  
  2691.             StackPointer++;
  2692.             Registers[REGISTER_D] = Memory[StackPointer];
  2693.  
  2694.             StackPointer++;
  2695.             Registers[REGISTER_C] = Memory[StackPointer];
  2696.  
  2697.             StackPointer++;
  2698.             Registers[REGISTER_B] = Memory[StackPointer];
  2699.  
  2700.             StackPointer++;
  2701.             Registers[REGISTER_A] = Memory[StackPointer];
  2702.         }
  2703.         break;
  2704.  
  2705.  
  2706.         \
  2707.         /*
  2708.         *   Opcode: ADI
  2709.         *   Addressing mode(s) : #
  2710.         *   Description: Data added to Accumulator with Carry
  2711.         *   Flags: - - - T T T - - T
  2712.         */
  2713.  
  2714.     case 0x25: //ADI (#)
  2715.         data = fetch();
  2716.  
  2717.         temp_word = (WORD)data + (WORD)Registers[REGISTER_A];
  2718.  
  2719.         if ((Flags & FLAG_C) != 0) {
  2720.             temp_word++;
  2721.         }
  2722.  
  2723.         if (temp_word >= 0x100) {
  2724.             Flags = Flags | FLAG_C; //Set carry flag
  2725.         }
  2726.         else {
  2727.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2728.         }
  2729.  
  2730.         set_flag_z((WORD)temp_word);
  2731.         set_flag_n((WORD)temp_word);
  2732.         set_flag_v((BYTE)data, REGISTER_A, (BYTE)temp_word);
  2733.         data = (BYTE)temp_word;
  2734.         break;
  2735.  
  2736.  
  2737.  
  2738.         /*
  2739.         *   Opcode: SBI
  2740.         *   Addressing mode(s) : #
  2741.         *   Description: Data subtracted to Accumulator with Carry
  2742.         *   Flags: - - - T T T - - T
  2743.         */
  2744.  
  2745.     case 0x26: //SBI (#)
  2746.         data = fetch();
  2747.  
  2748.         temp_word = (WORD)data - (WORD)Registers[REGISTER_A];
  2749.  
  2750.         if ((Flags & FLAG_C) != 0) {
  2751.             temp_word--;
  2752.         }
  2753.  
  2754.         if (temp_word >= 0x100) {
  2755.             Flags = Flags | FLAG_C; //Set carry flag
  2756.         }
  2757.         else {
  2758.             Flags = Flags & (0xFF - FLAG_C); //Clear carry flag
  2759.         }
  2760.  
  2761.         set_flag_z((WORD)temp_word);
  2762.         set_flag_n((WORD)temp_word);
  2763.         set_flag_v((BYTE)data, -REGISTER_A, (BYTE)temp_word);
  2764.         data = (BYTE)temp_word;
  2765.  
  2766.  
  2767.  
  2768.         /*
  2769.         *   Opcode: CPI
  2770.         *   Addressing mode(s) : #
  2771.         *   Description: Data compared to Accumulator
  2772.         *   Flags: - - - T T T - - T
  2773.         */
  2774.  
  2775.     case 0x27: //CPI (#)
  2776.         param1 = Registers[REGISTER_A];
  2777.         param2 = fetch();
  2778.         temp_word = (WORD)param1 - (WORD)param2;
  2779.         if (temp_word >= 0x100) {
  2780.             Flags = Flags | FLAG_C;
  2781.         }
  2782.         else {
  2783.             Flags = Flags & (0xFF - FLAG_C);
  2784.         }
  2785.         set_flag_n((BYTE)temp_word);
  2786.         set_flag_z((BYTE)temp_word);
  2787.         set_flag_v(param1, -param2, (BYTE)temp_word);
  2788.         break;
  2789.  
  2790.  
  2791.  
  2792.         /*
  2793.         *   Opcode: ANI
  2794.         *   Addressing mode(s) : #
  2795.         *   Description: Data added to Accumulator with Carry
  2796.         *   Flags: - - - T T T - - T
  2797.         */
  2798.  
  2799.     case 0x28: //ANI (#)
  2800.         Registers[REGISTER_A] = Registers[REGISTER_A] & fetch();
  2801.         set_flag_n(Registers[REGISTER_A]);
  2802.         set_flag_z(Registers[REGISTER_A]);
  2803.         break;
  2804.  
  2805.  
  2806.  
  2807.         /*
  2808.         *   Opcode: XRI
  2809.         *   Addressing mode(s) : #
  2810.         *   Description: Data bitwise and with Accumulator
  2811.         *   Flags: - - T - T - - -
  2812.         */
  2813.  
  2814.     case 0x29: //XRI (#)
  2815.         Registers[REGISTER_A] = Registers[REGISTER_A] ^ fetch();
  2816.         set_flag_n(Registers[REGISTER_A]);
  2817.         set_flag_z(Registers[REGISTER_A]);
  2818.         break;
  2819.  
  2820.  
  2821.  
  2822.         /*
  2823.         *   Opcode: NOP
  2824.         *   Addressing mode(s) : impl
  2825.         *   Description: No operation
  2826.         *   Flags: - - - - - - - -
  2827.         */
  2828.  
  2829.     case 0x1D: // NOP (impl)
  2830.         break;
  2831.  
  2832.  
  2833.  
  2834.         /*
  2835.         *   Opcode: WAI
  2836.         *   Addressing mode(s) : impl
  2837.         *   Description: Wait for interrupt
  2838.         *   Flags: - - - - - - - -
  2839.         */
  2840.  
  2841.     case 0x1E: // WAI (impl)
  2842.         halt = true;
  2843.         break;
  2844.  
  2845.  
  2846.         //===============================  ROTATE  ===============================//
  2847.  
  2848.  
  2849.         /*
  2850.         *   Opcode: RCL
  2851.         *   Addressing mode(s) : abs, abs X
  2852.         *   Description: Rotate left through carry Memory or Accumulator
  2853.         *   Flags: - - T - T - - T
  2854.         */
  2855.  
  2856.     case 0x47: // RCL (abs)
  2857.         HB = fetch();
  2858.         LB = fetch();
  2859.         address += (WORD)((WORD)HB << 8) + LB;
  2860.  
  2861.         saved_flags = Flags;
  2862.  
  2863.         if ((Memory[address] & 0x80) == 0x80) {
  2864.             Flags = Flags | FLAG_C;
  2865.         }
  2866.         else {
  2867.             Flags = Flags & (0xFF - FLAG_C);
  2868.         }
  2869.  
  2870.         Memory[address] = (Memory[address] << 1) & 0xFE;
  2871.  
  2872.         if ((saved_flags & FLAG_C) == FLAG_C) {
  2873.             Memory[address] = Memory[address] | 0x01;
  2874.         }
  2875.  
  2876.         set_flag_n(Memory[address]);
  2877.         set_flag_z(Memory[address]);
  2878.         break;
  2879.  
  2880.     case 0x57: //RCL (abs, X)
  2881.         address += IndexRegister;
  2882.         HB = fetch();
  2883.         LB = fetch();
  2884.         address += (WORD)((WORD)HB << 8) + LB;
  2885.  
  2886.         saved_flags = Flags;
  2887.  
  2888.         if ((Memory[address] & 0x80) == 0x80) {
  2889.             Flags = Flags | FLAG_C;
  2890.         }
  2891.         else {
  2892.             Flags = Flags & (0xFF - FLAG_C);
  2893.         }
  2894.  
  2895.         Memory[address] = (Memory[address] << 1) & 0xFE;
  2896.  
  2897.         if ((saved_flags & FLAG_C) == FLAG_C) {
  2898.             Memory[address] = Memory[address] | 0x01;
  2899.         }
  2900.  
  2901.         set_flag_n(Memory[address]);
  2902.         set_flag_z(Memory[address]);
  2903.         break;
  2904.  
  2905.  
  2906.  
  2907.         /*
  2908.             *   Opcode: RCLA
  2909.             *   Description: Rotate left through carry Memory or Accumulator
  2910.             *   Flags: - - T - T - - T
  2911.             */
  2912.  
  2913.     case 0x67: // RCLA (A)
  2914.         saved_flags = Flags;
  2915.  
  2916.         if ((Registers[REGISTER_A] & 0x80) == 0x80) {
  2917.             Flags = Flags | FLAG_C;
  2918.         }
  2919.         else {
  2920.             Flags = Flags & (0xFF - FLAG_C);
  2921.         }
  2922.  
  2923.         Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) & 0xFE;
  2924.  
  2925.         if ((saved_flags & FLAG_C) == FLAG_C) {
  2926.             Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
  2927.         }
  2928.  
  2929.         set_flag_n(Registers[REGISTER_A]);
  2930.         set_flag_z(Registers[REGISTER_A]);
  2931.         break;
  2932.  
  2933.  
  2934.  
  2935.         /*
  2936.         *   Opcode: RCR
  2937.         *   Addressing mode(s) : abs, abs X
  2938.         *   Description: Rotate right through carry Memory or Accumulator
  2939.         *   Flags: - - - - - - - -
  2940.         */
  2941.  
  2942.     case 0x46: // RCR (abs)
  2943.         HB = fetch();
  2944.         LB = fetch();
  2945.         address += (WORD)((WORD)HB << 8) + LB;
  2946.  
  2947.         saved_flags = Flags;
  2948.  
  2949.         if ((Memory[address] & 0x80) == 0x80) {
  2950.             Flags = Flags | FLAG_C;
  2951.         }
  2952.         else {
  2953.             Flags = Flags & (0xFF - FLAG_C);
  2954.         }
  2955.  
  2956.         Memory[address] = (Memory[address] >> 1) & 0xFE;
  2957.  
  2958.         if ((saved_flags & FLAG_C) == FLAG_C) {
  2959.             Memory[address] = Memory[address] | 0x01;
  2960.         }
  2961.  
  2962.         set_flag_n(Memory[address]);
  2963.         set_flag_z(Memory[address]);
  2964.         break;
  2965.  
  2966.     case 0x56: // RCR (abs, X)
  2967.         address += IndexRegister;
  2968.         HB = fetch();
  2969.         LB = fetch();
  2970.         address += (WORD)((WORD)HB << 8) + LB;
  2971.  
  2972.         saved_flags = Flags;
  2973.  
  2974.         if ((Memory[address] & 0x80) == 0x80) {
  2975.             Flags = Flags | FLAG_C;
  2976.         }
  2977.         else {
  2978.             Flags = Flags & (0xFF - FLAG_C);
  2979.         }
  2980.  
  2981.         Memory[address] = (Memory[address] >> 1) & 0xFE;
  2982.  
  2983.         if ((saved_flags & FLAG_C) == FLAG_C) {
  2984.             Memory[address] = Memory[address] | 0x01;
  2985.         }
  2986.  
  2987.         set_flag_n(Memory[address]);
  2988.         set_flag_z(Memory[address]);
  2989.         break;
  2990.  
  2991.  
  2992.  
  2993.         /*
  2994.         *   Opcode: RCRA
  2995.         *   Description: Rotate right through carry Memory or Accumulator
  2996.         *   Flags: - - T - T - - T
  2997.         */
  2998.  
  2999.     case 0x66: // RCRA (A)
  3000.         saved_flags = Flags;
  3001.  
  3002.         if ((Registers[REGISTER_A] & 0x80) == 0x80) {
  3003.             Flags = Flags | FLAG_C;
  3004.         }
  3005.         else {
  3006.             Flags = Flags & (0xFF - FLAG_C);
  3007.         }
  3008.  
  3009.         Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) & 0xFE;
  3010.  
  3011.         if ((saved_flags & FLAG_C) == FLAG_C) {
  3012.             Registers[REGISTER_A] = Registers[REGISTER_A] | 0x01;
  3013.         }
  3014.  
  3015.         set_flag_n(Registers[REGISTER_A]);
  3016.         set_flag_z(Registers[REGISTER_A]);
  3017.         break;
  3018.  
  3019.  
  3020.  
  3021.         /*
  3022.         *   Opcode: ROL
  3023.         *   Addressing mode(s) : abs, abs X
  3024.         *   Description: Rotate right without carry Memory or Accumulator
  3025.         *   Flags: - - T - T - - -
  3026.         */
  3027.  
  3028.     case 0x4B: // ROL (abs)
  3029.         HB = fetch();
  3030.         LB = fetch();
  3031.         address += (WORD)((WORD)HB << 8) + LB;
  3032.  
  3033.         if (0 <= address < MEMORY_SIZE) {
  3034.             if ((Memory[address] & 0x80) == 0x80)
  3035.             {
  3036.                 Memory[address] = (Memory[address] << 1) + 0x01;
  3037.             }
  3038.             else {
  3039.                 Memory[address] = (Memory[address] << 1);
  3040.             }
  3041.         }
  3042.  
  3043.         set_flag_z((BYTE)Memory[address]);
  3044.         set_flag_n((BYTE)Memory[address]);
  3045.         Memory[address] = Memory[address];
  3046.         break;
  3047.  
  3048.  
  3049.     case 0x5B: // ROL (abs, x)
  3050.         address += IndexRegister;
  3051.         HB = fetch();
  3052.         LB = fetch();
  3053.         address += (WORD)((WORD)HB << 8) + LB;
  3054.  
  3055.         if (0 <= address < MEMORY_SIZE)
  3056.         {
  3057.  
  3058.             if ((Memory[address] & 0x80) == 0x80) {
  3059.                 Memory[address] = (Memory[address] << 1) + 0x01;
  3060.             }
  3061.             else {
  3062.                 Memory[address] = (Memory[address] << 1);
  3063.             }
  3064.         }
  3065.  
  3066.         set_flag_z((BYTE)Memory[address]);
  3067.         set_flag_n((BYTE)Memory[address]);
  3068.         Memory[address] = Memory[address];
  3069.         break;
  3070.  
  3071.         /*
  3072.         *   Opcode: ROLA
  3073.         *   Description: Rotate left without carry Memory or Accumulator
  3074.         *   Flags: - - T - T - - -
  3075.         */
  3076.  
  3077.     case 0x6B: // ROLA (A)
  3078.         if ((Registers[REGISTER_A] & 0x80) == 0x80) {
  3079.             Registers[REGISTER_A] = (Registers[REGISTER_A] << 1) + 0x01;
  3080.         }
  3081.         else {
  3082.             Registers[REGISTER_A] = (Registers[REGISTER_A] << 1);
  3083.         }
  3084.  
  3085.         set_flag_n((BYTE)Registers[REGISTER_A]);
  3086.         set_flag_z((BYTE)Registers[REGISTER_A]);
  3087.         Registers[REGISTER_A] = (BYTE)Registers[REGISTER_A];
  3088.         break;
  3089.  
  3090.  
  3091.  
  3092.         /*
  3093.         *   Opcode: ROR
  3094.         *   Addressing mode(s) : abs, abs X
  3095.         *   Description: Rotate right without carry Memory or Accumulator
  3096.         *   Flags: - - T - T - - -
  3097.         */
  3098.  
  3099.     case 0x4C: // ROR (abs)
  3100.         HB = fetch();
  3101.         LB = fetch();
  3102.         address += (WORD)((WORD)HB << 8) + LB;
  3103.  
  3104.         if (0 <= address < MEMORY_SIZE)
  3105.         {
  3106.             if ((Memory[address] & 0x80) == 0x80)
  3107.             {
  3108.                 Memory[address] = (Memory[address] >> 1) + 0x01;
  3109.             }
  3110.             else {
  3111.                 Memory[address] = (Memory[address] >> 1);
  3112.             }
  3113.         }
  3114.         set_flag_z((BYTE)Memory[address]);
  3115.         set_flag_n((BYTE)Memory[address]);
  3116.         Memory[address] = Memory[address];
  3117.  
  3118.         break;
  3119.  
  3120.     case 0x5C: // ROR (abs, x)
  3121.         address += IndexRegister;
  3122.         HB = fetch();
  3123.         LB = fetch();
  3124.         address += (WORD)((WORD)HB << 8) + LB;
  3125.  
  3126.         if (0 <= address < MEMORY_SIZE)
  3127.         {
  3128.             if ((Memory[address] & 0x80) == 0x80)
  3129.             {
  3130.                 Memory[address] = (Memory[address] >> 1) + 0x01;
  3131.             }
  3132.             else {
  3133.                 Memory[address] = (Memory[address] >> 1);
  3134.             }
  3135.         }
  3136.         set_flag_z((BYTE)Memory[address]);
  3137.         set_flag_n((BYTE)Memory[address]);
  3138.         Memory[address] = Memory[address];
  3139.  
  3140.         break;
  3141.  
  3142.  
  3143.  
  3144.         /*
  3145.         *   Opcode: RORA
  3146.         *   Description: Rotate right through carry Memory or Accumulator
  3147.         *   Flags: - - T - T - - -
  3148.         */
  3149.  
  3150.     case 0x6C: // RORA (A)
  3151.         if ((Registers[REGISTER_A] & 0x80) == 0x80) {
  3152.             Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1) + 0x01;
  3153.         }
  3154.         else {
  3155.             Registers[REGISTER_A] = (Registers[REGISTER_A] >> 1);
  3156.         }
  3157.  
  3158.         set_flag_n((BYTE)Registers[REGISTER_A]);
  3159.         set_flag_z((BYTE)Registers[REGISTER_A]);
  3160.         Registers[REGISTER_A] = (BYTE)Registers[REGISTER_A];
  3161.         break;
  3162.     }
  3163. }
  3164.  
  3165.     //==================================  GROUP 2 ==================================//
  3166.  
  3167. void Group_2_Move(BYTE opcode) {
  3168.     WORD address = 0;
  3169.  
  3170.     BYTE source = opcode >> 4;
  3171.     BYTE dest = opcode & 0x0F;
  3172.     int destReg = 0;
  3173.     int sourceReg = 0;
  3174.  
  3175.  
  3176.     //==================================  MOVE DEST  ==================================//
  3177.  
  3178.  
  3179.         /*
  3180.         *   Opcode: MOVE
  3181.         *   Description: Transfer from one register to another
  3182.         *   Flags: - - - - - - - -
  3183.         */
  3184.  
  3185.  
  3186.     switch (dest) {
  3187.     case 0x08:
  3188.         destReg = REGISTER_A;
  3189.         break;
  3190.  
  3191.     case 0x09:
  3192.         destReg = REGISTER_B;
  3193.         break;
  3194.  
  3195.     case 0x0A:
  3196.         destReg = REGISTER_C;
  3197.         break;
  3198.  
  3199.     case 0x0B:
  3200.         destReg = REGISTER_D;
  3201.         break;
  3202.  
  3203.     case 0x0C:
  3204.         destReg = REGISTER_E;
  3205.         break;
  3206.  
  3207.     case 0x0D:
  3208.         destReg = REGISTER_L;
  3209.         break;
  3210.  
  3211.     case 0x0E:
  3212.         destReg = REGISTER_H;
  3213.         break;
  3214.  
  3215.     case 0x0F:
  3216.         destReg = REGISTER_M;
  3217.         break;
  3218.     }
  3219.  
  3220.  
  3221.     //==================================  MOVE SOURCE  ==================================//
  3222.  
  3223.  
  3224.     switch (source) {
  3225.     case 0x07:
  3226.         sourceReg = REGISTER_A;
  3227.         break;
  3228.  
  3229.     case 0x08:
  3230.         sourceReg = REGISTER_B;
  3231.         break;
  3232.  
  3233.     case 0x09:
  3234.         sourceReg = REGISTER_C;
  3235.         break;
  3236.  
  3237.     case 0x0A:
  3238.         sourceReg = REGISTER_D;
  3239.         break;
  3240.  
  3241.     case 0x0B:
  3242.         sourceReg = REGISTER_E;
  3243.         break;
  3244.  
  3245.     case 0x0C:
  3246.         sourceReg = REGISTER_L;
  3247.         break;
  3248.  
  3249.     case 0x0D:
  3250.         sourceReg = REGISTER_H;
  3251.         break;
  3252.  
  3253.     case 0x0E:
  3254.         sourceReg = REGISTER_M;
  3255.         break;
  3256.     }
  3257.  
  3258.     if (sourceReg == REGISTER_M) {
  3259.         address = Registers[REGISTER_L];
  3260.         address += (WORD)Registers[REGISTER_H] << 8;
  3261.         Registers[destReg] = Memory[address];
  3262.     }
  3263.     Registers[destReg] = Registers[sourceReg];
  3264.  
  3265.     if (destReg == REGISTER_M) {
  3266.         address = Registers[REGISTER_L];
  3267.         address += (WORD)Registers[REGISTER_H] << 8;
  3268.         Memory[address] = Registers[REGISTER_M];
  3269.     }
  3270. }
  3271.  
  3272. void execute(BYTE opcode) {
  3273.     if (((opcode >= 0x78) && (opcode <= 0x7F)) ||
  3274.         ((opcode >= 0x88) && (opcode <= 0x8F)) ||
  3275.         ((opcode >= 0x98) && (opcode <= 0x9F)) ||
  3276.         ((opcode >= 0xA8) && (opcode <= 0xAF)) ||
  3277.         ((opcode >= 0xB8) && (opcode <= 0xBF)) ||
  3278.         ((opcode >= 0xC8) && (opcode <= 0xCF)) ||
  3279.         ((opcode >= 0xD8) && (opcode <= 0xDF)) ||
  3280.         ((opcode >= 0xE8) && (opcode <= 0xEF))) {
  3281.         Group_2_Move(opcode);
  3282.     }
  3283.     else {
  3284.         Group_1(opcode);
  3285.     }
  3286. }
  3287.  
  3288. void emulate() {
  3289.     BYTE opcode;
  3290.  
  3291.     ProgramCounter = 0;
  3292.     halt = false;
  3293.     memory_in_range = true;
  3294.  
  3295.     int sanity = 0;
  3296.  
  3297.     printf("                    A  B  C  D  E  L  H  X    SP\n");
  3298.  
  3299.     while ((!halt) && (memory_in_range)) {
  3300.         printf("%04X ", ProgramCounter); // Print current address
  3301.         opcode = fetch();
  3302.         execute(opcode);
  3303.  
  3304.         sanity++;
  3305.         if (sanity > 500) halt = true;
  3306.  
  3307.         printf("%s  ", opcode_mneumonics[opcode]); // Print current opcode
  3308.  
  3309.         printf("%02X ", Registers[REGISTER_A]);
  3310.         printf("%02X ", Registers[REGISTER_B]);
  3311.         printf("%02X ", Registers[REGISTER_C]);
  3312.         printf("%02X ", Registers[REGISTER_D]);
  3313.         printf("%02X ", Registers[REGISTER_E]);
  3314.         printf("%02X ", Registers[REGISTER_L]);
  3315.         printf("%02X ", Registers[REGISTER_H]);
  3316.         printf("%04X ", IndexRegister);
  3317.         printf("%04X ", StackPointer); // Print Stack Pointer
  3318.  
  3319.         if ((Flags & FLAG_I) == FLAG_I) {
  3320.             printf("I=1 ");
  3321.         }
  3322.         else {
  3323.             printf("I=0 ");
  3324.         }
  3325.         if ((Flags & FLAG_N) == FLAG_N) {
  3326.             printf("N=1 ");
  3327.         }
  3328.         else {
  3329.             printf("N=0 ");
  3330.         }
  3331.         if ((Flags & FLAG_V) == FLAG_V) {
  3332.             printf("V=1 ");
  3333.         }
  3334.         else {
  3335.             printf("V=0 ");
  3336.         }
  3337.         if ((Flags & FLAG_Z) == FLAG_Z) {
  3338.             printf("Z=1 ");
  3339.         }
  3340.         else {
  3341.             printf("Z=0 ");
  3342.         }
  3343.         if ((Flags & FLAG_C) == FLAG_C) {
  3344.             printf("C=1 ");
  3345.         }
  3346.         else {
  3347.             printf("C=0 ");
  3348.         }
  3349.  
  3350.         printf("\n"); // New line
  3351.     }
  3352.  
  3353.     printf("\n"); // New line
  3354. }
  3355.  
  3356.  
  3357. ////////////////////////////////////////////////////////////////////////////////
  3358. //                            Simulator/Emulator (End)                        //
  3359. ////////////////////////////////////////////////////////////////////////////////
  3360.  
  3361.  
  3362. void initialise_filenames() {
  3363.     int i;
  3364.  
  3365.     for (i = 0; i < MAX_FILENAME_SIZE; i++) {
  3366.         hex_file[i] = '\0';
  3367.         trc_file[i] = '\0';
  3368.     }
  3369. }
  3370.  
  3371.  
  3372.  
  3373.  
  3374. int find_dot_position(char* filename) {
  3375.     int  dot_position;
  3376.     int  i;
  3377.     char chr;
  3378.  
  3379.     dot_position = 0;
  3380.     i = 0;
  3381.     chr = filename[i];
  3382.  
  3383.     while (chr != '\0') {
  3384.         if (chr == '.') {
  3385.             dot_position = i;
  3386.         }
  3387.         i++;
  3388.         chr = filename[i];
  3389.     }
  3390.  
  3391.     return (dot_position);
  3392. }
  3393.  
  3394.  
  3395. int find_end_position(char* filename) {
  3396.     int  end_position;
  3397.     int  i;
  3398.     char chr;
  3399.  
  3400.     end_position = 0;
  3401.     i = 0;
  3402.     chr = filename[i];
  3403.  
  3404.     while (chr != '\0') {
  3405.         end_position = i;
  3406.         i++;
  3407.         chr = filename[i];
  3408.     }
  3409.  
  3410.     return (end_position);
  3411. }
  3412.  
  3413.  
  3414. bool file_exists(char* filename) {
  3415.     bool exists;
  3416.     FILE* ifp;
  3417.  
  3418.     exists = false;
  3419.  
  3420.     if ((ifp = fopen(filename, "r")) != NULL) {
  3421.         exists = true;
  3422.  
  3423.         fclose(ifp);
  3424.     }
  3425.  
  3426.     return (exists);
  3427. }
  3428.  
  3429.  
  3430.  
  3431. void create_file(char* filename) {
  3432.     FILE* ofp;
  3433.  
  3434.     if ((ofp = fopen(filename, "w")) != NULL) {
  3435.         fclose(ofp);
  3436.     }
  3437. }
  3438.  
  3439.  
  3440.  
  3441. bool getline(FILE* fp, char* buffer) {
  3442.     bool rc;
  3443.     bool collect;
  3444.     char c;
  3445.     int  i;
  3446.  
  3447.     rc = false;
  3448.     collect = true;
  3449.  
  3450.     i = 0;
  3451.     while (collect) {
  3452.         c = getc(fp);
  3453.  
  3454.         switch (c) {
  3455.         case EOF:
  3456.             if (i > 0) {
  3457.                 rc = true;
  3458.             }
  3459.             collect = false;
  3460.             break;
  3461.  
  3462.         case '\n':
  3463.             if (i > 0) {
  3464.                 rc = true;
  3465.                 collect = false;
  3466.                 buffer[i] = '\0';
  3467.             }
  3468.             break;
  3469.  
  3470.         default:
  3471.             buffer[i] = c;
  3472.             i++;
  3473.             break;
  3474.         }
  3475.     }
  3476.  
  3477.     return (rc);
  3478. }
  3479.  
  3480.  
  3481.  
  3482.  
  3483.  
  3484.  
  3485. void load_and_run(int args, _TCHAR** argv) {
  3486.     char chr;
  3487.     int  ln;
  3488.     int  dot_position;
  3489.     int  end_position;
  3490.     long i;
  3491.     FILE* ifp;
  3492.     long address;
  3493.     long load_at;
  3494.     int  code;
  3495.  
  3496.     // Prompt for the .hex file
  3497.  
  3498.     printf("\n");
  3499.     printf("Enter the hex filename (.hex): ");
  3500.  
  3501.     if (args == 2) {
  3502.         ln = 0;
  3503.         chr = argv[1][ln];
  3504.         while (chr != '\0')
  3505.         {
  3506.             if (ln < MAX_FILENAME_SIZE)
  3507.             {
  3508.                 hex_file[ln] = chr;
  3509.                 trc_file[ln] = chr;
  3510.                 ln++;
  3511.             }
  3512.             chr = argv[1][ln];
  3513.         }
  3514.     }
  3515.     else {
  3516.         ln = 0;
  3517.         chr = '\0';
  3518.         while (chr != '\n') {
  3519.             chr = getchar();
  3520.  
  3521.             switch (chr) {
  3522.             case '\n':
  3523.                 break;
  3524.             default:
  3525.                 if (ln < MAX_FILENAME_SIZE) {
  3526.                     hex_file[ln] = chr;
  3527.                     trc_file[ln] = chr;
  3528.                     ln++;
  3529.                 }
  3530.                 break;
  3531.             }
  3532.         }
  3533.  
  3534.     }
  3535.     // Tidy up the file names
  3536.  
  3537.     dot_position = find_dot_position(hex_file);
  3538.     if (dot_position == 0) {
  3539.         end_position = find_end_position(hex_file);
  3540.  
  3541.         hex_file[end_position + 1] = '.';
  3542.         hex_file[end_position + 2] = 'h';
  3543.         hex_file[end_position + 3] = 'e';
  3544.         hex_file[end_position + 4] = 'x';
  3545.         hex_file[end_position + 5] = '\0';
  3546.     }
  3547.     else {
  3548.         hex_file[dot_position + 0] = '.';
  3549.         hex_file[dot_position + 1] = 'h';
  3550.         hex_file[dot_position + 2] = 'e';
  3551.         hex_file[dot_position + 3] = 'x';
  3552.         hex_file[dot_position + 4] = '\0';
  3553.     }
  3554.  
  3555.     dot_position = find_dot_position(trc_file);
  3556.     if (dot_position == 0) {
  3557.         end_position = find_end_position(trc_file);
  3558.  
  3559.         trc_file[end_position + 1] = '.';
  3560.         trc_file[end_position + 2] = 't';
  3561.         trc_file[end_position + 3] = 'r';
  3562.         trc_file[end_position + 4] = 'c';
  3563.         trc_file[end_position + 5] = '\0';
  3564.     }
  3565.     else {
  3566.         trc_file[dot_position + 0] = '.';
  3567.         trc_file[dot_position + 1] = 't';
  3568.         trc_file[dot_position + 2] = 'r';
  3569.         trc_file[dot_position + 3] = 'c';
  3570.         trc_file[dot_position + 4] = '\0';
  3571.     }
  3572.  
  3573.     if (file_exists(hex_file)) {
  3574.         // Clear Registers and Memory
  3575.  
  3576.         Registers[REGISTER_A] = 0;
  3577.         Registers[REGISTER_B] = 0;
  3578.         Registers[REGISTER_C] = 0;
  3579.         Registers[REGISTER_D] = 0;
  3580.         Registers[REGISTER_E] = 0;
  3581.         Registers[REGISTER_L] = 0;
  3582.         Registers[REGISTER_H] = 0;
  3583.         IndexRegister = 0;
  3584.         Flags = 0;
  3585.         ProgramCounter = 0;
  3586.         StackPointer = 0;
  3587.  
  3588.         for (i = 0; i < MEMORY_SIZE; i++) {
  3589.             Memory[i] = 0x00;
  3590.         }
  3591.  
  3592.         // Load hex file
  3593.  
  3594.         if ((ifp = fopen(hex_file, "r")) != NULL) {
  3595.             printf("Loading file...\n\n");
  3596.  
  3597.             load_at = 0;
  3598.  
  3599.             while (getline(ifp, InputBuffer)) {
  3600.                 if (sscanf(InputBuffer, "L=%x", &address) == 1) {
  3601.                     load_at = address;
  3602.                 }
  3603.                 else if (sscanf(InputBuffer, "%x", &code) == 1) {
  3604.                     if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
  3605.                         Memory[load_at] = (BYTE)code;
  3606.                     }
  3607.                     load_at++;
  3608.                 }
  3609.                 else {
  3610.                     printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
  3611.                 }
  3612.             }
  3613.  
  3614.             fclose(ifp);
  3615.         }
  3616.  
  3617.         // Emulate
  3618.  
  3619.         emulate();
  3620.     }
  3621.     else {
  3622.         printf("\n");
  3623.         printf("ERROR> Input file %s does not exist!\n", hex_file);
  3624.         printf("\n");
  3625.     }
  3626. }
  3627.  
  3628. void building(int args, _TCHAR** argv) {
  3629.     char buffer[1024];
  3630.     load_and_run(args, argv);
  3631.     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",
  3632.         Memory[TEST_ADDRESS_1],
  3633.         Memory[TEST_ADDRESS_2],
  3634.         Memory[TEST_ADDRESS_3],
  3635.         Memory[TEST_ADDRESS_4],
  3636.         Memory[TEST_ADDRESS_5],
  3637.         Memory[TEST_ADDRESS_6],
  3638.         Memory[TEST_ADDRESS_7],
  3639.         Memory[TEST_ADDRESS_8],
  3640.         Memory[TEST_ADDRESS_9],
  3641.         Memory[TEST_ADDRESS_10],
  3642.         Memory[TEST_ADDRESS_11],
  3643.         Memory[TEST_ADDRESS_12]
  3644.     );
  3645.     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
  3646. }
  3647.  
  3648.  
  3649.  
  3650. void test_and_mark() {
  3651.     char buffer[1024];
  3652.     bool testing_complete;
  3653.     int  len = sizeof(SOCKADDR);
  3654.     char chr;
  3655.     int  i;
  3656.     int  j;
  3657.     bool end_of_program;
  3658.     long address;
  3659.     long load_at;
  3660.     int  code;
  3661.     int  mark;
  3662.     int  passed;
  3663.  
  3664.     printf("\n");
  3665.     printf("Automatic Testing and Marking\n");
  3666.     printf("\n");
  3667.  
  3668.     testing_complete = false;
  3669.  
  3670.     sprintf(buffer, "Test Student %s", STUDENT_NUMBER);
  3671.     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
  3672.  
  3673.     while (!testing_complete) {
  3674.         memset(buffer, '\0', sizeof(buffer));
  3675.  
  3676.         if (recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (SOCKADDR*)&client_addr, &len) != SOCKET_ERROR) {
  3677.             printf("Incoming Data: %s \n", buffer);
  3678.  
  3679.             //if (strcmp(buffer, "Testing complete") == 1)
  3680.             if (sscanf(buffer, "Testing complete %d", &mark) == 1) {
  3681.                 testing_complete = true;
  3682.                 printf("Current mark = %d\n", mark);
  3683.  
  3684.             }
  3685.             else if (sscanf(buffer, "Tests passed %d", &passed) == 1) {
  3686.                 //testing_complete = true;
  3687.                 printf("Passed = %d\n", passed);
  3688.  
  3689.             }
  3690.             else if (strcmp(buffer, "Error") == 0) {
  3691.                 printf("ERROR> Testing abnormally terminated\n");
  3692.                 testing_complete = true;
  3693.             }
  3694.             else {
  3695.                 // Clear Registers and Memory
  3696.  
  3697.                 Registers[REGISTER_A] = 0;
  3698.                 Registers[REGISTER_B] = 0;
  3699.                 Registers[REGISTER_C] = 0;
  3700.                 Registers[REGISTER_D] = 0;
  3701.                 Registers[REGISTER_E] = 0;
  3702.                 Registers[REGISTER_L] = 0;
  3703.                 Registers[REGISTER_H] = 0;
  3704.                 IndexRegister = 0;
  3705.                 Flags = 0;
  3706.                 ProgramCounter = 0;
  3707.                 StackPointer = 0;
  3708.                 for (i = 0; i < MEMORY_SIZE; i++) {
  3709.                     Memory[i] = 0;
  3710.                 }
  3711.  
  3712.                 // Load hex file
  3713.  
  3714.                 i = 0;
  3715.                 j = 0;
  3716.                 load_at = 0;
  3717.                 end_of_program = false;
  3718.                 FILE* ofp;
  3719.                 fopen_s(&ofp, "branch.txt", "a");
  3720.  
  3721.                 while (!end_of_program) {
  3722.                     chr = buffer[i];
  3723.                     switch (chr) {
  3724.                     case '\0':
  3725.                         end_of_program = true;
  3726.  
  3727.                     case ',':
  3728.                         if (sscanf(InputBuffer, "L=%x", &address) == 1) {
  3729.                             load_at = address;
  3730.                         }
  3731.                         else if (sscanf(InputBuffer, "%x", &code) == 1) {
  3732.                             if ((load_at >= 0) && (load_at <= MEMORY_SIZE)) {
  3733.                                 Memory[load_at] = (BYTE)code;
  3734.                                 fprintf(ofp, "%02X\n", (BYTE)code);
  3735.                             }
  3736.                             load_at++;
  3737.                         }
  3738.                         else {
  3739.                             printf("ERROR> Failed to load instruction: %s \n", InputBuffer);
  3740.                         }
  3741.                         j = 0;
  3742.                         break;
  3743.  
  3744.                     default:
  3745.                         InputBuffer[j] = chr;
  3746.                         j++;
  3747.                         break;
  3748.                     }
  3749.                     i++;
  3750.                 }
  3751.                 fclose(ofp);
  3752.                 // Emulate
  3753.  
  3754.                 if (load_at > 1) {
  3755.                     emulate();
  3756.                     // Send and store results
  3757.                     sprintf(buffer, "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X",
  3758.                         Memory[TEST_ADDRESS_1],
  3759.                         Memory[TEST_ADDRESS_2],
  3760.                         Memory[TEST_ADDRESS_3],
  3761.                         Memory[TEST_ADDRESS_4],
  3762.                         Memory[TEST_ADDRESS_5],
  3763.                         Memory[TEST_ADDRESS_6],
  3764.                         Memory[TEST_ADDRESS_7],
  3765.                         Memory[TEST_ADDRESS_8],
  3766.                         Memory[TEST_ADDRESS_9],
  3767.                         Memory[TEST_ADDRESS_10],
  3768.                         Memory[TEST_ADDRESS_11],
  3769.                         Memory[TEST_ADDRESS_12]
  3770.                     );
  3771.                     sendto(sock, buffer, strlen(buffer), 0, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
  3772.                 }
  3773.             }
  3774.         }
  3775.     }
  3776. }
  3777.  
  3778.  
  3779.  
  3780. int _tmain(int argc, _TCHAR* argv[])
  3781. {
  3782.     char chr;
  3783.     char dummy;
  3784.  
  3785.     printf("\n");
  3786.     printf("Microprocessor Emulator\n");
  3787.     printf("UWE Computer and Network Systems Assignment 1\n");
  3788.     printf("\n");
  3789.  
  3790.     initialise_filenames();
  3791.  
  3792.     if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return(0);
  3793.  
  3794.     sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  // Here we create our socket, which will be a UDP socket (SOCK_DGRAM).
  3795.     if (!sock) {
  3796.         // Creation failed!
  3797.     }
  3798.  
  3799.     memset(&server_addr, 0, sizeof(SOCKADDR_IN));
  3800.     server_addr.sin_family = AF_INET;
  3801.     server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS_SERVER);
  3802.     server_addr.sin_port = htons(PORT_SERVER);
  3803.  
  3804.     memset(&client_addr, 0, sizeof(SOCKADDR_IN));
  3805.     client_addr.sin_family = AF_INET;
  3806.     client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  3807.     client_addr.sin_port = htons(PORT_CLIENT);
  3808.  
  3809.     chr = '\0';
  3810.     while ((chr != 'e') && (chr != 'E'))
  3811.     {
  3812.         printf("\n");
  3813.         printf("Please select option\n");
  3814.         printf("L - Load and run a hex file\n");
  3815.         printf("T - Have the server test and mark your emulator\n");
  3816.         printf("E - Exit\n");
  3817.         if (argc == 2) { building(argc, argv); exit(0); }
  3818.         printf("Enter option: ");
  3819.         chr = getchar();
  3820.         if (chr != 0x0A)
  3821.         {
  3822.             dummy = getchar();  // read in the <CR>
  3823.         }
  3824.         printf("\n");
  3825.  
  3826.         switch (chr)
  3827.         {
  3828.         case 'L':
  3829.         case 'l':
  3830.             load_and_run(argc, argv);
  3831.             break;
  3832.  
  3833.         case 'T':
  3834.         case 't':
  3835.             test_and_mark();
  3836.             break;
  3837.  
  3838.         default:
  3839.             break;
  3840.         }
  3841.     }
  3842.  
  3843.     closesocket(sock);
  3844.     WSACleanup();
  3845.  
  3846.  
  3847.     return 0;
  3848. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement