Advertisement
Guest User

Untitled

a guest
May 26th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.06 KB | None | 0 0
  1. public void opcodes(int opcode) {
  2.  
  3.         // these opcodes are the ones that don't need manipulation
  4.         switch (opcode) {
  5.         // clear the screen by filling the array with false
  6.         case 0x00E0:
  7.  
  8.             for (int y = 0; y <= display[y].length; y++) {
  9.                 Arrays.fill(display[y], false); // using the fill to fill each array of the 2d array with false
  10.             }
  11.             PC += 2;
  12.             break;
  13.  
  14.         // This returns the program counter from a subroutine
  15.         case 0x00EE:
  16.             // Returns from a subroutine then increments the program counter
  17.  
  18.             PC = stack[SP--];
  19.             PC += 2;
  20.             break;
  21.  
  22.         }
  23.  
  24.         // This switch performs a bitwise operation to separate the goto address from
  25.         // the action wanted to be performed
  26.         switch (opcode & 0xF000) {
  27.  
  28.         // this opcode jumps to address NNN
  29.         case 0x1000:
  30.             PC = opcode & 0x0FFF;
  31.  
  32.             break;
  33.         // this one calls a subroutine and stores the return in the stack
  34.         case 0x2000:
  35.             stack[++SP] = PC;
  36.            
  37.             PC = opcode & 0x0FFF;
  38.             break;
  39.         // If VX == NN then skip the next instruction, the opcode it 0x3XNN
  40.         case 0x3000:
  41.  
  42.             if (V[(opcode & 0x0F00) >>> 8] == (opcode & 0x00FF)) {
  43.                 PC += 4;
  44.             } else {
  45.                 PC += 2;
  46.             }
  47.             break;
  48.         // If VX != NN then skip the next instruction, the opcode is 0x3XNN
  49.         case 0x4000:
  50.  
  51.             if (V[(opcode & 0x0F00) >>> 0x0008] != (opcode & 0x00FF)) {
  52.                 PC += 4;
  53.             } else {
  54.                 PC += 2;
  55.             }
  56.             break;
  57.         // we are comparing VX and VY, if they match then skip, the opcode is 5XY0
  58.         case 0x5000:
  59.  
  60.             if (V[(opcode & 0x0F00) >>> 0x0008] == V[(opcode & 0x00F0) >>> 0x0004]) {
  61.                 PC += 4;
  62.             } else {
  63.                 PC += 2;
  64.             }
  65.             break;
  66.         // Set register VX to NN, opcode is 6XNN
  67.         case 0x6000:
  68.             V[(opcode & 0x0F00) >>> 0x0008] = (opcode & 0x00FF);
  69.  
  70.             PC += 2;
  71.             break;
  72.  
  73.         // add value NN to register VX, opcode is 7XNN
  74.         case 0x7000:
  75.             V[(opcode & 0x0F00) >>> 8] += (opcode & 0x00FF);
  76.             if ((V[(opcode & 0x0F00) >>> 8] >= 256)) {
  77.                 V[(opcode & 0x0F00) >>> 8] -= 256;
  78.             }
  79.  
  80.             PC += 2;
  81.         }
  82.         // Where the F is in the bitwise is used to determine which opcode is meant to
  83.         // be used
  84.  
  85.         switch (opcode & 0xF00F) {
  86.  
  87.         // sets VX to VY
  88.         case 0x8000:
  89.             V[(opcode & 0x0F00) >>> 0x0008] = V[(opcode & 0x00F0) >>> 4];
  90.             PC += 2;
  91.             break;
  92.  
  93.         // bitwise OR operation setting VX to VX|VY
  94.         case 0x8001:
  95.  
  96.             // the bitwise OR means any bit that is 1 in the byte will be 1 if either are 1
  97.             V[(opcode & 0x0F00) >>> 0x0008] = (V[(opcode & 0x0F00) >>> 8] | V[(opcode & 0x00F0) >>> 4]);
  98.             PC += 2;
  99.             break;
  100.         // Bitwise AND operation setting VX to VX&VY
  101.         case 0x8002:
  102.  
  103.             // the bitwise AND means any bit that is 1 in both will be 1
  104.             V[(opcode & 0x0F00) >>> 0x0008] = (V[(opcode & 0x0F00) >>> 8] & V[(opcode & 0x00F0) >>> 4]);
  105.             PC += 2;
  106.             break;
  107.         // bitwise XOR operation will only have a 1 if only one of the values has a 1
  108.         // there
  109.         case 0x8003:
  110.  
  111.             // the bitwise AND means any bit that is 1 in both will be 1
  112.             V[(opcode & 0x0F00) >>> 0x0008] = (V[(opcode & 0x0F00) >>> 8] ^ V[(opcode & 0x00F0) >>> 4]);
  113.             PC += 2;
  114.             break;
  115.  
  116.         // Adds VY to VX VF is set to 1 when there's a carry and to 0 when there isn't
  117.         case 0x8004:
  118.  
  119.             if (V[(opcode & 0x0F00) >>> 0x0008] + V[(opcode & 0x00F0) >>> 4] > 0x00FF) {
  120.                 V[0x000F] = 1;
  121.             } else {
  122.                 V[0x000F] = 0;
  123.             }
  124.  
  125.             V[(opcode & 0x0F00) >>> 0x0008] = ((V[(opcode & 0x0F00) >>> 0x0008] + V[(opcode & 0x00F0) >>> 4]) & 0x00FF);
  126.             PC += 2;
  127.  
  128.             break;
  129.         // subtract VY from VX and sets a register to 1 if borrow
  130.         case 0x8005:
  131.  
  132.             if (V[(opcode & 0x0F00) >>> 0x0008] - V[(opcode & 0x00F0) >>> 4] < 0x0000) {
  133.                 V[0x000F] = 1;
  134.             } else {
  135.                 V[0x000F] = 0;
  136.             }
  137.             PC += 2;
  138.  
  139.             break;
  140.  
  141.         // Stores the least significant bit of VX in VF and then shifts VX to the right
  142.         // by 1
  143.         case 0x8006:
  144.  
  145.             if ((V[(opcode & 0x0F00) >>> 8] & 0x0001) == 1) {
  146.                 V[0x000F] = 1;
  147.             } else {
  148.                 V[0x000F] = 0;
  149.             }
  150.             V[(opcode & 0x0F00) >>> 8] = V[(opcode & 0x0F00) >>> 8] >>> 1;
  151.  
  152.             PC += 2;
  153.             break;
  154.  
  155.         // set VX to VY minus VX and sets a register to 1 if borrow
  156.         case 0x8007:
  157.             V[(opcode & 0x0F00) >>> 0x0008] = V[(opcode & 0x00F0) >>> 4] - V[(opcode & 0x0F00) >>> 0x0008];
  158.             // have to check and account for a carry
  159.             if (V[opcode & 0x0F00 >>> 0x0008] < 0x0000) {
  160.                 V[opcode & 0x0F00 >>> 0x0008] += 0x00FF;
  161.                 V[0x000F] = 1;
  162.             } else {
  163.                 V[0x000F] = 0;
  164.             }
  165.             PC += 2;
  166.  
  167.             break;
  168.         // Stores the most significant bit of VX in VF and then shifts VX to the left by
  169.         // 1
  170.         case 0x800E:
  171.  
  172.             if ((V[(opcode & 0x0F00) >>> 8] >>> 7 & 0x0001) == 1) {
  173.                 V[0x000F] = 1;
  174.             } else {
  175.                 V[0x000F] = 0;
  176.             }
  177.             V[(opcode & 0x0F00) >>> 8] = V[(opcode & 0x0F00) >>> 8] << 1 & 0x00FF;
  178.  
  179.             PC += 2;
  180.             break;
  181.  
  182.         // skip if the two registers are not equal, VX and VY
  183.         case 0x9000:
  184.             if (V[(opcode & 0x0F00) >>> 8] != V[(opcode & 0x0F00) >>> 8]) {
  185.                 PC += 4;
  186.             } else {
  187.                 PC += 2;
  188.             }
  189.             break;
  190.         }
  191.  
  192.         switch (opcode & 0xF000) {
  193.         // set register I to address NNN, opcode ANNN
  194.         case 0xA000:
  195.             I = (opcode & 0x0FFF);
  196.             PC += 2;
  197.             break;
  198.         // Jump to address NNN plus V0
  199.         case 0xB000:
  200.             PC = V[0] + (opcode & 0x0FFF);
  201.             break;
  202.         // set VX to random value from random number with a bitwise & with NN, opcode is
  203.         // CXNN
  204.         case 0xC000:
  205.  
  206.             V[(opcode & 0x0F00) >>> 8] = ((int) (Math.random() * 0x0FF)) & (opcode & 0x0FF);
  207.  
  208.             PC += 2;
  209.             break;
  210.         // Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a
  211.         // height of N pixels. Each row of 8 pixels is read as bit-coded starting from
  212.         // memory location I; I value doesn’t change after the execution of this
  213.         // instruction. As described above, VF is set to 1 if any screen pixels are
  214.         // flipped from set to unset when the sprite is drawn, and to 0 if that doesn’t
  215.         // happen opcode DXYN
  216.  
  217.             //using someone elses code
  218.             //TODO Redo this code as original code
  219.         case 0xD000:
  220.  
  221.             // N - Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
  222.  
  223.                         V[0xF] = 0;
  224.                         for (int yLine = 0; yLine < (opcode & 0x000F); yLine++) {
  225.                             int pixel = memory[I + yLine];
  226.  
  227.                             for (int xLine = 0; xLine < 8; xLine++) {
  228.                                 // check each bit (pixel) in the 8 bit row
  229.                                 if ((pixel & (0x80 >> xLine)) != 0) {
  230.  
  231.                                     // wrap pixels if they're drawn off screen
  232.                                     int xCoord = V[(opcode & 0x0F00) >> 8]+xLine;
  233.                                     int yCoord = V[(opcode & 0x00F0) >> 4]+yLine;
  234.                                    
  235.                                     if (xCoord < 64 && yCoord < 32) {
  236.                                         // if pixel already exists, set carry (collision)
  237.                                         if (display[xCoord] [yCoord] == true) {
  238.                                             V[0xF] = 1;
  239.                                         }
  240.                                         // draw via xor
  241.                                         display[xCoord][yCoord]^= true;
  242.                                                
  243.  
  244.                                        
  245.                                     }
  246.                                 }
  247.                             }
  248.                         }
  249.        
  250.             PC += 2;
  251.             break;
  252.         }
  253.         switch (opcode & 0xF0FF) {
  254.         case 0xE09E:
  255.             // EX9E - Skip next instruction if key with the value of Vx is pressed.
  256.             // TODO Implement
  257.             PC += 2;
  258.  
  259.             break;
  260.         case 0xE0A1:
  261.             // EXA1 - Skip next instruction if key with the value of Vx is not pressed.
  262.             PC += 4;
  263.             break;
  264.  
  265.         case 0xF007:
  266.             V[((opcode & 0x0F00) >>> 8)] = (delayTimer);
  267.  
  268.             PC += 2;
  269.             break;
  270.         case 0xF00A:
  271.             // FX0A - Wait for a key press, store the value of the key in Vx.
  272.             // TODO Implement.
  273.             break;
  274.         case 0xF015:
  275.             // Set delay timer to Vx.
  276.             delayTimer = V[(opcode & 0x0F00) >>> 8];
  277.             PC += 2;
  278.             break;
  279.         case 0xF018:
  280.             // set sound timer to Vx
  281.             soundTimer = V[(opcode & 0x0F00) >>> 8];
  282.             PC += 2;
  283.             break;
  284.         case 0xF01E:
  285.             // Set I to I + Vx.
  286.             I += V[(opcode & 0x0F00) >>> 8] * 5;
  287.  
  288.             PC += 2;
  289.             break;
  290.         case 0xF029:
  291.             // set I to location of sprite
  292.             I = V[(opcode & 0x0F00) >>> 8];
  293.             PC += 2;
  294.             break;
  295.         case 0xF033:
  296.             // Stores the binary-coded decimal representation of VX, with the most
  297.             // significant of three digits at the address in I, the middle digit at I plus
  298.             // 1, and the least significant digit at I plus 2. (In other words, take the
  299.             // decimal representation of VX, place the hundreds digit in memory at location
  300.             // in I, the tens digit at location I+1, and the ones digit at location I+2.).
  301.             // get first digit
  302.             // get most significant digit
  303.  
  304.             //using someone elses code
  305.             //TODO Redo this code as original code
  306.  
  307.             memory[I] = (V[(opcode & 0x0F00) >>> 8] / 100);
  308.             memory[I + 1] = ((V[(opcode & 0x0F00) >>> 8] % 100) / 10);
  309.             memory[I + 2] = ((V[(opcode & 0x0F00) >>> 8] % 100) % 10);
  310.  
  311.             PC += 2;
  312.             break;
  313.         case 0xF055:
  314.             // Store registers V0 through Vx in memory at I
  315.             for (int x = 0x000; x < (opcode & 0x0F00 >>> 8); x++) {
  316.                 memory[I + x] = V[x];
  317.             }
  318.             PC += 2;
  319.             break;
  320.         case 0xF065:
  321.             // Read registers V0 through Vx
  322.             for (int x = 0x000; x < (opcode & 0x0F00) >>> 8; x++) {
  323.                 V[x] = memory[I + x] & 0x00ff;
  324.  
  325.             }
  326.             PC += 2;
  327.             break;
  328.         }
  329.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement