示例#1
0
        public void Draw(GameTime gameTime)
        {
            try
            {
                GuiSpriteBatch.Begin();

                ForEachScreen(screen =>
                {
                    screen.Draw(GuiSpriteBatch, gameTime);

                    DrawScreen?.Invoke(this, new GuiDrawScreenEventArgs(screen, gameTime));
                    //  DebugHelper.DrawScreen(screen);
                });
            }
            finally
            {
                GuiSpriteBatch.End();
            }
        }
示例#2
0
        public CPU()
        {
            Decoder = new Dictionary <int, Action>()
            {
                // 0x0*** opcodes.
                { 0x0, () =>
                  {
                      // 0x00E0 -- Clear the screen.
                      if ((IR & 0x00FF) == 0x00E0)
                      {
                          for (int y = 0; y < _g_mem.GetLength(0); y++)
                          {
                              for (int x = 0; x < _g_mem.GetLength(1); x++)
                              {
                                  _g_mem[y, x] = false;
                              }
                          }

                          DrawScreen(this, null);
                      }
                      // 0x00EE -- Return from a subroutine.
                      else if ((IR & 0x00FF) == 0x00EE)
                      {
                          PC = stack[SP];
                          SP--;
                      }
                      else
                      {
                          // No-op or halt
                      }
                  } },

                // 0x1nnn -- Jump to location nnn.
                { 0x1, () =>
                  {
                      PC = NNN;
                  } },

                // 0x2nnn -- Call subroutine at nnn.
                { 0x2, () =>
                  {
                      SP++;
                      stack[SP] = PC;
                      PC        = NNN;
                  } },

                // 0x3xnn -- Skip the next instruction if Vx == nn
                { 0x3, () =>
                  {
                      if (V[X] == NN)
                      {
                          PC += 2;
                      }
                  } },

                // 0x4xnn -- Skip the next instruction if Vx != nn
                { 0x4, () =>
                  {
                      if (V[X] != NN)
                      {
                          PC += 2;
                      }
                  } },

                // 0x5xy0 -- Skip the next instruction if Vx == Vy
                { 0x5, () =>
                  {
                      if (V[X] == V[Y])
                      {
                          PC += 2;
                      }
                  } },

                // 0x6xkk -- Puts the value kk into register Vx
                { 0x6, () =>
                  {
                      V[X] = (byte)NN;
                  } },

                // 0x7xkk -- Adds the value kk to the value of register Vx, then stores the result in Vx
                { 0x7, () =>
                  {
                      V[X] += (byte)NN;
                  } },

                // 0x800* opcodes.
                { 0x8, () =>
                  {
                      int c = IR & 0x000F;
                      switch (c)
                      {
                      // 0x8xy0 -- Store the value of register Vy in register Vx
                      case 0:
                          V[X] = V[Y];
                          break;

                      // 0x8xy1 -- Set Vx = Vx OR Vy
                      case 1:
                          V[X] |= V[Y];
                          break;

                      // 0x8xy2 -- Set Vx = AND Vy
                      case 2:
                          V[X] &= V[Y];
                          break;

                      // 0x8xy3 -- Set Vx = Vx XOR Vy
                      case 3:
                          V[X] ^= V[Y];
                          break;

                      // 0x8xy4 -- Set Vx = Vx + Vy, set VF = carry.
                      case 4:
                          int value = V[X] + V[Y];

                          V[X] = (byte)(value & 0xFF);

                          if (value > 0xFF)
                          {
                              V[0xF] = 1;
                          }
                          else
                          {
                              V[0xF] = 0;
                          }
                          break;

                      // 0x8xy5 -- Set Vx = Vx - Vy, set VF to NOT borrow.
                      case 5:
                          if (V[X] > V[Y])
                          {
                              V[0xF] = 1;
                          }
                          else
                          {
                              V[0xF] = 0;
                          }

                          V[X] -= V[Y];
                          break;

                      // 0x8xy6 -- sets Vx = Vx >> 1
                      case 6:
                          if ((V[X] & 0x01) > 0)
                          {
                              V[0xF] = 1;
                          }
                          else
                          {
                              V[0xF] = 0;
                          }

                          V[X] >>= 1;
                          break;

                      // 0x8xy7 -- SUBN Vx, Vy
                      case 7:
                          if (V[Y] > V[X])
                          {
                              V[0xF] = 1;
                          }
                          else
                          {
                              V[0xF] = 0;
                          }

                          V[X] = (byte)(V[Y] - V[X]);
                          break;

                      // 8xyE - SHL Vx {, Vy}
                      case 0xE:
                          if ((0x80 & V[X]) == 0x80)
                          {
                              V[0xF] = 1;
                          }
                          else
                          {
                              V[0xF] = 0;
                          }
                          V[X] <<= 1;
                          break;
                      }
                  } },

                // 0x9xy0 -- SNE Vx, Vy
                { 0x9, () =>
                  {
                      if (V[X] != V[Y])
                      {
                          PC += 2;
                      }
                  } },

                // 0xAnnn -- LD I, addr
                { 0xA, () =>
                  {
                      I = IR & NNN;
                  } },

                //Bnnn - JP V0, addr Jump to location nnn + V0.
                { 0xB, () =>
                  {
                      PC = NNN + V[0];
                  } },

                // Cxkk - RND Vx, byte Set Vx = random byte AND kk
                { 0xC, () =>
                  {
                      V[X] = (byte)(((new Random(DateTime.Now.Second)).Next(0, 255) & 0xFF) & NN);
                  } },

                // Dxyn - DRW Vx, Vy, nibble Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
                { 0xD, () =>
                  {
                      V[0xF] = 0;

                      for (int i = 0; i < N; i++)
                      {
                          byte b    = _mem[I + i];
                          int  yPos = (V[Y] + i) % 32;

                          for (int j = 0; j < 8; j++)
                          {
                              int bMask = 0x80 >> j;
                              int xPos  = (V[X] + j) % 64;

                              int b_bit = (b & bMask) << j;

                              if (_g_mem[yPos, xPos] && b_bit > 0)
                              {
                                  V[0xF] = 1;
                              }

                              _g_mem[yPos, xPos] ^= (b_bit > 0 ? true : false);
                          }
                      }

                      DrawScreen?.Invoke(this, null);
                  } },


                {
                    // 0xE*** opcodes.
                    0xE, () =>
                    {
                        // Ex9E - SKP Vx -- Skip next instruction if key with the value of Vx is pressed.
                        if (NN == 0x9E)
                        {
                            if (Keyboard[V[X]])
                            {
                                PC += 2;
                            }
                        }
                        // ExA1 - SKNP Vx -- Skip next instruction if key with the value of Vx is not pressed.
                        else if (NN == 0xA1)
                        {
                            if (!Keyboard[V[X]])
                            {
                                PC += 2;
                            }
                        }
                    }
                },

                // 0xF*** opcodes.
                { 0xF, () =>
                  {
                      int c = IR & 0x00FF;

                      switch (c)
                      {
                      // Fx07 - LD Vx, DT -- Set Vx = delay timer value.
                      case 0x07:
                          V[X] = DT;
                          break;

                      // Fx0A - LD Vx, K -- Wait for a key press, store the value of the key in Vx.
                      case 0x0A:
                          var pressedKeys = Keyboard.Where(k => k.Value);

                          while (pressedKeys.Count() <= 0)
                          {
                              // Poll until a key is pressed.
                              Task.Delay(_CLOCK_SPEED);
                          }

                          V[X] = pressedKeys.FirstOrDefault().Key;
                          break;

                      // Fx15 - LD DT, Vx -- Set delay timer = Vx.
                      case 0x15:
                          DT = V[X];
                          break;

                      // Fx18 - LD ST, Vx -- Set sound timer = Vx.
                      case 0x18:
                          ST = V[X];
                          break;

                      // Fx1E - ADD I, Vx -- Set I = I + Vx.
                      case 0x1E:
                          I = I + V[X];
                          break;

                      // Fx29 - LD F, Vx -- Set I = location of sprite for digit Vx.
                      case 0x29:
                          I = V[X] * 5;
                          break;

                      // Fx33 - LD B, Vx. Stores the BCD representation of V[X] in memory locations I, I+1, I+2
                      case 0x33:
                          int dec      = V[X];
                          int hundreds = (dec / 100);
                          int tens     = (dec / 10) - (hundreds * 10);
                          int ones     = dec % 10;
                          _mem[I]     = (byte)hundreds;
                          _mem[I + 1] = (byte)tens;
                          _mem[I + 2] = (byte)ones;
                          break;

                      // Fx55 - LD [I], Vx -- Store registers V0 through Vx in memory starting at location I.
                      case 0x55:
                          for (int i = 0; i <= X; i++)
                          {
                              _mem[I + i] = V[i];
                          }
                          break;

                      // Fx65 - LD Vx, [I] -- Read registers V0 through Vx from memory starting at location I.
                      case 0x65:
                          for (int i = 0; i <= X; i++)
                          {
                              V[i] = _mem[I + i];
                          }
                          break;
                      }
                  } },
            };
        }
 public void App_DrawScreen(PInfo[,] information, int x, int y, IRenderingApplication sender)
 {
     DrawScreen?.Invoke(information, x, y, sender);
 }