diff --git a/atari2600.cpp b/atari2600.cpp index 22010c6..567a0e4 100644 --- a/atari2600.cpp +++ b/atari2600.cpp @@ -44,7 +44,11 @@ namespace atari2600 // } else { bool instruction_done = false; while (!instruction_done) { - instruction_done = m6502::tick(); + if (!tia::is_rdy_low()) { + instruction_done = m6502::tick(); + } else { + instruction_done = true; + } tia::tick(); tia::tick(); tia::tick(); diff --git a/tia.cpp b/tia.cpp index 01fdcb1..23d82b7 100644 --- a/tia.cpp +++ b/tia.cpp @@ -2,6 +2,24 @@ namespace tia { + uint8_t collisions[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; + + float paddle_pos[4] { 0.5f, 0.5f, 0.5f, 0.5f }; + uint32_t paddle_charge_cycles[4] { 0, 0, 0, 0 }; + + bool joy0_button_pressed = false; + bool joy1_button_pressed = false; + + uint32_t current_frame_cycles = 0; + + bool vsync_set = false; + bool vblank_set = false; + bool vblank_latch = false; + bool vblank_dump = false; + + uint16_t color_clock = 0; + bool rdy_low = false; + void reset() { @@ -9,14 +27,41 @@ namespace tia void tick() { + if (!vblank_dump) current_frame_cycles++; + color_clock = (color_clock + 1) % 228; + if (color_clock == 0) rdy_low = false; + + // [TODO] Pintar pixels + } + + + uint8_t get_paddle_state(int index) + { + if (vblank_dump) return 0x00; + return (current_frame_cycles >= paddle_charge_cycles[index]) ? 0x80 : 0x00; } uint8_t read(uint16_t address) { - address &= 0x0f; + switch (address & 0x0f) { + case 0x00: return collisions[0]; + case 0x01: return collisions[2]; + case 0x02: return collisions[3]; + case 0x03: return collisions[4]; + case 0x04: return collisions[5]; + case 0x05: return collisions[6]; + case 0x06: return collisions[7]; + case 0x07: return collisions[8]; - // [TODO] Procesar segons l'adreça resultant + case 0x08: return get_paddle_state(0); + case 0x09: return get_paddle_state(1); + case 0x0A: return get_paddle_state(2); + case 0x0B: return get_paddle_state(3); + + case 0x0C: return joy0_button_pressed ? 0x00 : 0x80; + case 0x0D: return joy1_button_pressed ? 0x00 : 0x80; + } } void write(uint16_t address, uint8_t value) @@ -25,6 +70,34 @@ namespace tia if (address >= 0x2d) address -= 0x20; // [TODO] Procesar segons l'adreça resultant + switch (address) { + case 0x00: // VSYNC + vsync_set = value & 0x20; + break; + + case 0x01: // VBLANK + bool prev_dump = vblank_dump; + vblank_set = value & 0x20; + vblank_latch = value & 0x40; + vblank_dump = value & 0x80; + if (prev_dump && !vblank_dump) { + current_frame_cycles = 0; + for (int i = 0; i < 4; ++i) paddle_charge_cycles[i] = static_cast(paddle_pos[i] * 2400.0f); + } + break; + + case 0x02: // WSYNC + rdy_low = true; + break; + + case 0x03: // RSYNC + color_clock = 0; + break; + } } + bool is_rdy_low() + { + return rdy_low; + } } diff --git a/tia.h b/tia.h index 0c4605e..464ac49 100644 --- a/tia.h +++ b/tia.h @@ -7,4 +7,6 @@ namespace tia void tick(); uint8_t read(uint16_t address); void write(uint16_t address, uint8_t value); + + bool is_rdy_low(); }