Emulation of the 1970's Chip-8 machine. The emulator has 7 games that are unmodified from the original Chip-8 format.

Dependencies:   mbed

Committer:
taylorza
Date:
Sun Feb 08 01:58:57 2015 +0000
Revision:
0:bc3f11b1b41f
Chip-8 Emulator

Who changed what in which revision?

UserRevisionLine numberNew contents of line
taylorza 0:bc3f11b1b41f 1 #include "Chip8Emulator.h"
taylorza 0:bc3f11b1b41f 2 #include <string.h>
taylorza 0:bc3f11b1b41f 3 #include "GameInput.h"
taylorza 0:bc3f11b1b41f 4 #include "Color565.h"
taylorza 0:bc3f11b1b41f 5
taylorza 0:bc3f11b1b41f 6
taylorza 0:bc3f11b1b41f 7 DigitalOut led1(P0_18, false);
taylorza 0:bc3f11b1b41f 8
taylorza 0:bc3f11b1b41f 9 const uint8_t Chip8Emulator::_font[] =
taylorza 0:bc3f11b1b41f 10 {
taylorza 0:bc3f11b1b41f 11 0xF0,0x90,0x90,0x90,0xF0, // 0
taylorza 0:bc3f11b1b41f 12 0x20,0x60,0x20,0x20,0x70, // 1
taylorza 0:bc3f11b1b41f 13 0xF0,0x10,0xF0,0x80,0xF0, // 2
taylorza 0:bc3f11b1b41f 14 0xF0,0x10,0xF0,0x10,0xF0, // 3
taylorza 0:bc3f11b1b41f 15 0x90,0x90,0xF0,0x10,0x10, // 4
taylorza 0:bc3f11b1b41f 16 0xF0,0x80,0xF0,0x10,0xF0, // 5
taylorza 0:bc3f11b1b41f 17 0xF0,0x80,0xF0,0x90,0xF0, // 6
taylorza 0:bc3f11b1b41f 18 0xF0,0x10,0x20,0x40,0x40, // 7
taylorza 0:bc3f11b1b41f 19 0xF0,0x90,0xF0,0x90,0xF0, // 8
taylorza 0:bc3f11b1b41f 20 0xF0,0x90,0xF0,0x10,0xF0, // 9
taylorza 0:bc3f11b1b41f 21 0xF0,0x90,0xF0,0x90,0x90, // A
taylorza 0:bc3f11b1b41f 22 0xE0,0x90,0xE0,0x90,0xE0, // B
taylorza 0:bc3f11b1b41f 23 0xF0,0x80,0x80,0x80,0xF0, // C
taylorza 0:bc3f11b1b41f 24 0xE0,0x90,0x90,0x90,0xE0, // D
taylorza 0:bc3f11b1b41f 25 0xF0,0x80,0xF0,0x80,0xF0, // E
taylorza 0:bc3f11b1b41f 26 0xF0,0x80,0xF0,0x80,0x80 // F
taylorza 0:bc3f11b1b41f 27 };
taylorza 0:bc3f11b1b41f 28
taylorza 0:bc3f11b1b41f 29 Chip8Emulator::Chip8Emulator(LCD_ST7735 &screen, const uint8_t *program, uint16_t programSize, uint8_t leftKey, uint8_t rightKey, uint8_t upKey, uint8_t downKey, uint8_t fireKey, uint8_t startKey) :
taylorza 0:bc3f11b1b41f 30 _bmp(64, 32),
taylorza 0:bc3f11b1b41f 31 _screen(screen),
taylorza 0:bc3f11b1b41f 32 _delay(0),
taylorza 0:bc3f11b1b41f 33 _sound(0),
taylorza 0:bc3f11b1b41f 34 _pc(0x200),
taylorza 0:bc3f11b1b41f 35 _sp(0),
taylorza 0:bc3f11b1b41f 36 _i(0),
taylorza 0:bc3f11b1b41f 37 _leftKey(leftKey),
taylorza 0:bc3f11b1b41f 38 _rightKey(rightKey),
taylorza 0:bc3f11b1b41f 39 _upKey(upKey),
taylorza 0:bc3f11b1b41f 40 _downKey(downKey),
taylorza 0:bc3f11b1b41f 41 _fireKey(fireKey),
taylorza 0:bc3f11b1b41f 42 _startKey(startKey)
taylorza 0:bc3f11b1b41f 43 {
taylorza 0:bc3f11b1b41f 44 memset(_memory, 0, sizeof(_memory));
taylorza 0:bc3f11b1b41f 45 memset(_stack, 0, sizeof(_stack));
taylorza 0:bc3f11b1b41f 46 memset(_registers, 0, sizeof(_registers));
taylorza 0:bc3f11b1b41f 47
taylorza 0:bc3f11b1b41f 48 memcpy(_memory, _font, sizeof(_font));
taylorza 0:bc3f11b1b41f 49 memcpy(_memory + _pc, program, programSize);
taylorza 0:bc3f11b1b41f 50 }
taylorza 0:bc3f11b1b41f 51
taylorza 0:bc3f11b1b41f 52 void Chip8Emulator::run()
taylorza 0:bc3f11b1b41f 53 {
taylorza 0:bc3f11b1b41f 54 _screen.clearScreen(0);
taylorza 0:bc3f11b1b41f 55 _bmp.clear();
taylorza 0:bc3f11b1b41f 56
taylorza 0:bc3f11b1b41f 57 Timer updateTimer;
taylorza 0:bc3f11b1b41f 58 updateTimer.start();
taylorza 0:bc3f11b1b41f 59 int lastReading = updateTimer.read_ms();
taylorza 0:bc3f11b1b41f 60 while(true)
taylorza 0:bc3f11b1b41f 61 {
taylorza 0:bc3f11b1b41f 62 int reading = updateTimer.read_ms();
taylorza 0:bc3f11b1b41f 63 if (reading - lastReading > 16)
taylorza 0:bc3f11b1b41f 64 {
taylorza 0:bc3f11b1b41f 65 if (_delay > 0) --_delay;
taylorza 0:bc3f11b1b41f 66 if (_sound > 0) --_sound;
taylorza 0:bc3f11b1b41f 67 lastReading = reading;
taylorza 0:bc3f11b1b41f 68 }
taylorza 0:bc3f11b1b41f 69 wait_us(1500);
taylorza 0:bc3f11b1b41f 70 if (_sound != 0) led1 != led1;
taylorza 0:bc3f11b1b41f 71 switch(_memory[_pc] & 0xf0)
taylorza 0:bc3f11b1b41f 72 {
taylorza 0:bc3f11b1b41f 73 case 0x00:
taylorza 0:bc3f11b1b41f 74 switch(_memory[_pc + 1])
taylorza 0:bc3f11b1b41f 75 {
taylorza 0:bc3f11b1b41f 76 case 0xe0:
taylorza 0:bc3f11b1b41f 77 _bmp.clear();
taylorza 0:bc3f11b1b41f 78 _screen.clearScreen();
taylorza 0:bc3f11b1b41f 79 break;
taylorza 0:bc3f11b1b41f 80
taylorza 0:bc3f11b1b41f 81 case 0xee:
taylorza 0:bc3f11b1b41f 82 _pc = _stack[--_sp];
taylorza 0:bc3f11b1b41f 83 break;
taylorza 0:bc3f11b1b41f 84 }
taylorza 0:bc3f11b1b41f 85 break;
taylorza 0:bc3f11b1b41f 86
taylorza 0:bc3f11b1b41f 87 case 0x10:
taylorza 0:bc3f11b1b41f 88 _pc = ((_memory[_pc] & 0x0f) << 8) | _memory[_pc + 1];
taylorza 0:bc3f11b1b41f 89 continue;
taylorza 0:bc3f11b1b41f 90
taylorza 0:bc3f11b1b41f 91 case 0x20:
taylorza 0:bc3f11b1b41f 92 _stack[_sp++] = _pc;
taylorza 0:bc3f11b1b41f 93 _pc = ((_memory[_pc] & 0x0f) << 8) | _memory[_pc + 1];
taylorza 0:bc3f11b1b41f 94 continue;
taylorza 0:bc3f11b1b41f 95
taylorza 0:bc3f11b1b41f 96 case 0x30:
taylorza 0:bc3f11b1b41f 97 if (_registers[_memory[_pc] & 0x0f] == _memory[_pc + 1])
taylorza 0:bc3f11b1b41f 98 {
taylorza 0:bc3f11b1b41f 99 _pc += 2;
taylorza 0:bc3f11b1b41f 100 }
taylorza 0:bc3f11b1b41f 101 break;
taylorza 0:bc3f11b1b41f 102
taylorza 0:bc3f11b1b41f 103 case 0x40:
taylorza 0:bc3f11b1b41f 104 if (_registers[_memory[_pc] & 0x0f] != _memory[_pc + 1])
taylorza 0:bc3f11b1b41f 105 {
taylorza 0:bc3f11b1b41f 106 _pc += 2;
taylorza 0:bc3f11b1b41f 107 }
taylorza 0:bc3f11b1b41f 108 break;
taylorza 0:bc3f11b1b41f 109
taylorza 0:bc3f11b1b41f 110 case 0x50:
taylorza 0:bc3f11b1b41f 111 if (_registers[_memory[_pc] & 0x0f] == _registers[(_memory[_pc + 1] & 0x0f) >> 4])
taylorza 0:bc3f11b1b41f 112 {
taylorza 0:bc3f11b1b41f 113 _pc += 2;
taylorza 0:bc3f11b1b41f 114 }
taylorza 0:bc3f11b1b41f 115 break;
taylorza 0:bc3f11b1b41f 116
taylorza 0:bc3f11b1b41f 117 case 0x60:
taylorza 0:bc3f11b1b41f 118 _registers[_memory[_pc] & 0x0f] = _memory[_pc + 1];
taylorza 0:bc3f11b1b41f 119 break;
taylorza 0:bc3f11b1b41f 120
taylorza 0:bc3f11b1b41f 121 case 0x70:
taylorza 0:bc3f11b1b41f 122 _registers[_memory[_pc] & 0x0f] += _memory[_pc + 1];
taylorza 0:bc3f11b1b41f 123 break;
taylorza 0:bc3f11b1b41f 124
taylorza 0:bc3f11b1b41f 125 case 0x80:
taylorza 0:bc3f11b1b41f 126 switch(_memory[_pc + 1] & 0x0f)
taylorza 0:bc3f11b1b41f 127 {
taylorza 0:bc3f11b1b41f 128 case 0x00: _registers[_memory[_pc] & 0x0f] = _registers[(_memory[_pc + 1] & 0xf0) >> 4]; break;
taylorza 0:bc3f11b1b41f 129 case 0x01: _registers[_memory[_pc] & 0x0f] |= _registers[(_memory[_pc + 1] & 0xf0) >> 4]; break;
taylorza 0:bc3f11b1b41f 130 case 0x02: _registers[_memory[_pc] & 0x0f] &= _registers[(_memory[_pc + 1] & 0xf0) >> 4]; break;
taylorza 0:bc3f11b1b41f 131 case 0x03: _registers[_memory[_pc] & 0x0f] ^= _registers[(_memory[_pc + 1] & 0xf0) >> 4]; break;
taylorza 0:bc3f11b1b41f 132
taylorza 0:bc3f11b1b41f 133 case 0x04:
taylorza 0:bc3f11b1b41f 134 {
taylorza 0:bc3f11b1b41f 135 uint8_t vx = _registers[_memory[_pc] & 0x0f];
taylorza 0:bc3f11b1b41f 136 uint8_t vy = _registers[(_memory[_pc + 1] & 0xf0) >> 4];
taylorza 0:bc3f11b1b41f 137 uint16_t result = vx + vy;
taylorza 0:bc3f11b1b41f 138 _registers[0x0f] = (uint8_t)(result >> 8);
taylorza 0:bc3f11b1b41f 139 _registers[_memory[_pc] & 0x0f] = (uint8_t)result;
taylorza 0:bc3f11b1b41f 140 }
taylorza 0:bc3f11b1b41f 141 break;
taylorza 0:bc3f11b1b41f 142
taylorza 0:bc3f11b1b41f 143 case 0x05:
taylorza 0:bc3f11b1b41f 144 {
taylorza 0:bc3f11b1b41f 145 uint8_t vx = _registers[_memory[_pc] & 0x0f];
taylorza 0:bc3f11b1b41f 146 uint8_t vy = _registers[(_memory[_pc + 1] & 0xf0) >> 4];
taylorza 0:bc3f11b1b41f 147 uint16_t result = vx - vy;
taylorza 0:bc3f11b1b41f 148 _registers[0x0f] = (uint8_t)(((uint8_t)(result >> 8)) + 1);
taylorza 0:bc3f11b1b41f 149 _registers[_memory[_pc] & 0x0f] = (uint8_t)result;
taylorza 0:bc3f11b1b41f 150 }
taylorza 0:bc3f11b1b41f 151 break;
taylorza 0:bc3f11b1b41f 152
taylorza 0:bc3f11b1b41f 153 case 0x06:
taylorza 0:bc3f11b1b41f 154 _registers[0x0f] = (uint8_t)(_registers[_memory[_pc] & 0x0f] & 0x01);
taylorza 0:bc3f11b1b41f 155 _registers[_memory[_pc] & 0x0f] >>= 1;
taylorza 0:bc3f11b1b41f 156 break;
taylorza 0:bc3f11b1b41f 157
taylorza 0:bc3f11b1b41f 158 case 0x07:
taylorza 0:bc3f11b1b41f 159 _registers[0x0f] = (uint8_t)(_registers[(_memory[_pc + 1] & 0xf0) >> 4] > _registers[_memory[_pc] & 0x0f] ? 1 : 0);
taylorza 0:bc3f11b1b41f 160 _registers[_memory[_pc] & 0x0f] -= _registers[(_memory[_pc + 1] & 0xf0) >> 4];
taylorza 0:bc3f11b1b41f 161 break;
taylorza 0:bc3f11b1b41f 162
taylorza 0:bc3f11b1b41f 163 case 0x0E:
taylorza 0:bc3f11b1b41f 164 _registers[0x0f] = (uint8_t)(((_registers[_memory[_pc] & 0x0f] & 0x80) != 0) ? 1 : 0);
taylorza 0:bc3f11b1b41f 165 _registers[_memory[_pc] & 0x0f] <<= 1;
taylorza 0:bc3f11b1b41f 166 break;
taylorza 0:bc3f11b1b41f 167
taylorza 0:bc3f11b1b41f 168 }
taylorza 0:bc3f11b1b41f 169 break;
taylorza 0:bc3f11b1b41f 170
taylorza 0:bc3f11b1b41f 171 case 0x90:
taylorza 0:bc3f11b1b41f 172 if (_registers[_memory[_pc] & 0x0f] != _registers[(_memory[_pc + 1] & 0xf0) >> 4])
taylorza 0:bc3f11b1b41f 173 {
taylorza 0:bc3f11b1b41f 174 _pc += 2;
taylorza 0:bc3f11b1b41f 175 }
taylorza 0:bc3f11b1b41f 176 break;
taylorza 0:bc3f11b1b41f 177
taylorza 0:bc3f11b1b41f 178 case 0xA0:
taylorza 0:bc3f11b1b41f 179 _i = (uint16_t)(((_memory[_pc] & 0x0f) << 8) | _memory[_pc + 1]);
taylorza 0:bc3f11b1b41f 180 break;
taylorza 0:bc3f11b1b41f 181
taylorza 0:bc3f11b1b41f 182 case 0xB0:
taylorza 0:bc3f11b1b41f 183 _pc = (uint16_t)((((_memory[_pc] & 0x0f) << 8) | _memory[_pc + 1]) + _registers[0]);
taylorza 0:bc3f11b1b41f 184 continue;
taylorza 0:bc3f11b1b41f 185
taylorza 0:bc3f11b1b41f 186 case 0xC0:
taylorza 0:bc3f11b1b41f 187 _registers[_memory[_pc] & 0x0f] = (uint8_t)(rnd() & _memory[_pc + 1]);
taylorza 0:bc3f11b1b41f 188 break;
taylorza 0:bc3f11b1b41f 189
taylorza 0:bc3f11b1b41f 190 case 0xD0:
taylorza 0:bc3f11b1b41f 191 {
taylorza 0:bc3f11b1b41f 192 _registers[0x0f] = 0;
taylorza 0:bc3f11b1b41f 193 uint8_t x = _registers[_memory[_pc] & 0x0f];
taylorza 0:bc3f11b1b41f 194 uint8_t y = _registers[_memory[_pc + 1] >> 4];
taylorza 0:bc3f11b1b41f 195 uint8_t n = _memory[_pc + 1] & 0x0f;
taylorza 0:bc3f11b1b41f 196 for (int i = 0; i < n; i++)
taylorza 0:bc3f11b1b41f 197 {
taylorza 0:bc3f11b1b41f 198 plot(x, y + i, _memory[_i + i]);
taylorza 0:bc3f11b1b41f 199 }
taylorza 0:bc3f11b1b41f 200 }
taylorza 0:bc3f11b1b41f 201 break;
taylorza 0:bc3f11b1b41f 202
taylorza 0:bc3f11b1b41f 203 case 0xE0:
taylorza 0:bc3f11b1b41f 204 switch(_memory[_pc+1])
taylorza 0:bc3f11b1b41f 205 {
taylorza 0:bc3f11b1b41f 206 case 0x9E :
taylorza 0:bc3f11b1b41f 207 if (isKeyPressed(_registers[_memory[_pc] & 0x0f])) _pc += 2;
taylorza 0:bc3f11b1b41f 208 break;
taylorza 0:bc3f11b1b41f 209
taylorza 0:bc3f11b1b41f 210 case 0xA1 :
taylorza 0:bc3f11b1b41f 211 if (!isKeyPressed(_registers[_memory[_pc] & 0x0f])) _pc += 2;
taylorza 0:bc3f11b1b41f 212 break;
taylorza 0:bc3f11b1b41f 213 }
taylorza 0:bc3f11b1b41f 214 break;
taylorza 0:bc3f11b1b41f 215
taylorza 0:bc3f11b1b41f 216 case 0xF0:
taylorza 0:bc3f11b1b41f 217 switch (_memory[_pc + 1])
taylorza 0:bc3f11b1b41f 218 {
taylorza 0:bc3f11b1b41f 219 case 0x07:
taylorza 0:bc3f11b1b41f 220 _registers[_memory[_pc] & 0x0f] = _delay;
taylorza 0:bc3f11b1b41f 221 break;
taylorza 0:bc3f11b1b41f 222
taylorza 0:bc3f11b1b41f 223 case 0x0A:
taylorza 0:bc3f11b1b41f 224 {
taylorza 0:bc3f11b1b41f 225 uint8_t key = getKeyPressed();
taylorza 0:bc3f11b1b41f 226 if (key != 255)
taylorza 0:bc3f11b1b41f 227 {
taylorza 0:bc3f11b1b41f 228 _registers[_memory[_pc] & 0x0f] = key;
taylorza 0:bc3f11b1b41f 229 }
taylorza 0:bc3f11b1b41f 230 else
taylorza 0:bc3f11b1b41f 231 {
taylorza 0:bc3f11b1b41f 232 _pc -= 2;
taylorza 0:bc3f11b1b41f 233 }
taylorza 0:bc3f11b1b41f 234 }
taylorza 0:bc3f11b1b41f 235 break;
taylorza 0:bc3f11b1b41f 236
taylorza 0:bc3f11b1b41f 237 case 0x15:
taylorza 0:bc3f11b1b41f 238 _delay = _registers[_memory[_pc] & 0x0f];
taylorza 0:bc3f11b1b41f 239 break;
taylorza 0:bc3f11b1b41f 240
taylorza 0:bc3f11b1b41f 241 case 0x18:
taylorza 0:bc3f11b1b41f 242 _sound = _registers[_memory[_pc] & 0x0f];
taylorza 0:bc3f11b1b41f 243 break;
taylorza 0:bc3f11b1b41f 244
taylorza 0:bc3f11b1b41f 245 case 0x1e:
taylorza 0:bc3f11b1b41f 246 _i += _registers[_memory[_pc] & 0x0f];
taylorza 0:bc3f11b1b41f 247 break;
taylorza 0:bc3f11b1b41f 248
taylorza 0:bc3f11b1b41f 249 case 0x29:
taylorza 0:bc3f11b1b41f 250 _i = (uint8_t)(_registers[_memory[_pc] & 0x0f] * 5);
taylorza 0:bc3f11b1b41f 251 break;
taylorza 0:bc3f11b1b41f 252
taylorza 0:bc3f11b1b41f 253 case 0x33:
taylorza 0:bc3f11b1b41f 254 {
taylorza 0:bc3f11b1b41f 255 uint8_t r = _registers[_memory[_pc] & 0x0f];
taylorza 0:bc3f11b1b41f 256 _memory[_i + 2] = (uint8_t)(r % 10);
taylorza 0:bc3f11b1b41f 257 r /= 10;
taylorza 0:bc3f11b1b41f 258 _memory[_i + 1] = (uint8_t)(r % 10);
taylorza 0:bc3f11b1b41f 259 r /= 10;
taylorza 0:bc3f11b1b41f 260 _memory[_i] = (uint8_t)(r % 10);
taylorza 0:bc3f11b1b41f 261 }
taylorza 0:bc3f11b1b41f 262 break;
taylorza 0:bc3f11b1b41f 263
taylorza 0:bc3f11b1b41f 264 case 0x55:
taylorza 0:bc3f11b1b41f 265 {
taylorza 0:bc3f11b1b41f 266 uint8_t n = _memory[_pc] & 0x0f;
taylorza 0:bc3f11b1b41f 267 for (int r = 0; r <= n; r++)
taylorza 0:bc3f11b1b41f 268 {
taylorza 0:bc3f11b1b41f 269 _memory[_i + r] = _registers[r];
taylorza 0:bc3f11b1b41f 270 }
taylorza 0:bc3f11b1b41f 271 }
taylorza 0:bc3f11b1b41f 272 break;
taylorza 0:bc3f11b1b41f 273
taylorza 0:bc3f11b1b41f 274 case 0x65:
taylorza 0:bc3f11b1b41f 275 {
taylorza 0:bc3f11b1b41f 276 uint8_t n = _memory[_pc] & 0x0f;
taylorza 0:bc3f11b1b41f 277 for (int r = 0; r <= n; r++)
taylorza 0:bc3f11b1b41f 278 {
taylorza 0:bc3f11b1b41f 279 _registers[r] = _memory[_i + r];
taylorza 0:bc3f11b1b41f 280 }
taylorza 0:bc3f11b1b41f 281 }
taylorza 0:bc3f11b1b41f 282 break;
taylorza 0:bc3f11b1b41f 283 }
taylorza 0:bc3f11b1b41f 284 break;
taylorza 0:bc3f11b1b41f 285 }
taylorza 0:bc3f11b1b41f 286
taylorza 0:bc3f11b1b41f 287 _pc += 2;
taylorza 0:bc3f11b1b41f 288 if (_pc >= sizeof(_memory))
taylorza 0:bc3f11b1b41f 289 {
taylorza 0:bc3f11b1b41f 290 _pc = 0x200 + (sizeof(_memory) - _pc - 1);
taylorza 0:bc3f11b1b41f 291 }
taylorza 0:bc3f11b1b41f 292 }
taylorza 0:bc3f11b1b41f 293 }
taylorza 0:bc3f11b1b41f 294
taylorza 0:bc3f11b1b41f 295 uint8_t Chip8Emulator::rnd()
taylorza 0:bc3f11b1b41f 296 {
taylorza 0:bc3f11b1b41f 297 return (uint8_t)(rand() % 256);
taylorza 0:bc3f11b1b41f 298 }
taylorza 0:bc3f11b1b41f 299
taylorza 0:bc3f11b1b41f 300 bool Chip8Emulator::isKeyPressed(uint8_t key)
taylorza 0:bc3f11b1b41f 301 {
taylorza 0:bc3f11b1b41f 302 return getKeyPressed() == key;
taylorza 0:bc3f11b1b41f 303 }
taylorza 0:bc3f11b1b41f 304
taylorza 0:bc3f11b1b41f 305 uint8_t Chip8Emulator::getKeyPressed()
taylorza 0:bc3f11b1b41f 306 {
taylorza 0:bc3f11b1b41f 307 if (GameInput::isLeftPressed()) return _leftKey;
taylorza 0:bc3f11b1b41f 308 if (GameInput::isRightPressed()) return _rightKey;
taylorza 0:bc3f11b1b41f 309 if (GameInput::isUpPressed()) return _upKey;
taylorza 0:bc3f11b1b41f 310 if (GameInput::isDownPressed()) return _downKey;
taylorza 0:bc3f11b1b41f 311 if (GameInput::isCirclePressed()) return _fireKey;
taylorza 0:bc3f11b1b41f 312 if (GameInput::isSquarePressed()) return _startKey;
taylorza 0:bc3f11b1b41f 313
taylorza 0:bc3f11b1b41f 314 return 255;
taylorza 0:bc3f11b1b41f 315 }
taylorza 0:bc3f11b1b41f 316
taylorza 0:bc3f11b1b41f 317 void Chip8Emulator::plot(int x, int y, uint8_t pattern)
taylorza 0:bc3f11b1b41f 318 {
taylorza 0:bc3f11b1b41f 319 if (y >= 32) return;
taylorza 0:bc3f11b1b41f 320 for (int i = 0; i < 8; ++i)
taylorza 0:bc3f11b1b41f 321 {
taylorza 0:bc3f11b1b41f 322 if (x + i >= 64) return;
taylorza 0:bc3f11b1b41f 323
taylorza 0:bc3f11b1b41f 324 uint16_t set = ((pattern << i) & 0x80) != 0 ? 1 : 0;
taylorza 0:bc3f11b1b41f 325 uint16_t current = _bmp.getPixel(x + i, y);
taylorza 0:bc3f11b1b41f 326
taylorza 0:bc3f11b1b41f 327 if ((set & current) != 0) _registers[0x0f] = 1;
taylorza 0:bc3f11b1b41f 328
taylorza 0:bc3f11b1b41f 329 _bmp.setPixel(x + i, y, current ^ set);
taylorza 0:bc3f11b1b41f 330
taylorza 0:bc3f11b1b41f 331 int nx = OFFSET_X + (x + i) * 2;
taylorza 0:bc3f11b1b41f 332 int ny = OFFSET_Y + (y * 2);
taylorza 0:bc3f11b1b41f 333 _screen.fillRect(nx, ny, nx + 1, ny + 1, current ^ set ? Color565::White : Color565::Black);
taylorza 0:bc3f11b1b41f 334 }
taylorza 0:bc3f11b1b41f 335 }