Emulation of the 1970's Chip-8 machine. The emulator has 7 games that are unmodified from the original Chip-8 format.
Chip8Emulator.cpp@0:bc3f11b1b41f, 2015-02-08 (annotated)
- Committer:
- taylorza
- Date:
- Sun Feb 08 01:58:57 2015 +0000
- Revision:
- 0:bc3f11b1b41f
Chip-8 Emulator
Who changed what in which revision?
User | Revision | Line number | New 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 | } |