daily pastebin goal
66%
SHARE
TWEET

emu_chip.cpp

otto_baynes Jun 12th, 2012 445 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. /*
  2.  *  emuChip - CHIP-8 emulator.
  3.  *  Copyright (C) 2009-2012 Boris Timofeev <mashin87@gmail.com> <http://www.emunix.org>
  4.  *
  5.  *  This program is free software: you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation, either version 3 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18. #include "chip_emu.h"
  19. #include <stdlib.h>
  20. #include <iostream>
  21. #include <fstream>
  22. #include <time.h>
  23.  
  24. using namespace std;
  25.  
  26. ChipEmu::ChipEmu()
  27. {
  28.         init();
  29.         srand(time(NULL));
  30. }
  31.  
  32. // Clear registers, memory and stack. Load fonts and redraw screen.
  33. void ChipEmu::init()
  34. {
  35.         PC = 0x200;
  36.         SP = 0;
  37.         I = 0;
  38.         delay_timer = 0;
  39.         sound_timer = 0;
  40.  
  41.         for (int i = 0; i < 4096; i++)
  42.                 memory[i] = 0;
  43.        
  44.         for (int y = 0; y < 64; y++)
  45.                 for (int x = 0; x < 128; x++)
  46.                         screen[x][y] = 0;
  47.  
  48.         for (int i = 0; i < 16; i++)
  49.                 V[i] = 0;
  50.        
  51.         for (int i = 0; i < 16; i++)
  52.                 key[i] = 0;
  53.  
  54.         for (int i = 0; i < 16; i++)
  55.                 stack[i] = 0;
  56.        
  57.         unsigned char font[16*5] = {
  58.                 0xF0, 0x90, 0x90, 0x90, 0xF0,   // 0
  59.                 0x20, 0x60, 0x20, 0x20, 0x70,   // 1
  60.                 0xF0, 0x10, 0xF0, 0x80, 0xF0,   // 2
  61.                 0xF0, 0x10, 0xF0, 0x10, 0xF0,   // 3
  62.                 0x90, 0x90, 0xF0, 0x10, 0x10,   // 4
  63.                 0xF0, 0x80, 0xF0, 0x10, 0xF0,   // 5
  64.                 0xF0, 0x80, 0xF0, 0x90, 0xF0,   // 6
  65.                 0xF0, 0x10, 0x20, 0x40, 0x40,   // 7
  66.                 0xF0, 0x90, 0xF0, 0x90, 0xF0,   // 8
  67.                 0xF0, 0x90, 0xF0, 0x10, 0xF0,   // 9
  68.                 0xF0, 0x90, 0xF0, 0x90, 0x90,   // A
  69.                 0xE0, 0x90, 0xE0, 0x90, 0xE0,   // B
  70.                 0xF0, 0x80, 0x80, 0x80, 0xF0,   // C
  71.                 0xE0, 0x90, 0x90, 0x90, 0xE0,   // D
  72.                 0xF0, 0x80, 0xF0, 0x80, 0xF0,   // E
  73.                 0xF0, 0x80, 0xF0, 0x80, 0x80    // F
  74.         };
  75.         // Load font
  76.         for (int i = 0; i < 16*5; i++)
  77.                 memory[i] = font[i];
  78.        
  79.         unsigned char bigfont[16*10] = {
  80.                 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF,     // 0
  81.                 0x18, 0x78, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF,     // 1
  82.                 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF,     // 2
  83.                 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF,     // 3
  84.                 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x03, // 4
  85.                 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF,     // 5
  86.                 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF,     // 6
  87.                 0xFF, 0xFF, 0x03, 0x03, 0x06, 0x0C, 0x18, 0x18, 0x18, 0x18, // 7
  88.                 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF,     // 8
  89.                 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF,     // 9
  90.                 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, // A
  91.                 0xFC, 0xFC, 0xC3, 0xC3, 0xFC, 0xFC, 0xC3, 0xC3, 0xFC, 0xFC, // B
  92.                 0x3C, 0xFF, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0xFF, 0x3C, // C
  93.                 0xFC, 0xFE, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFE, 0xFC, // D
  94.                 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, // E
  95.                 0xFF, 0xFF, 0xC0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0  // F
  96.         };
  97.        
  98.         // Load big font
  99.         for (int i=0; i < 16*10; i++)
  100.                 memory[i+80] = bigfont[i];
  101.        
  102.         for (int i=0; i < 8; i++)
  103.                 hp48_flags[i] = 0;
  104.        
  105.         stop = false;
  106.        
  107.         mode = 0;
  108. }
  109.  
  110. void ChipEmu::drawSprite(unsigned char X, unsigned char Y, unsigned char N)
  111. {      
  112.         V[0xF] = 0;
  113.         switch (mode)
  114.         {
  115.                 case 0: // CHIP-8 mode
  116.                         if (N == 0) N = 16;
  117.                         for (int yline = 0; yline < N; yline++)
  118.                         {
  119.                                 unsigned char data = memory[I + yline];
  120.                                 for (int xpix = 0; xpix < 8; xpix++)
  121.                                 {
  122.                                         if((data & (0x80 >> xpix)) != 0)
  123.                                         {
  124.                                                 if ((V[X] + xpix) < 64 && (V[Y] + yline) < 32 && (V[X] + xpix) >= 0 && (V[Y] + yline) >= 0)
  125.                                                 {
  126.                                                         if (screen[(V[X] + xpix)*2][(V[Y] + yline)*2] == 1) V[0xF] = 1;
  127.                                                         screen[(V[X] + xpix)*2][(V[Y] + yline)*2] ^= 1;
  128.                                                         screen[(V[X] + xpix)*2 + 1][(V[Y] + yline)*2] ^= 1;
  129.                                                         screen[(V[X] + xpix)*2][(V[Y] + yline)*2 + 1] ^= 1;
  130.                                                         screen[(V[X] + xpix)*2 + 1][(V[Y] + yline)*2 + 1] ^= 1;
  131.                                                 }
  132.                                         }
  133.                                 }
  134.                         }
  135.                         break;
  136.                        
  137.                 case 1: // SCHIP mode
  138.                         if (N == 0)
  139.                                 for (int yline = 0; yline < 16; yline++)
  140.                                 {
  141.                                         unsigned char data = memory[I + yline*2];
  142.                                         for (int xpix = 0; xpix < 8; xpix++)
  143.                                         {
  144.                                                 if((data & (0x80 >> xpix)) != 0)
  145.                                                 {
  146.                                                         if ((V[X] + xpix) < 128 && (V[Y] + yline) < 64 && (V[X] + xpix) >= 0 && (V[Y] + yline) >= 0)
  147.                                                         {
  148.                                                                 if (screen[V[X] + xpix][V[Y] + yline] == 1) V[0xF] = 1;
  149.                                                                 screen[V[X] + xpix][V[Y] + yline] ^= 1;
  150.                                                         }
  151.                                                 }
  152.                                         }
  153.                                         data = memory[I + 1 + yline*2];
  154.                                         for (int xpix = 0; xpix < 8; xpix++)
  155.                                         {
  156.                                                 if((data & (0x80 >> xpix)) != 0)
  157.                                                 {
  158.                                                         if ((V[X] + xpix + 8) < 128 && (V[Y] + yline) < 64 && (V[X] + xpix + 8) >= 0 && (V[Y] + yline) >= 0)
  159.                                                         {
  160.                                                                 if (screen[V[X] + xpix + 8][V[Y] + yline] == 1) V[0xF] = 1;
  161.                                                                 screen[V[X] + xpix + 8][V[Y] + yline] ^= 1;
  162.                                                         }
  163.                                                 }
  164.                                         }
  165.                                 }
  166.                         else
  167.                                 for (int yline = 0; yline < N; yline++)
  168.                                 {
  169.                                         unsigned char data = memory[I + yline];
  170.                                         for (int xpix = 0; xpix < 8; xpix++)
  171.                                         {
  172.                                                 if((data & (0x80 >> xpix)) != 0)
  173.                                                 {
  174.                                                         if ((V[X] + xpix) < 128 && (V[Y] + yline) < 64 && (V[X] + xpix) >= 0 && (V[Y] + yline) >= 0)
  175.                                                         {
  176.                                                                 if (screen[V[X] + xpix][V[Y] + yline] == 1) V[0xF] = 1;
  177.                                                                 screen[V[X] + xpix][V[Y] + yline] ^= 1;
  178.                                                         }
  179.                                                 }
  180.                                         }
  181.                                 }
  182.                         break;
  183.         }
  184. }
  185.  
  186. void ChipEmu::executeNextOpcode()
  187. {
  188.         opcode = (memory[PC]<<8) + memory[PC+1];
  189.  
  190.         PC += 2;
  191.  
  192.         switch ((opcode & 0xF000)>>12)
  193.         {
  194.                 case 0x0:
  195.                         if ((opcode & 0x00F0)>>4 == 0xC) // 00CN - scroll display N lines down *SCHIP*
  196.                         {
  197.                                 int N = opcode & 0x000F;
  198.                                 for (int y = 63; y > N; y--)
  199.                                         for (int x = 0; x < 128; x++)
  200.                                                 screen[x][y] = screen[x][y-N];
  201.                                 for (int y = 0; y < N; y++)
  202.                                         for (int x = 0; x < 128; x++)
  203.                                                 screen[x][y] = 0;
  204.                                 break;
  205.                         }
  206.  
  207.                         switch  (opcode & 0x00FF)
  208.                         {
  209.                                 case 0xE0:              // 00E0 - clear the screen
  210.                                         for (int y = 0; y < 64; y++)
  211.                                                 for (int x = 0; x < 128; x++)
  212.                                                         screen[x][y] = 0;
  213.                                         break;
  214.  
  215.                                 case 0xEE:              // 00EE - return from subroutine
  216.                                         PC = stack[--SP];
  217.                                         break;
  218.                                
  219.                                 case 0xFB:              // 00FB - scroll display 4 pixels right *SCHIP*
  220.                                         for (int y = 0; y < 64; y++)
  221.                                         {
  222.                                                 for (int x = 127; x > 3; x--)
  223.                                                         screen[x][y] = screen[x-4][y];
  224.                                                 screen[0][y] = 0;
  225.                                                 screen[1][y] = 0;
  226.                                                 screen[2][y] = 0;
  227.                                                 screen[3][y] = 0;
  228.                                         }
  229.                                         break;
  230.                                
  231.                                 case 0xFC:              // 00FB - scroll display 4 pixels left *SCHIP*
  232.                                         for (int y = 0; y < 64; y++)
  233.                                         {
  234.                                                 for (int x = 0; x < 124; x++)
  235.                                                         screen[x][y] = screen[x+4][y];
  236.                                                 screen[124][y] = 0;
  237.                                                 screen[125][y] = 0;
  238.                                                 screen[126][y] = 0;
  239.                                                 screen[127][y] = 0;
  240.                                         }
  241.                                         break;
  242.                                
  243.                                 case 0xFD:              // 00FD - Quit the emulator
  244.                                         stop = true;
  245.                                         cout << "Quit the emulator" << endl;
  246.                                         break;
  247.                                                
  248.                                 case 0xFE:              // 00FE - disable extended screen mode *SCHIP*
  249.                                         mode = 0;
  250.                                         break;
  251.                                
  252.                                 case 0xFF:              // 00FF - enable extended screen mode *SCHIP*
  253.                                         mode = 1;
  254.                                         break;
  255.                                
  256.                                 default:
  257.                                         cerr << "Unknown opcode: 0x" << hex << opcode <<endl;
  258.                         }
  259.                         break;
  260.  
  261.                 case 0x1:                               // 1NNN - jump to addr
  262.                         PC = opcode & 0x0FFF;
  263.                         break;
  264.  
  265.                 case 0x2:                               // 2NNN - call subroutine
  266.                         stack[SP++] = PC;
  267.                         PC = opcode & 0x0FFF;
  268.                         break;
  269.  
  270.                 case 0x3:                               // 3XKK - skip next instruction if VX == Byte
  271.                         if (V[((opcode & 0x0F00)>>8)] == (opcode & 0x00FF)) PC += 2;
  272.                         break;
  273.  
  274.                 case 0x4:                               // 4XKK - skip next instruction if VX != Byte
  275.                         if (V[((opcode & 0x0F00)>>8)] != (opcode & 0x00FF)) PC += 2;
  276.                         break;
  277.  
  278.                 case 0x5:                               // 5XY0 - skip next instruction if VX == VY
  279.                         if (V[((opcode & 0x0F00)>>8)] == V[((opcode & 0x00F0)>>4)]) PC += 2;
  280.                         break;
  281.  
  282.                 case 0x6:                               // 6XKK - set VX = Byte
  283.                         V[((opcode & 0x0F00)>>8)] = opcode & 0x00FF;
  284.                         break;
  285.  
  286.                 case 0x7:                               // 7XKK - set VX = VX + Byte
  287.                         V[((opcode & 0x0F00)>>8)] += opcode & 0x00FF;
  288.                         break;
  289.  
  290.                 case 0x8:
  291.                         switch (opcode & 0x000F)
  292.                         {
  293.                                 case 0x0:               // 8XY0 - set VX = VY
  294.                                         V[((opcode & 0x0F00)>>8)] = V[((opcode & 0x00F0)>>4)];
  295.                                
  296.                                         break;
  297.  
  298.                                 case 0x1:               // 8XY1 - set VX = VX | VY
  299.                                         V[((opcode & 0x0F00)>>8)] |= V[((opcode & 0x00F0)>>4)];
  300.                                         break;
  301.  
  302.                                 case 0x2:               // 8XY2 - set VX = VX & VY
  303.                                         V[((opcode & 0x0F00)>>8)] &= V[((opcode & 0x00F0)>>4)];
  304.                                         break;
  305.  
  306.                                 case 0x3:               // 8XY3 - set VX = VX ^ VY
  307.                                         V[((opcode & 0x0F00)>>8)] ^= V[((opcode & 0x00F0)>>4)];
  308.                                         break;
  309.  
  310.                                 case 0x4:               // 8XY4 - set VX = VX + VY, VF = carry
  311.                                         int i;
  312.                                         i = static_cast<int>(V[((opcode & 0x0F00)>>8)]) + static_cast<int>(V[((opcode & 0x00F0)>>4)]);
  313.  
  314.                                         if (i > 255)
  315.                                                 V[0xF] = 1;
  316.                                         else
  317.                                                 V[0xF] = 0;
  318.  
  319.                                         V[((opcode & 0x0F00)>>8)] = i;
  320.                                         break;
  321.  
  322.                                 case 0x5:               // 8XY5 - set VX = VX - VY, VF = !borrow
  323.                                         if (V[((opcode & 0x0F00)>>8)] >= V[((opcode & 0x00F0)>>4)])
  324.                                                 V[0xF] = 1;
  325.                                         else
  326.                                                 V[0xF] = 0;
  327.  
  328.                                         V[((opcode & 0x0F00)>>8)] -= V[((opcode & 0x00F0)>>4)];
  329.                                         break;
  330.  
  331.                                 case 0x6:               // 8XY6 - set VX = VX >> 1, VF = carry
  332.                                         V[0xF] = V[((opcode & 0x0F00)>>8)] & 0x1;
  333.                                         V[((opcode & 0x0F00)>>8)] >>= 1;
  334.                                         break;
  335.  
  336.                                 case 0x7:               // 8XY7 - set VX = VY - VX, VF = !borrow
  337.                                         if (V[((opcode & 0x00F0)>>4)] >= V[((opcode & 0x0F00)>>8)])
  338.                                                 V[0xF] = 1;
  339.                                         else
  340.                                                 V[0xF] = 0;
  341.  
  342.                                         V[((opcode & 0x0F00)>>8)] = V[((opcode & 0x00F0)>>4)] - V[((opcode & 0x0F00)>>8)];
  343.                                         break;
  344.  
  345.                                 case 0xE:               // 8XYE - set VX = VX << 1, VF = carry
  346.                                         V[0xF] = (V[((opcode & 0x0F00)>>8)] >> 7) & 0x01;
  347.                                         V[((opcode & 0x0F00)>>8)] <<= 1;
  348.                                         break;
  349.                                
  350.                                 default:
  351.                                         cerr << "Unknown opcode: 0x" << hex << opcode <<endl;
  352.                         }
  353.                         break;
  354.  
  355.                 case 0x9:                               // 9XY0 - skip next instruction if VX != VY
  356.                         if (V[((opcode & 0x0F00)>>8)] != V[((opcode & 0x00F0)>>4)]) PC += 2;
  357.                         break;
  358.  
  359.                 case 0xA:                               // ANNN - set I = Addr
  360.                         I = opcode & 0x0FFF;
  361.                         break;
  362.  
  363.                 case 0xB:                               // BNNN - jump to Addr + V0
  364.                         PC = (opcode & 0x0FFF) + V[0];
  365.                         break;
  366.  
  367.                 case 0xC:                               // CXKK - set VX = random & Byte
  368.                         V[((opcode & 0x0F00)>>8)] = (rand() % 255) & (opcode & 0x00FF);
  369.                         break;
  370.  
  371.                 case 0xD:                               // DXYN - Draw sprite
  372.                         drawSprite(((opcode & 0x0F00)>>8), ((opcode & 0x00F0)>>4), (opcode & 0x000F));
  373.                         break;
  374.  
  375.                 case 0xE:
  376.                         switch (opcode & 0x00FF)
  377.                         {
  378.                                 case 0x9E:              // EX9E - skip next instruction if key VX down
  379.                                         if (key[V[((opcode & 0x0F00)>>8)]] == 1)
  380.                                                 PC += 2;
  381.                                         break;
  382.  
  383.                                 case 0xA1:              // EXA1 - skip next instruction if key VX up
  384.                                         if (key[V[((opcode & 0x0F00)>>8)]] == 0)
  385.                                                 PC += 2;
  386.                                         break;
  387.                                        
  388.                                 default:
  389.                                         cerr << "Unknown opcode: 0x" << hex << opcode <<endl;
  390.                         }
  391.                         break;
  392.  
  393.                 case 0xF:
  394.                         switch (opcode & 0x00FF)
  395.                         {
  396.                                 case 0x07:              // FX07 - set VX = delaytimer
  397.                                         V[((opcode & 0x0F00)>>8)] = delay_timer;
  398.                                         break;
  399.  
  400.                                 case 0x0A:              // FX0A - set VX = key, wait for keypress
  401.                                         PC -= 2;
  402.                                         for (unsigned char n=0; n < 16; n++)
  403.                                         {
  404.                                                 if (key[n] == 1)
  405.                                                 {
  406.                                                         V[((opcode & 0x0F00)>>8)] = n;
  407.                                                         PC += 2;
  408.                                                         break;
  409.                                                 }
  410.                                         }
  411.                                         break;
  412.  
  413.                                 case 0x15:              // FX15 - set delaytimer = VX
  414.                                         delay_timer = V[((opcode & 0x0F00)>>8)];
  415.                                         break;
  416.  
  417.                                 case 0x18:              // FX18 - set soundtimer = VX
  418.                                         sound_timer = V[((opcode & 0x0F00)>>8)];
  419.                                         break;
  420.  
  421.                                 case 0x1E:              // FX1E - set I = I + VX; set VF if buffer overflow
  422.                                         if ((I += V[((opcode & 0x0F00)>>8)]) > 0xfff)
  423.                                                 V[0xF] = 1;
  424.                                         else
  425.                                                 V[0xF] = 0;
  426.                                         break;
  427.  
  428.                                 case 0x29:              // FX29 - point I to 5 byte numeric sprite for value in VX
  429.                                         I = V[((opcode & 0x0F00)>>8)] * 5;
  430.                                         break;
  431.                                
  432.                                 case 0x30:              // FX30 - point I to 10 byte numeric sprite for value in VX *SCHIP*
  433.                                         I = V[((opcode & 0x0F00)>>8)] * 10 + 80;
  434.                                         break;
  435.  
  436.                                 case 0x33:              // FX33 - store BCD of VX in [I], [I+1], [I+2]
  437.                                         int n;
  438.                                         n = V[((opcode & 0x0F00)>>8)];
  439.                                         memory[I] = (n - (n % 100)) / 100;
  440.                                         n -= memory[I] * 100;
  441.                                         memory[I+1] = (n - (n % 10)) / 10;
  442.                                         n -= memory[I+1] * 10;
  443.                                         memory[I+2] = n;
  444.                                         break;
  445.  
  446.                                 case 0x55:              // FX55 - store V0 .. VX in [I] .. [I+X]
  447.                                         for (int n=0; n <= ((opcode & 0x0F00)>>8); n++)
  448.                                                 memory[I+n] = V[n];
  449.                                         break;
  450.  
  451.                                 case 0x65:              // FX65 - read V0 .. VX from [I] .. [I+X]
  452.                                         for (int n=0; n <= ((opcode & 0x0F00)>>8); n++)
  453.                                                 V[n] = memory[I+n];
  454.                                         break;
  455.                                        
  456.                                 case 0x75:              // FX75 - save V0...VX (X<8) in the HP48 flags *SCHIP*
  457.                                         //for (int i=0; i < 8; i++)
  458.                                                 //hp48_flags[i] = 0;
  459.                                         for (int i=0; i <= ((opcode & 0x0F00)>>8); i++)
  460.                                                 hp48_flags[i] = V[i];
  461.                                         break;
  462.                                
  463.                                 case 0x85:              // FX85 - load V0...VX (X<8) from the HP48 flags *SCHIP*
  464.                                         for (int i=0; i <= ((opcode & 0x0F00)>>8); i++)
  465.                                                 V[i] = hp48_flags[i];
  466.                                         //for (int i=0; i < 8; i++)
  467.                                                 //hp48_flags[i] = 0;
  468.                                         break;
  469.                                        
  470.                                 default:
  471.                                         cerr << "Unknown opcode: 0x" << hex << opcode <<endl;
  472.                         }
  473.                         break;
  474.  
  475.                 default:
  476.                         cerr << "Unknown opcode: 0x" << hex << opcode <<endl;
  477.         }
  478. }
  479.  
  480. bool ChipEmu::loadGame(const char *filename)
  481. {
  482.         ifstream file(filename, ios::in | ios::binary | ios::ate);
  483.         if (file.is_open())
  484.         {
  485.                 ifstream::pos_type size;
  486.                 size = file.tellg();
  487.                 if (size > 0x0FFF - 0x200)
  488.                 {
  489.                         cerr << "Error: file '" << filename << "' is too large." << endl;
  490.                         return false;
  491.                 }
  492.                 file.seekg(0, ios::beg);
  493.                 file.read(reinterpret_cast<char*>(&memory[0x200]), size);
  494.                 file.close();
  495.                
  496.                 cout << "File '" << filename << "' loaded." << endl;
  497.                 return true;
  498.         }
  499.  
  500.         cerr << "Error: unable to open file '" << filename << "'" << endl;
  501.         return false;
  502. }
  503.  
  504. void ChipEmu::decreaseTimers()
  505. {
  506.         if(delay_timer > 0)
  507.                 --delay_timer;
  508.  
  509.         if(sound_timer > 0)
  510.                 --sound_timer;
  511. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top