Advertisement
Guest User

Untitled

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