Этот сайт использует файлы cookies. Продолжая просмотр страниц сайта, вы соглашаетесь с использованием файлов cookies. Если вам нужна дополнительная информация, пожалуйста, посетите страницу Политика файлов Cookie
Subscribe
Прямой эфир
Cryptocurrencies: 8192 / Markets: 112938
Market Cap: $ 2 061 433 945 644 / 24h Vol: $ 94 435 845 989 / BTC Dominance: 58.073579585229%

Н Новости

Программист & LLM: как написать эмулятор ретро-компьютера за четыре вечера. Часть 1, вводная

Тон данной публикации задал товарищ @kiltum в своих статьях, начатых с этой. В самом начале был задан вопрос

может ли ИИ заменить программиста?

А действительно? Сколько вокруг этой темы хайпа, нет ни дня чтобы здесь на ресурсе не появилось 100500 статей на тему нейросетей, LLM, ML и прочего. Пишут много и всякое. Возникло желание проверить лично, насколько решения, предлагаемые ИИ могут быть воплощены в жизнь.

Системы ИИ прочно вошли в нашу жизнь, и да, я тоже ими регулярно пользуюсь. Но мысли программировать с их помощью особо не возникало. Но что если попробовать, поставив при этом задачу из предметной области в которой ты не особо разбираешься? Похожий вопрос ставит и @kiltum, но я хочу попросить автора не ругаться на мою невольную попытку "пообезьянничать". Своей публикацией я лишь хочу подкрепить уже высказанные тезисы, на примере личного опыта. К тому же, старое железо - это всегда интересно, не правда ли? Если так, то добро пожаловать под кат.

1. Исходные данные

Чего хотим? Реализовать архитектуру на базе Z80 - довольно банальная история. Такие системы были популярны в нашей стране (ZX Spectrum, MSX). Сам в школе начинал с Yamaha MSX. К тому же Z80 - довольно таки сложный процессор. Чтобы не тратить время, лучше реализовать что-то попроще, например... MOS 6502. Очень простой процессор - набор команд всего 56 инструкций, вместе со всеми режимами адресации дающий 151 вариант выполнения. Длина инструкций - от одно до трех байт. Данный чип послужил основой для таких систем как Apple I/II, Famicom/NES и... Commodor 64. Вот на последнем я и остановился, в виду не особой распространенности этой системы на постсоветском пространстве.

Существуют ли эмуляторы Commodor 64? Конечно, например VICE. Опенсорцный, кроссплатформенный. Ссылки на репозиторий не даю - я сам не смотрел, из спортивного интереса, желая решить все задачи путем запросов к LLM, чтения документации и собственных раздумий.

Итак, Commodor 64 - домашний компьютер на базе процессора MOS 6510 (модификация MOS 6502, разницу обсудим ниже), с 64 кб оперативной памяти и 20 кб ПЗУ. Как и все 8-битные компьютеры того времени, имел на борту интерпретатор BASIC в качестве OS и и основного средства разработки. Умел, как и ZX Spectrum, читать программы с кассет, для чего в комплекте шел оригинальный магнитофон. Умел запускать программы с ROM-картриджей. Судя по фото ниже, имел он и дисковод на 5,25'', да и всякой периферии к нему выходило не мало, благо машина разошлась по миру тиражом аж в 15 млн. штук.

Пациент в естественной среде обитания
Пациент в естественной среде обитания

Кроме процессора 6510, на борту трудились видеоконтроллер MOS Technology VIC-II и звуковой чип MOS Technology SID, что делало машинку, в купе большим для того времени объемом ОЗУ, достаточно хорошей развлекательной мультимедийной системой. Машина увидела свет в 1982 году, так что он еще и мой ровесник. На этом довольно истории, на ресурсе есть масса статей и о Commodor 64 (далее C64), и о компании его производившей, и о Джеке Трэмеле. За историей отсылаю к википедии и прочим источникам.

Что до LLM, то выбор пал на бесплатные системы, типа Deepseek или Qwen, остановившись на последней, опять таки в целях ее испытания.

Что же касается реализации, то тут выбор для очевидный - C++, как наиболее часто используемый мною язык. И желательно без особенных зависимостей. Без зависимостей, конечно не обойтись, и вопрос их выбора менялся в зависимости от контекста продвижения по задаче. Итак, начнем...

2. Эмуляция ядра MOS 6502: консультируемся с LLM

Первый промпт был предельно прост

эмулятор mos6502 на c++

на что, после немногословного пояснения был выдан следующий код

mos6502.cpp
#include <iostream>
#include <vector>
#include <cstdint>

class MOS6502 {
public:
    // Регистры
    uint8_t A, X, Y, SP, P;
    uint16_t PC;

    // Память (64 КБ)
    std::vector<uint8_t> memory = std::vector<uint8_t>(0x10000, 0);

    // Флаги
    enum {
        C = 0x01, Z = 0x02, I = 0x04, D = 0x08,
        B = 0x10, R = 0x20, V = 0x40, N = 0x80
    };

    MOS6502() {
        reset();
    }

    void reset() {
        PC = read16(0xFFFC);  // Адрес сброса
        SP = 0xFD;
        P = I;
        A = X = Y = 0;
    }

    uint8_t read(uint16_t addr) {
        return memory[addr];
    }

    void write(uint16_t addr, uint8_t value) {
        memory[addr] = value;
    }

    uint16_t read16(uint16_t addr) {
        return read(addr) | (read(addr + 1) << 8);
    }

    void setFlag(uint8_t flag, bool value) {
        if (value) P |= flag; else P &= ~flag;
    }

    bool getFlag(uint8_t flag) {
        return (P & flag) != 0;
    }

    uint8_t fetch() {
        return read(PC++);
    }

    void executeInstruction() {
        uint8_t opcode = fetch();

        switch (opcode) {
            case 0xA9: { // LDA Immediate
                uint8_t value = fetch();
                A = value;
                setFlag(Z, A == 0);
                setFlag(N, A & 0x80);
                break;
            }
            case 0xAD: { // LDA Absolute
                uint16_t addr = read16(PC);
                PC += 2;
                A = read(addr);
                setFlag(Z, A == 0);
                setFlag(N, A & 0x80);
                break;
            }
            case 0x69: { // ADC Immediate
                uint8_t value = fetch();
                uint16_t result = A + value + (getFlag(C) ? 1 : 0);
                setFlag(C, result > 0xFF);
                setFlag(V, (~(A ^ value) & (A ^ result)) & 0x80);
                A = result & 0xFF;
                setFlag(Z, A == 0);
                setFlag(N, A & 0x80);
                break;
            }
            case 0x4C: { // JMP Absolute
                PC = read16(PC);
                break;
            }
            case 0x20: { // JSR
                uint16_t addr = read16(PC);
                PC += 2;
                push16(PC - 1);
                PC = addr;
                break;
            }
            case 0x60: { // RTS
                PC = pop16() + 1;
                break;
            }
            default:
                std::cout << "Unknown opcode: 0x" << std::hex << (int)opcode << "\n";
                exit(1);
        }
    }

    void push(uint8_t value) {
        write(0x0100 + SP, value);
        SP--;
    }

    void push16(uint16_t value) {
        push((value >> 8) & 0xFF);
        push(value & 0xFF);
    }

    uint8_t pop() {
        SP++;
        return read(0x0100 + SP);
    }

    uint16_t pop16() {
        uint8_t low = pop();
        uint8_t high = pop();
        return low | (high << 8);
    }
};

int main() {
    MOS6502 cpu;

    // Пример: загрузить программу в память
    // Программа: LDA #$01; ADC #$02; JMP $8000
    cpu.memory[0x8000] = 0xA9; // LDA #$01
    cpu.memory[0x8001] = 0x01;
    cpu.memory[0x8002] = 0x69; // ADC #$02
    cpu.memory[0x8003] = 0x02;
    cpu.memory[0x8004] = 0x4C; // JMP $8000
    cpu.memory[0x8005] = 0x00;
    cpu.memory[0x8006] = 0x80;

    cpu.PC = 0x8000;

    for (int i = 0; i < 10; i++) {
        cpu.executeInstruction();
        std::cout << "A: " << std::hex << (int)cpu.A << std::endl;
    }

    return 0;
}

Однако, эмулятор процессора из 148 строчек кода (вообще есть полноценные эмуляторы и меньшего размера, написанные на C, но это явно не мой случай...). Не принимая на веру, начинаем анализировать выданное нам решение. Что мы тут видим?

  1. Реализация процессора как отдельного класса

  2. Регистры, как переменные класса соответствующей разрядности, память - как линейный массив байт объемом 64 кб.

  3. Реализация работы с регистрами и флагами, обращения к памяти, работы со стеком

  4. Пример декодирования некоторых инструкций

  5. Демка, с принудительным помещением машинного кода в память и его выполнение, без учета тактовой частоты, числа тактов на команду.

В общем что просили то нам и дали. Не следует думать, что ИИ способен решить за нас задачу. Иногда он недоговаривает или откровенно врет, поэтому первое правило разработчика, решившего использовать ИИ в своей работе - тотальная проверка и анализ выданных результатов.

Ок, начинать конечно нужно с малого, и простейший эмулятор MOS 6502 нас устроит, но хочется большего, поэтому уточняем вопрос, предварительно ознакомившись с выводами нашего помощника и его предложениями, например

Если тебе нужна реализация с поддержкой NES, с полным набором инструкций, или с отладчиком — могу дать более продвинутый пример.

NES, разумеется, нас не интересует а вот это

реализовать точное количество тактов

пригодилось бы. Смотрим ответ на запрос

mos6502_cycles.cpp
#include <iostream>
#include <vector>
#include <cstdint>

class MOS6502 {
public:
    uint8_t A, X, Y, SP, P;
    uint16_t PC;
    int cycles = 0; // Общее количество тактов

    std::vector<uint8_t> memory = std::vector<uint8_t>(0x10000, 0);

    // Флаги
    enum {
        C = 0x01, Z = 0x02, I = 0x04, D = 0x08,
        B = 0x10, R = 0x20, V = 0x40, N = 0x80
    };

    MOS6502() {
        reset();
    }

    void reset() {
        PC = read16(0xFFFC);
        SP = 0xFD;
        P = I;
        A = X = Y = 0;
        cycles = 0;
    }

    uint8_t read(uint16_t addr) {
        cycles++; // Каждое чтение занимает 1 такт
        return memory[addr];
    }

    void write(uint16_t addr, uint8_t value) {
        cycles++; // Каждая запись — 1 такт
        memory[addr] = value;
    }

    uint16_t read16(uint16_t addr) {
        return read(addr) | (read(addr + 1) << 8);
    }

    void setFlag(uint8_t flag, bool value) {
        if (value) P |= flag; else P &= ~flag;
    }

    bool getFlag(uint8_t flag) {
        return (P & flag) != 0;
    }

    uint8_t fetch() {
        return read(PC++);
    }

    // --- Адресация ---
    uint16_t addr_abs = 0;
    uint16_t addr_rel = 0;
    uint8_t fetched = 0;

    uint8_t fetchOperand() {
        fetched = read(addr_abs);
        return fetched;
    }

    // --- Стандартная таблица тактов ---
    static const int cycle_table[256] = {
    //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
        7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, // 0
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 1
        6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, // 2
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 3
        6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, // 4
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 5
        6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, // 6
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 7
        2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // 8
        2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, // 9
        2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // A
        2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, // B
        2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // C
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // D
        2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // E
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7  // F
    };

    int executeInstruction() {
        uint8_t opcode = fetch();
        int base_cycles = cycle_table[opcode];

        switch (opcode) {
            case 0xA9: // LDA Immediate
                addr_abs = PC++;
                A = read(addr_abs);
                setFlag(Z, A == 0);
                setFlag(N, A & 0x80);
                break;
            case 0xAD: // LDA Absolute
                addr_abs = read16(PC);
                PC += 2;
                A = read(addr_abs);
                setFlag(Z, A == 0);
                setFlag(N, A & 0x80);
                break;
            case 0x69: // ADC Immediate
                addr_abs = PC++;
                fetched = read(addr_abs);
                uint16_t temp = A + fetched + (getFlag(C) ? 1 : 0);
                setFlag(C, temp > 0xFF);
                setFlag(V, (~(A ^ fetched) & (A ^ temp)) & 0x80);
                A = temp & 0xFF;
                setFlag(Z, A == 0);
                setFlag(N, A & 0x80);
                break;
            case 0x4C: // JMP Absolute
                PC = read16(PC);
                break;
            case 0x20: // JSR
                addr_abs = read16(PC);
                PC += 2;
                push16(PC - 1);
                PC = addr_abs;
                break;
            case 0x60: // RTS
                PC = pop16() + 1;
                break;
            // Пример с условным переходом (BNE), может быть +1 такт
            case 0xD0: { // BNE
                int8_t offset = (int8_t)fetch();
                addr_rel = PC + offset;
                bool taken = !getFlag(Z);
                if (taken) {
                    cycles++; // +1 если переход
                    if ((PC & 0xFF00) != (addr_rel & 0xFF00)) {
                        cycles++; // +1 если страница пересекается
                    }
                    PC = addr_rel;
                }
                break;
            }
            default:
                std::cout << "Unknown opcode: 0x" << std::hex << (int)opcode << "\n";
                exit(1);
        }

        cycles += base_cycles;
        return base_cycles;
    }

    void push(uint8_t value) {
        write(0x0100 + SP, value);
        SP--;
    }

    void push16(uint16_t value) {
        push((value >> 8) & 0xFF);
        push(value & 0xFF);
    }

    uint8_t pop() {
        SP++;
        return read(0x0100 + SP);
    }

    uint16_t pop16() {
        uint8_t low = pop();
        uint8_t high = pop();
        return low | (high << 8);
    }
};

int main() {
    MOS6502 cpu;

    // Пример программы
    cpu.memory[0x8000] = 0xA9; cpu.memory[0x8001] = 0x01; // LDA #$01
    cpu.memory[0x8002] = 0x69; cpu.memory[0x8003] = 0x02; // ADC #$02
    cpu.memory[0x8004] = 0x4C; cpu.memory[0x8005] = 0x00; cpu.memory[0x8006] = 0x80; // JMP $8000

    cpu.PC = 0x8000;

    for (int i = 0; i < 10; i++) {
        int c = cpu.executeInstruction();
        std::cout << "Cycles: " << cpu.cycles << ", A: " << std::hex << (int)cpu.A << std::endl;
    }

    return 0;
}

Ага, почти такой же пример, но с добавками, а конкретно, теперь каждой инструкции приписано число тактов ее выполнения, которые сведены в массив, с индексацией по коду операции (опкоду)

// --- Стандартная таблица тактов ---
    static const int cycle_table[256] = {
    //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
        7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, // 0
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 1
        6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, // 2
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 3
        6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, // 4
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 5
        6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, // 6
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 7
        2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // 8
        2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, // 9
        2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // A
        2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, // B
        2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // C
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // D
        2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // E
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7  // F
    };

Кроме того, число исполненных тактов учитывается при чтении и записи в память

uint8_t read(uint16_t addr) {
        cycles++; // Каждое чтение занимает 1 такт
        return memory[addr];
    }

    void write(uint16_t addr, uint8_t value) {
        cycles++; // Каждая запись — 1 такт
        memory[addr] = value;
    }

а при декодировании инструкций к ним добавляется число тактов необходимое для конкретной команды. В демо-примере выводится число тактов, потраченных на исполнение программы. Наверное так и должно быть, пока примем на веру.

Не удовлетворившись результатами, идем дальше, задав такой вопрос

все 56 инструкций с точным счётом тактов

на что получаем уже более массивный ответ

mos6502.cpp
#include <iostream>
#include <vector>
#include <cstdint>

class MOS6502 {
public:
    uint8_t A, X, Y, SP, P;
    uint16_t PC;
    int cycles = 0;

    std::vector<uint8_t> memory = std::vector<uint8_t>(0x10000, 0);

    // Флаги
    enum {
        C = 0x01, Z = 0x02, I = 0x04, D = 0x08,
        B = 0x10, R = 0x20, V = 0x40, N = 0x80
    };

    // Вспомогательные переменные для адресации
    uint16_t addr_abs = 0;
    uint16_t addr_rel = 0;
    uint8_t fetched = 0;

    // Таблица базовых тактов
    static const int cycle_table[256] = {
    //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
        7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, // 0
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 1
        6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, // 2
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 3
        6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, // 4
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 5
        6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, // 6
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 7
        2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // 8
        2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, // 9
        2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // A
        2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, // B
        2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // C
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // D
        2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // E
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7  // F
    };

    MOS6502() {
        reset();
    }

    void reset() {
        PC = read16(0xFFFC);
        SP = 0xFD;
        P = I;
        A = X = Y = 0;
        cycles = 0;
    }

    uint8_t read(uint16_t addr) {
        cycles++;
        return memory[addr];
    }

    void write(uint16_t addr, uint8_t value) {
        cycles++;
        memory[addr] = value;
    }

    uint16_t read16(uint16_t addr) {
        return read(addr) | (read(addr + 1) << 8);
    }

    void setFlag(uint8_t flag, bool value) {
        if (value) P |= flag; else P &= ~flag;
    }

    bool getFlag(uint8_t flag) {
        return (P & flag) != 0;
    }

    uint8_t fetch() {
        return read(PC++);
    }

    uint8_t fetchOperand() {
        fetched = read(addr_abs);
        return fetched;
    }

    void writeAddr(uint16_t addr, uint8_t value) {
        write(addr, value);
    }

    // --- Адресация ---
    void addr_immediate() {
        addr_abs = PC++;
    }

    void addr_zero_page() {
        addr_abs = fetch();
    }

    void addr_zero_page_x() {
        addr_abs = (fetch() + X) & 0xFF;
    }

    void addr_zero_page_y() {
        addr_abs = (fetch() + Y) & 0xFF;
    }

    void addr_absolute() {
        addr_abs = read16(PC);
        PC += 2;
    }

    void addr_absolute_x() {
        addr_abs = read16(PC) + X;
        PC += 2;
    }

    void addr_absolute_y() {
        addr_abs = read16(PC) + Y;
        PC += 2;
    }

    void addr_indirect_x() {
        uint16_t ptr = (fetch() + X) & 0xFF;
        addr_abs = read16(ptr);
    }

    void addr_indirect_y() {
        uint16_t ptr = fetch();
        addr_abs = read16(ptr) + Y;
    }

    void addr_relative() {
        addr_rel = fetch();
        if (addr_rel & 0x80) addr_rel |= 0xFF00; // Знаковое расширение
    }

    // --- Инструкции ---
    int ADC() {
        fetchOperand();
        uint16_t temp = A + fetched + (getFlag(C) ? 1 : 0);
        setFlag(C, temp > 0xFF);
        setFlag(V, (~(A ^ fetched) & (A ^ temp)) & 0x80);
        A = temp & 0xFF;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int SBC() {
        fetchOperand();
        uint16_t temp = A - fetched - (getFlag(C) ? 0 : 1);
        setFlag(C, temp < 0x100);
        setFlag(V, ((A ^ temp) & (fetched ^ A)) & 0x80);
        A = temp & 0xFF;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int AND() {
        fetchOperand();
        A &= fetched;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int EOR() {
        fetchOperand();
        A ^= fetched;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int ORA() {
        fetchOperand();
        A |= fetched;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int CMP() {
        fetchOperand();
        uint16_t temp = A - fetched;
        setFlag(C, A >= fetched);
        setFlag(Z, temp == 0);
        setFlag(N, temp & 0x80);
        return 0;
    }

    int CPX() {
        uint8_t value = read(addr_abs);
        uint16_t temp = X - value;
        setFlag(C, X >= value);
        setFlag(Z, temp == 0);
        setFlag(N, temp & 0x80);
        return 0;
    }

    int CPY() {
        uint8_t value = read(addr_abs);
        uint16_t temp = Y - value;
        setFlag(C, Y >= value);
        setFlag(Z, temp == 0);
        setFlag(N, temp & 0x80);
        return 0;
    }

    int DEC() {
        uint8_t value = read(addr_abs);
        value--;
        writeAddr(addr_abs, value);
        setFlag(Z, value == 0);
        setFlag(N, value & 0x80);
        return 0;
    }

    int DEX() {
        X--;
        setFlag(Z, X == 0);
        setFlag(N, X & 0x80);
        return 0;
    }

    int DEY() {
        Y--;
        setFlag(Z, Y == 0);
        setFlag(N, Y & 0x80);
        return 0;
    }

    int INC() {
        uint8_t value = read(addr_abs);
        value++;
        writeAddr(addr_abs, value);
        setFlag(Z, value == 0);
        setFlag(N, value & 0x80);
        return 0;
    }

    int INX() {
        X++;
        setFlag(Z, X == 0);
        setFlag(N, X & 0x80);
        return 0;
    }

    int INY() {
        Y++;
        setFlag(Z, Y == 0);
        setFlag(N, Y & 0x80);
        return 0;
    }

    int LDA() {
        fetchOperand();
        A = fetched;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int LDX() {
        fetchOperand();
        X = fetched;
        setFlag(Z, X == 0);
        setFlag(N, X & 0x80);
        return 0;
    }

    int LDY() {
        fetchOperand();
        Y = fetched;
        setFlag(Z, Y == 0);
        setFlag(N, Y & 0x80);
        return 0;
    }

    int STA() {
        writeAddr(addr_abs, A);
        return 0;
    }

    int STX() {
        writeAddr(addr_abs, X);
        return 0;
    }

    int STY() {
        writeAddr(addr_abs, Y);
        return 0;
    }

    int TAX() {
        X = A;
        setFlag(Z, X == 0);
        setFlag(N, X & 0x80);
        return 0;
    }

    int TAY() {
        Y = A;
        setFlag(Z, Y == 0);
        setFlag(N, Y & 0x80);
        return 0;
    }

    int TSX() {
        X = SP;
        setFlag(Z, X == 0);
        setFlag(N, X & 0x80);
        return 0;
    }

    int TXA() {
        A = X;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int TXS() {
        SP = X;
        return 0;
    }

    int TYA() {
        A = Y;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int ASL() {
        if (addr_abs == 0) { // Accumulator mode
            setFlag(C, A & 0x80);
            A <<= 1;
            setFlag(Z, A == 0);
            setFlag(N, A & 0x80);
        } else {
            uint8_t value = read(addr_abs);
            setFlag(C, value & 0x80);
            value <<= 1;
            writeAddr(addr_abs, value);
            setFlag(Z, value == 0);
            setFlag(N, value & 0x80);
        }
        return 0;
    }

    int LSR() {
        if (addr_abs == 0) {
            setFlag(C, A & 0x01);
            A >>= 1;
            setFlag(Z, A == 0);
            setFlag(N, 0);
        } else {
            uint8_t value = read(addr_abs);
            setFlag(C, value & 0x01);
            value >>= 1;
            writeAddr(addr_abs, value);
            setFlag(Z, value == 0);
            setFlag(N, 0);
        }
        return 0;
    }

    int ROL() {
        uint16_t temp;
        if (addr_abs == 0) {
            temp = (A << 1) | (getFlag(C) ? 1 : 0);
            setFlag(C, A & 0x80);
            A = temp & 0xFF;
            setFlag(Z, A == 0);
            setFlag(N, A & 0x80);
        } else {
            temp = (read(addr_abs) << 1) | (getFlag(C) ? 1 : 0);
            setFlag(C, fetched & 0x80);
            writeAddr(addr_abs, temp & 0xFF);
            setFlag(Z, (temp & 0xFF) == 0);
            setFlag(N, temp & 0x80);
        }
        return 0;
    }

    int ROR() {
        uint16_t temp;
        if (addr_abs == 0) {
            temp = (A >> 1) | (getFlag(C) ? 0x80 : 0);
            setFlag(C, A & 0x01);
            A = temp & 0xFF;
            setFlag(Z, A == 0);
            setFlag(N, A & 0x80);
        } else {
            temp = (read(addr_abs) >> 1) | (getFlag(C) ? 0x80 : 0);
            setFlag(C, fetched & 0x01);
            writeAddr(addr_abs, temp & 0xFF);
            setFlag(Z, (temp & 0xFF) == 0);
            setFlag(N, temp & 0x80);
        }
        return 0;
    }

    int BIT() {
        fetchOperand();
        uint8_t temp = A & fetched;
        setFlag(Z, temp == 0);
        setFlag(N, fetched & 0x80);
        setFlag(V, fetched & 0x40);
        return 0;
    }

    int PHA() {
        push(A);
        return 0;
    }

    int PHP() {
        push(P | B | R);
        return 0;
    }

    int PLA() {
        A = pop();
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
        return 0;
    }

    int PLP() {
        P = pop();
        P &= ~B;
        P &= ~R;
        return 0;
    }

    int BRK() {
        PC++;
        push16(PC);
        push(P | B);
        setFlag(I, true);
        PC = read16(0xFFFE);
        return 0;
    }

    int RTI() {
        P = pop();
        P &= ~B;
        P &= ~R;
        PC = pop16();
        return 0;
    }

    int JSR() {
        uint16_t target = read16(PC);
        PC += 2;
        push16(PC - 1);
        PC = target;
        return 0;
    }

    int RTS() {
        PC = pop16() + 1;
        return 0;
    }

    int JMP() {
        PC = addr_abs;
        return 0;
    }

    int NOP() {
        return 0;
    }

    // --- Основной цикл выполнения инструкции ---
    int executeInstruction() {
        uint8_t opcode = fetch();
        int base_cycles = cycle_table[opcode];
        int additional_cycles = 0;

        // Установить addr_abs или addr_rel в зависимости от инструкции
        switch (opcode) {
            case 0xA9: addr_immediate(); break;
            case 0xA5: addr_zero_page(); break;
            case 0xB5: addr_zero_page_x(); break;
            case 0xAD: addr_absolute(); break;
            case 0xBD: addr_absolute_x(); additional_cycles = ((PC - 1) & 0xFF00) != (addr_abs & 0xFF00) ? 1 : 0; break;
            case 0xB9: addr_absolute_y(); additional_cycles = ((PC - 1) & 0xFF00) != (addr_abs & 0xFF00) ? 1 : 0; break;
            case 0xA1: addr_indirect_x(); break;
            case 0xB1: addr_indirect_y(); additional_cycles = ((PC - 1) & 0xFF00) != (addr_abs & 0xFF00) ? 1 : 0; break;
            case 0x20: JSR(); return base_cycles + additional_cycles;
            case 0x4C: addr_absolute(); JMP(); return base_cycles + additional_cycles;
            case 0x6C: addr_abs = read16(PC); PC += 2; JMP(); return base_cycles + additional_cycles;
            case 0x10: case 0x30: case 0x50: case 0x70:
            case 0x90: case 0xB0: case 0xD0: case 0xF0:
                addr_relative();
                if ((PC & 0xFF00) != (addr_rel & 0xFF00)) additional_cycles = 2;
                else additional_cycles = 1;
                break;
            default:
                // Для остальных инструкций — адресация не нужна
                break;
        }

        switch (opcode) {
            case 0x69: case 0x65: case 0x75: case 0x6D: case 0x7D: case 0x79: case 0x61: case 0x71: ADC(); break;
            case 0xE9: case 0xE5: case 0xF5: case 0xED: case 0xFD: case 0xF9: case 0xE1: case 0xF1: SBC(); break;
            case 0x29: case 0x25: case 0x35: case 0x2D: case 0x3D: case 0x39: case 0x21: case 0x31: AND(); break;
            case 0x49: case 0x45: case 0x55: case 0x4D: case 0x5D: case 0x59: case 0x41: case 0x51: EOR(); break;
            case 0x09: case 0x05: case 0x15: case 0x0D: case 0x1D: case 0x19: case 0x01: case 0x11: ORA(); break;
            case 0xC9: case 0xC5: case 0xD5: case 0xCD: case 0xDD: case 0xD9: case 0xC1: case 0xD1: CMP(); break;
            case 0xE0: case 0xE4: case 0xEC: CPX(); break;
            case 0xC0: case 0xC4: case 0xCC: CPY(); break;
            case 0xC6: case 0xD6: case 0xCE: case 0xDE: DEC(); break;
            case 0xCA: DEX(); break;
            case 0x88: DEY(); break;
            case 0xE6: case 0xF6: case 0xEE: case 0xFE: INC(); break;
            case 0xE8: INX(); break;
            case 0xC8: INY(); break;
            case 0xA9: case 0xA5: case 0xB5: case 0xAD: case 0xBD: case 0xB9: case 0xA1: case 0xB1: LDA(); break;
            case 0xA2: case 0xA6: case 0xB6: case 0xAE: case 0xBE: case 0xA0: case 0xB0: LDX(); break;
            case 0xA0: case 0xA4: case 0xB4: case 0xAC: case 0xBC: LDY(); break;
            case 0x85: case 0x95: case 0x8D: case 0x9D: case 0x99: case 0x81: case 0x91: STA(); break;
            case 0x86: case 0x96: case 0x8E: STX(); break;
            case 0x84: case 0x94: case 0x8C: STY(); break;
            case 0xAA: TAX(); break;
            case 0xA8: TAY(); break;
            case 0xBA: TSX(); break;
            case 0x8A: TXA(); break;
            case 0x9A: TXS(); break;
            case 0x98: TYA(); break;
            case 0x0A: case 0x06: case 0x16: case 0x0E: case 0x1E: ASL(); break;
            case 0x4A: case 0x46: case 0x56: case 0x4E: case 0x5E: LSR(); break;
            case 0x2A: case 0x26: case 0x36: case 0x2E: case 0x3E: ROL(); break;
            case 0x6A: case 0x66: case 0x76: case 0x6E: case 0x7E: ROR(); break;
            case 0x24: case 0x2C: BIT(); break;
            case 0x48: PHA(); break;
            case 0x08: PHP(); break;
            case 0x68: PLA(); break;
            case 0x28: PLP(); break;
            case 0x00: BRK(); break;
            case 0x40: RTI(); break;
            case 0x60: RTS(); break;
            case 0x4C: case 0x6C: break; // Уже обработано выше
            case 0x10: case 0x30: case 0x50: case 0x70:
            case 0x90: case 0xB0: case 0xD0: case 0xF0: {
                bool branch_taken = false;
                switch (opcode) {
                    case 0x10: branch_taken = !getFlag(N); break;
                    case 0x30: branch_taken = !getFlag(V); break;
                    case 0x50: branch_taken = !getFlag(V); break;
                    case 0x70: branch_taken = getFlag(V); break;
                    case 0x90: branch_taken = !getFlag(C); break;
                    case 0xB0: branch_taken = getFlag(C); break;
                    case 0xD0: branch_taken = !getFlag(Z); break;
                    case 0xF0: branch_taken = getFlag(Z); break;
                }
                if (branch_taken) {
                    PC = addr_rel;
                } else {
                    additional_cycles = 0;
                }
                break;
            }
            case 0xEA: NOP(); break;
            default:
                std::cout << "Unknown opcode: 0x" << std::hex << (int)opcode << "\n";
                exit(1);
        }

        cycles += base_cycles + additional_cycles;
        return base_cycles + additional_cycles;
    }

    void push(uint8_t value) {
        write(0x0100 + SP, value);
        SP--;
    }

    void push16(uint16_t value) {
        push((value >> 8) & 0xFF);
        push(value & 0xFF);
    }

    uint8_t pop() {
        SP++;
        return read(0x0100 + SP);
    }

    uint16_t pop16() {
        uint8_t low = pop();
        uint8_t high = pop();
        return low | (high << 8);
    }
};

int main() {
    MOS6502 cpu;

    // Пример программы: LDA #$01; ADC #$02; JMP $8000
    cpu.memory[0x8000] = 0xA9; cpu.memory[0x8001] = 0x01; // LDA #$01
    cpu.memory[0x8002] = 0x69; cpu.memory[0x8003] = 0x02; // ADC #$02
    cpu.memory[0x8004] = 0x4C; cpu.memory[0x8005] = 0x00; cpu.memory[0x8006] = 0x80; // JMP $8000

    cpu.PC = 0x8000;

    for (int i = 0; i < 10; i++) {
        int c = cpu.executeInstruction();
        std::cout << "Cycles: " << cpu.cycles << ", A: 0x" << std::hex << (int)cpu.A << std::endl;
    }

    return 0;
}

Наглая Qwen утверждает, что реализовала все команды процессора, коих 56, а так же 13 режимов адресации. Да, по коду видно, что теперь при декодировании инструкций учитывается режим адресации по опкоду команды, а также, к исполненному числу тактов дается довесок в виде дополнительных тактах при условных переходах. До поры отбросим интерпретацию полученных результатов, а пока дадим еще один запрос

имитация реальной тактовой частоты

по которому был предложен такой вариант основного цикла

#include <thread>

int main() {
    MOS6502 cpu;
    const int TARGET_HZ = 1790000; // ~1.79 MHz для NES
    const double CYCLE_TIME_NS = 1e9 / TARGET_HZ; // Наносекунд на такт

    // Пример программы: LDA #$01; ADC #$02; JMP $8000
    cpu.memory[0x8000] = 0xA9; cpu.memory[0x8001] = 0x01;
    cpu.memory[0x8002] = 0x69; cpu.memory[0x8003] = 0x02;
    cpu.memory[0x8004] = 0x4C; cpu.memory[0x8005] = 0x00; cpu.memory[0x8006] = 0x80;
    cpu.PC = 0x8000;

    int64_t total_emulated_cycles = 0;
    auto start_time = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < 1000000; i++) { // Например, 1 млн инструкций
        int cycles_this_step = cpu.executeInstruction();
        total_emulated_cycles += cycles_this_step;

        double elapsed_time_ns = std::chrono::duration<double, std::nano>(
            std::chrono::high_resolution_clock::now() - start_time
        ).count();

        double target_time_ns = total_emulated_cycles * CYCLE_TIME_NS;

        if (elapsed_time_ns < target_time_ns) {
            std::this_thread::sleep_for(
                std::chrono::nanoseconds((long long)(target_time_ns - elapsed_time_ns))
            );
        }
    }

    std::cout << "Эмуляция завершена. Выполнено " << total_emulated_cycles << " тактов.\n";
    return 0;
}

что в общем-то пойдет, для начала. Соединив все вместе, можно пробовать реализовать свой пример.

3. Реализация тестового эмулятора MOS 6502

Потратив первый вечер, я написал первый вариант проекта, структура которого такова

include/-
        |-main.h
        |-mos6502.h
src/----
        |-main.cpp
        |-mos6502.cpp
CMakeLists.txt

Пока что предельно просто - класс, реализующий работу процессора и главная функция, имитирующая прогон программы

Листинги

mos6502.h
#ifndef     MOS6502_H
#define     MOS6502_H

#include    <vector>
#include    <cstdint>

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
class MOS6502
{
public:

    MOS6502();

    ~MOS6502(){}

    /// Регистр-аккумулятор
    uint8_t A = 0;
    /// Впомогательный регистр X
    uint8_t X = 0;
    /// Вспомогательный регистр Y
    uint8_t Y = 0;
    /// Регистр указателя стека
    uint8_t SP = 0;
    /// Регистр флагов
    uint8_t P = 0;

    /// Регистр-счетчик команд
    uint16_t PC = 0;

    uint64_t cycles = 0;

    enum
    {
        MEMORY_SIZE = 0x10000
    };

    /// Флаги
    enum
    {
        C = 0x01, /// Перенос
        Z = 0x02, /// Ноль
        I = 0x04, /// Запрет прерываний
        D = 0x08, /// Переводит АЛУ в режим двично-десятичного кода
        B = 0x10, /// Флаг останова
        R = 0x20,
        V = 0x40, /// Переполнение
        N = 0x80  /// Знак
    };


    std::vector<uint8_t> memory = std::vector<uint8_t>(MEMORY_SIZE, 0x00);

    /// Сброс процессора
    void reset();

    /// Читаем байт из памяти по указанному адресу
    uint8_t read(uint16_t addr);

    /// Читаем слово по адресу в памяти
    uint16_t read16(uint16_t addr);

    /// Пишем в память по адресу
    void write(uint16_t addr, uint8_t value);

    /// Установить флаг
    void setFlag(uint8_t flag, bool value);

    /// Прочиать флаг
    bool getFlag(uint8_t flag);

    uint16_t addr_abs = 0;
    uint16_t addr_rel = 0;
    uint8_t fetched = 0;

    uint8_t fetch();

    uint8_t fetchOperand();

    void writeAddr(uint16_t addr, uint8_t value);

    /// 1. Непосредственная адрессация
    void addr_immediate();

    /// 2.
    void addr_zero_page();

    /// 3.
    void addr_zero_page_x();

    /// 4.
    void addr_zero_page_y();

    /// 5.
    void addr_absolute();

    /// 6.
    void addr_absolute_x();

    /// 7.
    void addr_absolute_y();

    /// 8.
    void addr_indirect_x();

    /// 9.
    void addr_indirect_y();

    /// 10.
    void addr_relative();

    /// 11.
    void addr_accumulator();

    // Таблица базовых тактов
    const int cycle_table[256] = {
        //  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
        7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, // 0
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 1
        6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, // 2
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 3
        6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, // 4
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 5
        6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, // 6
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 7
        2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // 8
        2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, // 9
        2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // A
        2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, // B
        2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // C
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // D
        2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // E
        2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7  // F
    };

    /// Сложение с аккумулятором с переносом
    int ADC();

    /// Вычитание из аккумулятора с переносом
    int SBC();

    /// Логичесое битовое "И" с аккумулятором
    int AND();

    /// Исключающее "ИЛИ" с аккумулятором
    int EOR();

    /// "ИЛИ" с аккумулятором
    int ORA();

    /// Сравнение с аккумулятором
    int CMP();

    /// Сравнение с регистром X
    int CPX();

    /// Сравнение с регистром Y
    int CPY();

    /// Декремент значения в памяти
    int DEC();

    /// Декремент регистра X
    int DEX();

    /// Декремент регистра Y
    int DEY();

    /// Инкремент значения в памяти
    int INC();

    /// Инкремент регистра X
    int INX();

    /// Инкремент регистра Y
    int INY();

    /// Загрузка аккумулятора
    int LDA();

    /// Загрузка регистра X
    int LDX();

    /// Загрузка регистра Y
    int LDY();

    /// Сохранить аккумулятор в памяти
    int STA();

    /// Сохранить X в памяти
    int STX();

    /// Сохранить Y в памяти
    int STY();

    /// Перенести значение из аккумулятора в X
    int TAX();

    /// Перенести значение из аккумулятора в Y
    int TAY();

    /// Перенести значение SP в X
    int TSX();

    /// Перенести значение из X в аккумулятор
    int TXA();

    /// Перенести значение из Y в аккумулятор
    int TYA();

    /// Загрузить SP из X
    int TXS();

    /// Арифметический сдвиг влево (аккумулятор или память)
    int ASL();

    /// Логический сдвиг вправо (аккумулятор или память
    int LSR();

    /// Циклический сдвиг влево
    int ROL();

    /// Циклический сдвиг вправо
    int ROR();

    /// Тест битов
    int BIT();

    /// Протолкнуть в стек байт
    void push(uint8_t value);

    /// Протлкнуть в стек слово
    void push16(uint16_t value);

    /// Извлечь из стека байт
    uint8_t pop();

    /// Извлечь из стека слово
    uint16_t pop16();

    /// Протолкнуть в стек аккумулятор
    int PHA();

    /// Протолкнуть в стек флаги
    int PHP();

    /// Извлечь из стека в аккумулятор
    int PLA();

    /// Извлечь из стека флаги
    int PLP();

    /// Инициировать программное прервывание
    int BRK();

    /// Возврат из прерывания
    int RTI();

    /// Вызов подпрограммы
    int JSR();

    /// Возврат из подпрограммы
    int RTS();

    /// Безусловный переход
    int JMP();

    /// Пустая операция
    int NOP();

    /// Цикл выполнения инструкции
    int execInstruction();
};

#endif
mos6502.cpp
#include    <mos6502.h>
#include    <iostream>

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
MOS6502::MOS6502()
{
    reset();
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::reset()
{
    PC = read16(0xFFFC);
    SP = 0xFD;
    P = I;
    A = X = Y = 0;
    cycles = 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint8_t MOS6502::read(uint16_t addr)
{
    cycles++;
    return memory[addr];
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint16_t MOS6502::read16(uint16_t addr)
{
    return read(addr) | (read(addr + 1) << 8);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::write(uint16_t addr, uint8_t value)
{
    cycles++;
    memory[addr] = value;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::setFlag(uint8_t flag, bool value)
{
    if (value)
        P |= flag;
    else
        P &= ~flag;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
bool MOS6502::getFlag(uint8_t flag)
{
    return (P & flag) != 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint8_t MOS6502::fetch()
{
    return read(PC++);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint8_t MOS6502::fetchOperand()
{
    fetched = read(addr_abs);
    return fetched;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::writeAddr(uint16_t addr, uint8_t value)
{
    write(addr, value);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_immediate()
{
    // Берем непосредственный операнд, лежащий в памяти сразу за опкодом
    addr_abs = PC++;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_zero_page()
{
    addr_abs = fetch();
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_zero_page_x()
{
    addr_abs = (fetch() + X) & 0xFF;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_zero_page_y()
{
    addr_abs = (fetch() + Y) & 0xFF;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_absolute()
{
    addr_abs = read16(PC);
    PC += 2;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_absolute_x()
{
    addr_abs = read16(PC) + X;
    PC += 2;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_absolute_y()
{
    addr_abs = read16(PC) + Y;
    PC += 2;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_indirect_x()
{
    uint16_t ptr = (fetch() + X) & 0xFF;
    addr_abs = read16(ptr);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_indirect_y()
{
    uint16_t ptr = fetch();
    addr_abs = read16(ptr) + Y;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_relative()
{
    addr_rel = fetch();

    if (addr_rel & 0x80)
        addr_rel |= 0xFF00;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_accumulator()
{
    addr_abs = 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::ADC()
{
    fetchOperand();
    uint16_t tmp = A + fetched + (getFlag(C) ? 1 : 0);
    setFlag(C, tmp > 0xFF);
    setFlag(V, (~(A ^ fetched) & (A & tmp)) & 0x80);
    A = tmp & 0xFF;
    setFlag(Z, A ==0);
    setFlag(N, A & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::SBC()
{
    fetchOperand();
    uint16_t tmp = A - fetched - (getFlag(C) ? 1 : 0);
    setFlag(C, tmp < 0x100);
    setFlag(V, ((A ^ tmp) & (fetched ^ A)) & 0x80);
    A = tmp & 0xFF;
    setFlag(Z, A == 0);
    setFlag(N, A & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::AND()
{
    fetchOperand();
    A &= fetched;
    setFlag(Z, A == 0);
    setFlag(N, A & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::EOR()
{
    fetchOperand();
    A ^= fetched;
    setFlag(Z, A == 0);
    setFlag(N, A & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::ORA()
{
    fetchOperand();
    A |= fetched;
    setFlag(Z, A == 0);
    setFlag(N, A & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::CMP()
{
    fetchOperand();
    uint16_t tmp = A - fetched;
    setFlag(C, A >= fetched);
    setFlag(Z, tmp == 0);
    setFlag(N, tmp & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::CPX()
{
    uint8_t value = read(addr_abs);
    uint16_t tmp = X - value;
    setFlag(C, X >= value);
    setFlag(Z, tmp ==0);
    setFlag(N, tmp & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::CPY()
{
    uint8_t value = read(addr_abs);
    uint16_t tmp = Y - value;
    setFlag(C, Y >= value);
    setFlag(Z, tmp ==0);
    setFlag(N, tmp & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::DEC()
{
    uint8_t value = read(addr_abs);
    value--;
    writeAddr(addr_abs, value);
    setFlag(Z, value == 0);
    setFlag(N, value & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::DEX()
{
    X--;
    setFlag(Z, X == 0);
    setFlag(N, X & 0x80);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::DEY()
{
    Y--;
    setFlag(Z, Y == 0);
    setFlag(N, Y & 0x80);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::INC()
{
    uint8_t value = read(addr_abs);
    value++;
    writeAddr(addr_abs, value);
    setFlag(Z, value == 0);
    setFlag(N, value & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::INX()
{
    X++;
    setFlag(Z, X == 0);
    setFlag(N, X & 0x80);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::INY()
{
    Y++;
    setFlag(Z, Y == 0);
    setFlag(N, Y & 0x80);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::LDA()
{
    fetchOperand();
    A = fetched;
    setFlag(Z, A == 0);
    setFlag(N, A & 0x80);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::LDX()
{
    fetchOperand();
    X = fetched;
    setFlag(Z, X == 0);
    setFlag(N, X & 0x80);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::LDY()
{
    fetchOperand();
    Y = fetched;
    setFlag(Z, Y == 0);
    setFlag(N, Y & 0x80);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::STA()
{
    writeAddr(addr_abs, A);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::STX()
{
    writeAddr(addr_abs, X);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::STY()
{
    writeAddr(addr_abs, Y);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::TAX()
{
    X = A;
    setFlag(Z, X == 0);
    setFlag(N, X & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::TAY()
{
    Y = A;
    setFlag(Z, Y == 0);
    setFlag(N, Y & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::TSX()
{
    X = SP;
    setFlag(Z, X == 0);
    setFlag(N, X & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::TXA()
{
    A = X;
    setFlag(Z, A == 0);
    setFlag(N, A & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::TYA()
{
    A = Y;
    setFlag(Z, A == 0);
    setFlag(N, A & 0x80);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::TXS()
{
    SP = X;
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::ASL()
{
    if (addr_abs == 0)
    {
        setFlag(C, A & 0x80);
        A <<= 1;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
    }
    else
    {
        uint8_t value = read(addr_abs);
        setFlag(C, value & 0x80);
        value <<= 1;
        writeAddr(addr_abs, value);
        setFlag(Z, value == 0);
        setFlag(N, value & 0x80);
    }

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::LSR()
{
    if (addr_abs == 0)
    {
        setFlag(C, A & 0x01);
        A >>= 1;
        setFlag(Z, A == 0);
        setFlag(N, 0);
    }
    else
    {
        uint8_t value = read(addr_abs);
        setFlag(C, value & 0x01);
        value >>= 1;
        writeAddr(addr_abs, value);
        setFlag(Z, value == 0);
        setFlag(N, 0);
    }

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::ROL()
{
    uint16_t tmp = 0;
    if (addr_abs == 0)
    {
        tmp = (A << 1) | (getFlag(C) ? 1 : 0);
        setFlag(C, A & 0x80);
        A = tmp & 0xFF;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
    }
    else
    {
        tmp = (read(addr_abs) << 1) | (getFlag(C) ? 1 : 0);
        setFlag(C, fetched & 0x80);
        writeAddr(addr_abs, tmp & 0xFF);
        setFlag(Z, (tmp & 0xFF) == 0);
        setFlag(N, tmp & 0x80);
    }

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::ROR()
{
    uint16_t tmp = 0;
    if (addr_abs == 0)
    {
        tmp = (A >> 1) | (getFlag(C) ? 0x80 : 0);
        setFlag(C, A & 0x01);
        A = tmp & 0xFF;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
    }
    else
    {
        tmp = (read(addr_abs) >> 1) | (getFlag(C) ? 0x80 : 0);
        setFlag(C, fetched & 0x01);
        writeAddr(addr_abs, tmp & 0xFF);
        setFlag(Z, (tmp & 0xFF) == 0);
        setFlag(N, tmp & 0x80);
    }

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::BIT()
{
    fetchOperand();
    uint8_t tmp = A & fetched;
    setFlag(Z, tmp == 0);
    setFlag(N, fetched & 0x80);
    setFlag(V, fetched & 0x40);

    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::push(uint8_t value)
{
    write(0x100 + SP, value);
    SP--;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::push16(uint16_t value)
{
    push((value >> 8) & 0xFF);
    push(value & 0xFF);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint8_t MOS6502::pop()
{
    SP++;
    return read(0x100 + SP);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint16_t MOS6502::pop16()
{
    uint8_t low = pop();
    uint8_t high = pop();
    return low | (high << 8);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::PHA()
{
    push(A);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::PHP()
{
    push(P | B | R);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::PLA()
{
    A = pop();
    setFlag(Z, A == 0);
    setFlag(N, A & 0x80);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::PLP()
{
    P = pop();
    P &= ~B;
    P &= ~R;
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::BRK()
{
    PC++;
    push16(PC);
    push(P | B);
    setFlag(I, true);
    PC = read16(0xFFFE);
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::RTI()
{
    P = pop();
    P &= ~B;
    P &= ~R;
    PC = pop16();
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::JSR()
{
    uint16_t target = read16(PC);
    PC += 2;
    push16(PC - 1);
    PC = target;
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::RTS()
{
    PC = pop16() + 1;
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::JMP()
{
    PC = addr_abs;
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::NOP()
{
    return 0;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::execInstruction()
{
    uint8_t opcode = fetch();
    int base_cycles = cycle_table[opcode];
    int additional_cycles = 0;

    switch (opcode)
    {
    // Непосредственная адресация
    case 0xA9: case 0x69: case 0x29: case 0xC9: case 0xE0:
    case 0xC0: case 0x49: case 0xA2: case 0xA0: case 0x09:
    case 0xE9: addr_immediate(); break;

    case 0xA5: case 0x65: case 0x25: addr_zero_page(); break;

    case 0xB5: case 0x75: case 0x35: addr_zero_page_x(); break;

    case 0xAD: case 0x6D: case 0x2D: addr_absolute(); break;

    case 0x0A: case 0x2A: case 0x6A: addr_accumulator(); break;

    case 0xBD: case 0x7D: case 0x3D: addr_absolute_x(); additional_cycles = ((PC-1) & 0xFF00) != (addr_abs & 0xFF00) ? 1 : 0; break;

    case 0xB9: case 0x79: case 0x39: addr_absolute_y(); additional_cycles = ((PC-1) & 0xFF00) != (addr_abs & 0xFF00) ? 1 : 0; break;

    case 0xA1: addr_indirect_x(); break;

    case 0xB1: addr_indirect_y(); additional_cycles = ((PC-1) & 0xFF00) != (addr_abs & 0xFF00) ? 1 : 0; break;

    case 0x20: JSR(); return base_cycles + additional_cycles;

    case 0x4C: addr_absolute(); JMP(); return base_cycles + additional_cycles;

    case 0x6C: addr_abs = read16(PC); PC += 2; JMP(); return base_cycles + additional_cycles;

    case 0x10: case 0x30: case 0x50: case 0x70:
    case 0x90: case 0xB0: case 0xD0: case 0xF0:
        addr_relative();
        if ((PC & 0xFF00) != (addr_rel & 0xFF00)) additional_cycles = 2;
        else additional_cycles = 1;
        break;

    default:

        break;
    }

    switch (opcode)
    {
    case 0x69: case 0x65: case 0x75: case 0x6D: case 0x7D: case 0x79: case 0x61: case 0x71: ADC(); break;
    case 0xE9: case 0xE5: case 0xF5: case 0xED: case 0xFD: case 0xF9: case 0xE1: case 0xF1: SBC(); break;
    case 0x29: case 0x25: case 0x35: case 0x2D: case 0x3D: case 0x39: case 0x21: case 0x31: AND(); break;
    case 0x49: case 0x45: case 0x55: case 0x4D: case 0x5D: case 0x59: case 0x41: case 0x51: EOR(); break;
    case 0x09: case 0x05: case 0x15: case 0x0D: case 0x1D: case 0x19: case 0x01: case 0x11: ORA(); break;
    case 0xC9: case 0xC5: case 0xD5: case 0xCD: case 0xDD: case 0xD9: case 0xC1: case 0xD1: CMP(); break;
    case 0xE0: case 0xE4: case 0xEC: CPX(); break;
    case 0xC0: case 0xC4: case 0xCC: CPY(); break;
    case 0xC6: case 0xD6: case 0xCE: case 0xDE: DEC(); break;
    case 0xCA: DEX(); break;
    case 0x88: DEY(); break;
    case 0xE6: case 0xF6: case 0xEE: case 0xFE: INC(); break;
    case 0xE8: INX(); break;
    case 0xC8: INY(); break;
    case 0xA9: case 0xA5: case 0xB5: case 0xAD: case 0xBD: case 0xB9: case 0xA1: case 0xB1: LDA(); break;
    case 0xA2: case 0xA6: case 0xB6: case 0xAE: case 0xBE: LDX(); break;
    case 0xA0: case 0xA4: case 0xB4: case 0xAC: case 0xBC: LDY(); break;
    case 0x85: case 0x95: case 0x8D: case 0x9D: case 0x99: case 0x81: case 0x91: STA(); break;
    case 0x86: case 0x96: case 0x8E: STX(); break;
    case 0x84: case 0x94: case 0x8C: STY(); break;
    case 0xAA: TAX(); break;
    case 0xA8: TAY(); break;
    case 0xBA: TSX(); break;
    case 0x8A: TXA(); break;
    case 0x9A: TXS(); break;
    case 0x98: TYA(); break;
    case 0x0A: case 0x06: case 0x16: case 0x0E: case 0x1E: ASL(); break;
    case 0x4A: case 0x46: case 0x56: case 0x4E: case 0x5E: LSR(); break;
    case 0x2A: case 0x26: case 0x36: case 0x2E: case 0x3E: ROL(); break;
    case 0x6A: case 0x66: case 0x76: case 0x6E: case 0x7E: ROR(); break;
    case 0x24: case 0x2C: BIT(); break;
    case 0x48: PHA(); break;
    case 0x08: PHP(); break;
    case 0x68: PLA(); break;
    case 0x28: PLP(); break;
    case 0x00: BRK(); break;
    case 0x40: RTI(); break;
    case 0x60: RTS(); break;
    case 0x4C: case 0x6C: break;
    case 0x10: case 0x30: case 0x50: case 0x70:
    case 0x90: case 0xB0: case 0xD0: case 0xF0:
        {
            bool branch_taken = false;
            switch (opcode)
            {
            case 0x10: branch_taken = !getFlag(N); break;
            case 0x30: branch_taken = !getFlag(V); break;
            case 0x50: branch_taken = !getFlag(V); break;
            case 0x70: branch_taken = !getFlag(V); break;
            case 0x90: branch_taken = !getFlag(C); break;
            case 0xB0: branch_taken = !getFlag(C); break;
            case 0xD0: branch_taken = !getFlag(Z); break;
            case 0xF0: branch_taken = !getFlag(Z); break;
            }

            if (branch_taken)
            {
                PC = addr_rel;
            }
            else
            {
                additional_cycles = 0;
            }

            break;
        }

    case 0xEA: NOP(); break;

    default:
        std::cout << "Unknown opcode: 0x" << std::hex << (int) opcode << std::endl;
        exit(1);
    }

    cycles += base_cycles + additional_cycles;
    return base_cycles + additional_cycles;
}

main.h
#ifndef     MAIN_H
#define     MAIN_H

#include    <mos6502.h>
#include    <iostream>

#endif
main.cpp
#include    <main.h>

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    MOS6502 cpu;

    cpu.memory[0x8000] = 0xA9;
    cpu.memory[0x8001] = 0x01;
    cpu.memory[0x8002] = 0x0A;
    cpu.memory[0x8003] = 0x4C;
    cpu.memory[0x8004] = 0x02;
    cpu.memory[0x8005] = 0x80;

    cpu.PC = 0x8000;

    for (int i = 0; i < 10; ++i)
    {
        int c = cpu.execInstruction();
        std::cout << "Cycles: " << cpu.cycles << ", A: 0x" << std::hex << (int) cpu.A << std::endl;
    }

    return 0;
}
CMakeLists.txt
cmake_minimum_required (VERSION 3.29)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(TARGET c64)

project(${TARGET})

set(EXECUTABLE_OUTPUT_PATH "../bin")

file(GLOB INCLUDES "./include/*.h")
file(GLOB SOURCES "./src/*.cpp")

add_executable(${TARGET} ${SOURCES} ${INCLUDES})

target_include_directories(${TARGET} PRIVATE ./include/)

Напрямую в память был установлена программа в машинных кодах, имеющая следующий ассемблерный листинг

8000: LDA $01
8002: ASL
8003: JMP $8002

Загружаем аккумулятор непосредственным значением, выполняем арифметический сдвиг влево, безусловно прыгаем снова на команду сдвига. Регистр-счетчик команд ставим принудительно на адрес 0x8000. Все просто. И как вы думаете, заработало оно сразу, по реализации предложенной Qwen? Конечно же нет!

Проблемы начались уже на команде ASL. Qwen предлагает реализовать её с учетом всех возможных способов адрессации

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::ASL()
{
    if (addr_abs == 0)
    {
        setFlag(C, A & 0x80);
        A <<= 1;
        setFlag(Z, A == 0);
        setFlag(N, A & 0x80);
    }
    else
    {
        uint8_t value = read(addr_abs);
        setFlag(C, value & 0x80);
        value <<= 1;
        writeAddr(addr_abs, value);
        setFlag(Z, value == 0);
        setFlag(N, value & 0x80);
    }

    return 0;
}

предполагая работу как с аккумулятором, так и с абсолютной адресацией. Но не предусматривает варианта адресации "accumulator", которая описана в спецификации системы команд MOS 6502. Пришлось написать его самостоятельно

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::addr_accumulator()
{
    addr_abs = 0;
}

поправив процедуру декодирования с учетом команд работающих с аккумулятором

case 0x0A: case 0x2A: case 0x6A: addr_accumulator(); break;

То есть опкода 0x0A нейронка не предусмотрела, хотя горделиво заявила, что реализовала все 56 инструкций со всеми способами адресации.

После внесения таких исправлений и прогона по шагам, значение в аккумуляторе стало весело удваиваться с каждой итерацией цикла. Заработало! А что же дальше

А дальше - взять описание системы команд 6502 и начать кропотливо проверять каждую из команд во всех вариантах адресации, правя код. Qwen не учла все способы адресации, совершенно неправильно реализовала относительную адресацию, что сделало неработоспособным блок команд ближнего перехода. Короче говоря, глядя в документацию, кропотливо проверялась команда за командой, её реализация, дописывались нереализованные команды. В общем, эмулятор процессора ожил, стал выполнять команды в машинных кодах, непосредственно помещенные в память.

Но ведь в машинных кодах писать неинтересно. По хорошему нам бы освоить хотя бы ассемблер, и загружать скомпилированные программы из фала в память машины с передачей управления. Для начала...

4. Кросс-компиляция и выполнение программ на ассемблере

Для архитектуры 6502 есть кросс-ассемблер, и даже целый компилятор для языка C - это cc65. Это свободный проект, с отличнейшей документацией. Поскольку я работал в линуксе, а конкретно в ArchLinux, я собрал PKGBUILD из репозитория AUR. Все прошло тривиально и не стоит того, чтобы описывать.

Теперь, когда у нас есть компилятор, можно подумать и о модификации проекта - процессор у нас уже есть, пора подумать о том чтобы делать компьютер C64. С помощью Qwen удалось выяснить что:

  1. Формат исполняемых файлов для C64 называется PRG и элементарен по своей структуре - это бинарный файл, первые два байта которого - адрес загрузки программы в память (Little Edian), остальное - голый машинный код и данные.

  2. Предложена процедура загрузки файла (я ж непрограммист, у меня ж жеж лапки). Qwen "выдала гениальное"

// === ЗАГРУЗКА .PRG ===
    void load_prg(const std::string& filename) {
        std::ifstream file(filename, std::ios::binary);
        if (!file.is_open()) {
            std::cerr << "Cannot open file: " << filename << "\n";
            exit(1);
        }

        uint8_t lo, hi;
        file.read((char*)&lo, 1);
        file.read((char*)&hi, 1);
        uint16_t load_addr = lo | (hi << 8);

        std::cout << "Loading PRG to $0x" << std::hex << load_addr << std::endl;

        file.seekg(0, std::ios::beg); // Перейти в начало
        file.seekg(2, std::ios::cur); // Пропустить 2 байта заголовка

        char byte;
        while (file.get(byte)) {
            ram[load_addr++] = static_cast<uint8_t>(byte);
        }

        cpu.PC = load_addr; // Установить PC в конец загрузки
    }

Гениальность в последней, 24 строке. В строках с 9 по 12 мы так старались извлечь адрес загрузки, чтобы затем весело использовать его в качестве счетчика байт, а потом, тем что получилось, загрузить счетчик команд процессора. Круто, круто... Даже без запуска строчка 24 перекочевала на 13-ю строку, как это и должно было быть. Кто там писал, что нейросеть пишет код как "джун"? Да - в точку!

Отбросив иронию идем разбираться дальше - загрузчик кода у нас есть, теперь нужно собрать сам тестовый исполняемый файл. Ок, пишем его

test.asm
        .pc02
        .org $0801

start:
        lda #$01
loop:
        asl
        jmp loop

С помощью той же Qwen удалось выяснить, как это собрать. Надо скомпилировать исходник в объектный файл

$ ca65 test.asm -o test.o

а потом вызвать компоновщик

$ ld65 -C c64-asm.cfg test.o -o test.bin

Стоп, какой-такой c64-asm.cfg? А без него? Нельзя без него, это скрипт линковки, определяющий размещение кода и данных в конечном бинарнике. Хорошо, что нам посоветует ИИ?

c64-asm.cfg
MEMORY {
    ZP:       start = $0002, size = $001A, type = rw, define = yes;  # Область ZP (Zero Page)
    LOADADDR: start = $07FF,  size = $0002, type = ro, define = yes; # Адрес загрузки (2 байта)
    RAM:      start = $0801,  size = $97FE, file = %O, define = yes; # Основная память
}

SEGMENTS {
    LOADADDR: load = LOADADDR, type = ro;
    EXEHDR:   load = RAM,      type = ro,  optional = yes;
    CODE:     load = RAM,      type = ro,  optional = yes;
    RODATA:   load = RAM,      type = ro,  optional = yes;
    DATA:     load = RAM,      type = rw,  optional = yes;
    BSS:      load = RAM,      type = bss, optional = yes, define = yes;
}

Ладно, хоть тут ничего не понятно, кроме того что программа будет загружена по адресу 0x07FF. Попробуем - матернувшись,

ld65: Warning: c64.cfg(19): Segment 'LOADADDR' does not exist

компоновщик выдал двоичный файл следующего содержания

0000000 a9 01 0a 4c 03 08
0000006

и никакого адреса в начале там нет, хм... Ладно, мы не гордые, добавим эти два байта путем магического заклятия

$ echo -ne '\xff\x07' > test.prg
$ cat test.bin >> test.prg

Супер, заветный бинарник получен. И таки да, он запустился! Что же, теперь мы избавлены от мучения писать программы в машинных кодах, у нас есть целый ассемблер. Естественно, тестирование эмулятора процессора было продолжено. А заодно, не без помощи ИИ, найдены концы к автоматической генерации бинарника, что в конечном итоге вылилось в такой пример

test-stack.asm

.segment "LOADADDR"
		.word Start

		.org $0200

.segment "CODE"

Start:
		CLD
		CLI

		LDA #$2A
		PHA
		LDA #$2B
		PHA
		LDA #$2C
		PHA
		LDA #$00
		PLA
		PLA
		PLA
Loop:		
		JMP Loop

.segment "VECTORS"

		.org $FFFA
		.word Start
		.word Start
		.word Start

c64-asm.cfg

MEMORY {
	ZP:			start=$0000, size=$0100, type=rw, define=yes;
	LOADADDR:	start=$01FE, size=$0002, type=ro, define=yes;
	RAM:		start=$0200, size=$0100, type=rw, define=yes;
	ROM:		start=$C000, size=$4000, type=ro, define=yes;	 
}

SEGMENTS {
	ZEROPAGE:	load=ZP, type=zp;
	LOADADDR:	load=LOADADDR, type=ro;
	CODE:		load=RAM, type=ro, define=yes;
	VECTORS:	load=ROM, start=$FFFA, type=ro;
}

Все это собралось, загрузилось и выполнилось, а заодно мы проверили работу и сбаллансированность стека - как видно из примера, мы погрузили туда подряд три байта, а затем извлекли их. То есть, теоретически мы можем исполнять подпрограммы.

Вся эта возня с ассемблером позволила ещё раз проверить реализацию дешифровки команд. В основном это касалось добавления неучтенных опкодов и правку кода, отвечающего за адресацию. Несколько примеров дали хороший результат - эмулятор перестал останавливаться с ошибкой что получен Unknown opcode. Значит настал момент поручить ему нечто более серьезное. Что там у нас с ПЗУ? Что если попробовать скачать оригинальные образы ПЗУ Commodore 64 и отравить их на выполение? Ведь работа нашего компьютера начинается именно со сброса и передаче управления ПЗУ. Как раз работа для второго вечера.

5. Организация памяти Commodore 64

Теперь нас не устроит организация памяти в виде линейного массива байт - нам потребуется целый класс, который будет отвечать за всю аппаратную подсистему управления памятью в C64. Память этого компьютера состоит из:

  • RAM (ОЗУ) объемом 64 кб.

  • BASIC ROM (ПЗУ) объемом 8 кб - там живет интерпретатор бейсика.

  • KERNAL ROM (ПЗУ) объемом 8 кб - там обитает что-то вроде "биоса", системное ПО для инициализации и управления оборудованием на начальном этапе загрузки и предоставляющее программисту функции для реализации системных задач.

  • Character set ROM (ПЗУ) объемом 4 кб - там хранятся растровые шрифты и спецсимвола в двух наборах, каждый по 256 символов.

Все перечисленное - отдельные аппаратные устройства.

Процессор у нас имеет 16-разрядную адресную шину, то есть он непосредственно может адресовать лишь 64 кб, а у нас их 84. Для того чтобы выкрутиться из этой ситуации Commodor 64 содержит еще один системный чип - PLA (Programmable Logic Array), представляющий собой подобие ПЛИС, задача которой - дирижировать доступом процессора к различным областям памяти, вовремя переключая адресную шины на разные чипы. В эту карусель включены так же и

  • VIC - чип видео-контроллера, имеющий 64 байта регистровой памяти

  • SIC - чип аудио-контроллера со своими регистрами

  • CIA1 и CIA2 - чипы контроллеров ввода/вывода, естественно со своим набором регистров

Виртуальные адреса у нас непрерывны от 0x0000 до 0xFFFF. Однако, с помощью PLA, управляемого по сигналам процессора, в это адресное пространство проецируется все вышеперечисленное.

PLA представляет собой микросхему комбинационной логики не имеющую специальных регистров управления. Однако к трем его входам подключен специальный регистр процессора MOS 6510 (и именно это и отличает его от 6502). Переключением банков памяти управляют три младших бита этого регистра.

По умолчанию, адресное пространство распределено следующим образом:

  • 0x0000 - регистр CPU (CPU_REG0) управляющий направлением I/O портов

  • 0x0001 - регистр CPU (CPU_REG1) управляющий переключением банков памяти через PLA (биты 0-2). Старшие биты управляют кассетным магнитофоном

  • 0x0100 - 0x01FF - по-умолчанию здесь расположен стек

  • 0x0200 - 0x03FF - служебная область, выделенная для работы интерпретатора бейсика

  • 0x0400 - 0x07FF - видеопамять

  • 0x0800 - 0x9FFF - область хранения BASIC-программ

  • 0xA000 - 0xBFFF - по-умолчанию сюда проецируется BASIC ROM. Важно понимать, что не копируется, физически, при работе процессора с BASIC ROM эта область памяти остается свободной, а чтение данных происходит из соответствующего ПЗУ. Может быть изменено через регистр CPU_REG1

  • 0xC000 - 0xCFFF - область загрузки программ на машинном языке, то есть бинарников, написанных на ассемблере или C.

  • 0xD000 - 0xD3FF - область регистров чипа VIC-II. Обращение осуществляется к регистровой памяти видео-контроллера

  • 0xD400 - 0xD7FF - область регистров аудио-чипа SID

  • 0xD800 - 0xD8FF - Color memory чипа VIC-II. Содержит цвета символов, выводимых в текстовом режиме, причем от каждого байта этой области используется лишь одна младшая тетрада, то есть в нашем распоряжении аж 16 цветов.

  • 0xDC00 - 0xDE00 - поровну делится регистрами чипов CIA1 и CIA2

  • 0xDF00 - 0xDFFF - область портов ввода/вывода

  • 0xE000 - 0xFFFF - по-умолчанию сюда проецируется KERNAL ROM. Может быть изменено настройкой через регистр CPU_REG1

Кроме того, область памяти 0xD000 - 0xDFFF может быть спроецирована на Character ROM, это также управляется регистром CPU_REG1, но по умолчанию выключено. Состояния памяти, определяемые битами 0-2 выглядят так

  • 0xY00 - ни одна из ROM недоступна. Доступ осуществляется к RAM по соответствующим адресам. Y - означает произвольное состояние старшего бита

  • 0xY01 - нет доступа к BACIS ROM и KERNAL ROM

  • 0xY10 - нет доступа к BASIC ROM

  • 0x0YY - доступ к Character ROM по адресам 0xD000 - 0xDFFF

  • 0x1YY - доступны BACIS ROM и KERNAL ROM, а по адресам 0xD000 - 0xDFFF происходит доступ к портам VIC, SID, CIA и портам ввода/вывода

Много информации можно почерпнуть здесь и тут. Вторая ссылка очень полезна, так как дает базовое представление об архитектуре нашего пациента. А теперь, со всем этим багажем попробуем

6. Реализация подсистемы памяти Commodore 64

Не буду описывать многочисленные варианты, в конце я дам ссылку на репозиторий проекта и по коммитам можно отследить, что я пришел к нижеприведенному коду не сразу. Запуск с ROM произошел намного раньше, к исходу третьего вечера работы, на другой реализации памяти, нежели приведенная ниже. Здесь я "включил" разработчика и самостоятельно реализовал класс Memory интегрировав его с ядром MOS 6502, услужливо написанное для меня Qwen, и терпеливо доработанное мной. Приведу лишь выдержки из кода, главные его моменты.

Чтение и запись байта в память с учетом работы PLA

memory.cpp

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint8_t Memory::read(uint16_t addr)
{
    // При попытке чтения области I/O портов
    if (addr >= VIC_REGS && addr < IO_PORTS2)
    {
        // проверяем видимость этой области для процессора
        if ( ram[CPU_PORT1] & 0x04 )
        {
            return ram[addr];
        }
        else // в противном случе ситаем Character ROM
        {
            return char_rom[addr - CHAR_ROM];
        }
    }

    // При попытке чтения из области BASIC ROM
    if (addr >= BASIC_ROM && addr < BASIC_ROM + BASIC_ROM_SIZE)
    {
        // проверяем доступность этой области
        if ( (ram[CPU_PORT1] & 0x03) == 0x03)
        {
            return basic_rom[addr - BASIC_ROM];
        }
        else
        {
            // иначе - мы читаем ОЗУ
            return ram[addr];
        }
    }

    // При попытке чтения из KERNAL ROM
    if (addr >= KERNAL_ROM && addr <= KERNAL_ROM + KERNAL_ROM_SIZE - 1)
    {
        // Проверяем доступность этой области
        if (ram[CPU_PORT1] & 0x03)
        {
            return kernal_rom[addr - KERNAL_ROM];
        }
        else
        {
            // иначе - читаем ОЗУ
            return ram[addr];
        }
    }

    // Читаем память во всех остальных случаях
    return ram[addr];
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void Memory::write(uint16_t addr, uint8_t value)
{
    // При попытке записи в область I/O портов
    if (addr >= VIC_REGS && addr < IO_PORTS2)
    {
        // проверяем видимость этой области для процессора
        if ( ram[CPU_PORT1] & 0x04 )
        {
            ram[addr] = value;
            return;
        }

        // в противном случае запись не состоиться, уходим
        return;
    }

    // При попытке записи в область BASIC ROM
    if (addr >= BASIC_ROM && addr < BASIC_ROM + BASIC_ROM_SIZE)
    {
        // проверяем доступность этой области
        if ( (ram[CPU_PORT1] & 0x03) == 0x03)
        {
            return;
        }
        else
        {
            // иначе - пишем в ОЗУ
            ram[addr] = value;
            return;
        }
    }

    // При попытке записи в KERNAL ROM
    if (addr >= KERNAL_ROM && addr <= KERNAL_ROM + KERNAL_ROM_SIZE - 1)
    {
        // Проверяем доступность этой области
        if (ram[CPU_PORT1] & 0x03)
        {
            return;
        }
        else
        {
            // иначе - пишем в ОЗУ
            ram[addr] = value;
            return;
        }
    }

    // Пишем в RAM во всех остальных случаях
    ram[addr] = value;
}

агрузка ROM из образа на диске. Тут надо пояснить, что эти образы - один к одному образ памяти последовательно записанный в бинарный файл, так что код тривиален

memory.cpp

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void Memory::load_rom_file(const std::string &filename, std::vector<uint8_t> &rom)
{
    std::ifstream file(filename, std::ios::binary);

    if (!file.is_open())
    {
        std::cout << "Warning: Can't open ROM file: " << filename << std::endl;
        return;
    }

    file.read(reinterpret_cast<char*>(rom.data()), rom.size());

    std::cout << "Loaded ROM: " << filename << std::endl;
}

Модифицируем реализованные ранее методы процессора для работы с памятью, с учетом указателя на класс Memory, передаваемый процессору

mos6502.cpp

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint8_t MOS6502::read(uint16_t addr)
{
    cycles++;
    return memory->read(addr);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
uint16_t MOS6502::read16(uint16_t addr)
{
    return read(addr) | (read(addr + 1) << 8);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::write(uint16_t addr, uint8_t value)
{
    cycles++;
    memory->write(addr, value);
}

Инициализация железа C64

c64.cpp

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void C64::load_roms()
{
    cpu.memory->load_rom_file("../data/basic.901226-01.bin", cpu.memory->basic_rom);
    cpu.memory->load_rom_file("../data/kernal.901227-03.bin", cpu.memory->kernal_rom);
    cpu.memory->load_rom_file("../data/c64_char.bin", cpu.memory->char_rom);
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void C64::init()
{
    load_roms();

    cpu.reset();
}

Грамотный сброс процессора

mos6502.cpp


//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void MOS6502::reset()
{
    memory->ram[Memory::CPU_PORT0] = 0x2F;
    memory->ram[Memory::CPU_PORT1] = 0x37;

    PC = read16(0xFFFC);
    SP = 0xFF;
    P = 0x24;
    A = X = Y = 0;
    cycles = 0;
}

Обращаем внимание на то, что необходимо инициализировать CPU_REG0 и CPU_REG1, для того чтобы PLA верно переключил нам банки памяти, то есть сделал доступным бейсик и "биос". Кроме того, нам нужно передать управление на адрес, хранимый KERNAL ROM по адресу 0xFFFC - так называемый вектор сброса, где записан адрес, куда будет передано управление в код KERNAL ROM. Загружаем счетчик команд адресом из этой ячейки. Устанавливаем указатель стека на самое его дно - обращаю внимание, что адресация стека идет относительно адреса 0x0100, регистр SP - 8-битный, то есть стек не может быть более 256 байт. Не густо, но нам хватит. Устанавливает необходимые флаги процессора, чистим регистры, обнуляем счетчик тактов. Ок, погнали!

Ага, совершенно забыл, но образы всех ROM можно скачать тут. Это оригинальные образы, написанные в 80-е годы. Однако, их исходники я видел и на гитхабе, в том числе и бейсик - майкрософт его тоже открыл. Кроме того, доступен листинг BASIC и KERNAL ROM, можно посмотреть вот тут - он очень пригодился мне в процессе.

И - да, эмулятор запустился, кулер на процессоре загудел, выведенные на экран регистры весело изменялись. Ошибки "Неизвестный код операции" нет. Что-то выполняется, что-то запущено! Недаром проделана работа по отладке тестовых ассемблерных примеров. Но, мы не видим, что происходит с нашим "компьютером". Нужна визуализация экрана, ибо совершенно очевидно, что на экран должно что-то выводиться. Визуализацию я реализовал, о чем свидетельствует скриншот на КДПВ, однако о ней я напишу ниже, а пока перечислю те "затыки", которые мне пришлось решить до того, как я увидел что-то, кроме черного окна.

  • Мой косяк - не надо сбрасывать процессор до загрузки ROM-ов, иначе он будет читать нули

mos6502.cpp

//------------------------------------------------------------------------------
MOS6502::MOS6502()
{
-    reset();
+
}

строка 4 была удалена

  • Снова мой косяк - считая себя умнее ИИ, я написал по своему обработку команды JSR - вызов подпрограммы. Вернул так, как рекомендовала Qwen

mos6502.cpp

  case 0x91: addr_indirect_y(); additional_cycles = ((PC-1) & 0xFF00) != (addr_abs & 0xFF00) ? 1 : 0; break;

  // Вызов подпрограммы с абсолютной адресацией
- case 0x20: addr_absolute(); JSR(); return base_cycles + additional_cycles;
+ case 0x20: JSR(); return base_cycles + additional_cycles;

  // Безусловные переходы с абсолютной адрессацией
  case 0x4C: addr_absolute(); JMP(); return base_cycles + additional_cycles;
  • Косяк Qwen, который она нагло и упорно тащила через все примеры, которые печатала для меня. Ошибка в вычислении адреса перехода при относительной адресации

mos6502.cpp

            if (branch_taken)
            {
-                PC = addr_rel;
+                PC += addr_rel;
            }
            else
            {

Это приводило к неверной работе ближних переходов, то есть в пределах 256 байт +/- от текущей инструкции.

  • Снова косяк от Qwen - не учтены некоторые коды операций при дешифровке команд, однако это 50/50 и мой косяк, вызванный банальной невнимательностью

mos6502.cpp

    case 0xA5: case 0x65: case 0x25: case 0x06: case 0x24:
    case 0xC5: case 0xE4: case 0xC4: case 0xC6: case 0x45:
    case 0xE6: case 0xA6: case 0xA4: case 0x46: case 0x05:
-   case 0x26: case 0x66: case 0xE5: case 0x85:
+   case 0x26: case 0x66: case 0xE5: case 0x85: case 0x84:
    case 0x86: addr_zero_page(); break;

    // Адресация в пределах нулевой страницы относительной регистра X
    case 0xCD: case 0xEC: case 0xCC: case 0xCE: case 0x4D:
    case 0xEE: case 0xAE: case 0xAC: case 0x4E:
    case 0x0D: case 0x2E: case 0x6E: case 0xED: case 0x8D:
-   case 0x8C: addr_absolute(); break;
+   case 0x8C: case 0x8E: addr_absolute(); break;

Каждая из этих ошибок приводила к неверной адресации, а значит неверной выборке инструкций из памяти. То, что не ловился неверный код операции - чистая случайность. И процессор работал, исполняя совершенейший бред, случайный набор команд, из-за сдвигов в адресе.

И после исправления всего этого... (барабанная дробь), я увидел чудо

Первый признак того, что KERNAL ROM работает. Как-то работает...
Первый признак того, что KERNAL ROM работает. Как-то работает...

Экран раскрасился в знакомый по обзорам C64 цвет! Черный экран стал цветным, значит что-то работает верно! Не сказать чтобы это результат, но и тоже не шутка - запустился код, написанный не мной, машинный код почти полувековой давности. Да, друзья, это воодушевляет. Всегда с восхищением относился к людям, которые пишут эмуляторы компьютерных систем. Я занимался системным программированием, но не до такой степени. И тут ожил мой, склепанный на коленке эмулятор!

Однако, восторг сменился унынием. Так как этот пустой экран сообщал, что KERNAL ROM запустилась и работает, но не передает управление интерпретатору BASIC. С позволения читателя, я сначала расскажу как я решал это, а уж потом опишу процесс визуализации экранного вывода - так будет вернее с методической точки зрения.

7. Отладка внутри отладки, или как запустить BASIC

Итак, эмулятор работает, не вываливается с ошибкой о неверном опкоде. Очевидно выполнение зациклилось. Ну что же, вооружившись листингом приведенным выше, я пошел пошагово, в отладчике выполнять последовательно все инструкции загрузки. Внимание я обращал на соответствие листингу прошивки опкода, и адреса перехода, который загружен в регистр-счетчик команд.

По ходу этого действа выяснилась неверная отработка команды BMI, что было исправлено. Для честности, припишу этот участок кода моим ошибкам, хотя это может быть и косяк Qwen, ибо эту часть я, из-за лени, копипастил из выдачи LLM.

//------------------------------------------------------------------------------
int MOS6502::execInstruction()
{
    if (PC == 0xA000)
    if (PC == 0xE584)
    {
        int a = 0;
    }
            switch (opcode)
            {
            case 0x10: branch_taken = !getFlag(N); break;
-           case 0x30: branch_taken = !getFlag(V); break;
+           case 0x30: branch_taken = getFlag(N); break;
            case 0x50: branch_taken = !getFlag(V); break;
            case 0x70: branch_taken = getFlag(V); break;
            case 0x90: branch_taken = !getFlag(C); break;

после ликвидации данного возмущения в Силе, процесс на лад не пошел - все тот же экран, но уже другого цвета

a339818a8e34a529832ed2349a19b184.png

На данный процесс наложилось неуверенное состояние класса чипа VIC, который я несколько раз переписывал. Мне казалось что должно что-то выводится, просто VIC работает неверно. Это отчасти так, но анализ видеопамяти и обращение к таблице символов Cahracter ROM показало, что мой эмулятор верно заполняет экран пробелами, причем нужного цвета, как прописали разработчbки KERNAL ROM. Закономерный вывод - на каком-то этапе нарушается процесс выборки инструкций и процессор выполняет хрень. Или зацикливается, что я изначально отметал, памятуя о предыдущем опыте отладки.

Прыжок в торону бейсика начинается в KERNAL ROM с адреса 0xFCFF, где стоит безусловный джамп на адрес, читаемый из первой ячейки бейсика по адресу 0xA000

FCEF   8E 16 D0   STX $D016
FCF2   20 A3 FD   JSR $FDA3
FCF5   20 50 FD   JSR $FD50
FCF8   20 15 FD   JSR $FD15
FCFB   20 5B FF   JSR $FF5B
FCFE   58         CLI
FCFF   6C 00 A0   JMP ($A000)   ; start basic

Ну ок, брякнем условную точку останова на этот адрес. Но дело в том что условные брейкпоинты в условиях QtCreator, коим я давно и прочно пользуюсь сильно тупят. Поэтому был применен такой прием, в самом начале кода декодирования инструкций

mos6502.cpp

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int MOS6502::execInstruction()
{
    if (PC == 0xFF5E)
    {
        int a = 0;
    }

Как вы понимаете, бряк ставим на восьмую строку. И это быстро и безотказно работает, позволяя решить два вопроса: доходит или не доходит сюда выполнение кода, или затык сразу за этим адресом, что дальше, последующее пошаговой отладкой и выясняем.

Да, я честно крутил по шагам KERNAL ROM, сверяясь с листингом, раз за разом удивляясь как работает отлаженное ядро MOS 6502. Да, первый затык, с BMI, я выяснил именно таким способом, ибо процесс уходил бредить сразу после вызова подпрограммы по адресу 0xFCFB. Но исправление ошибки не принесло избавления.

Сидел я долго, переписывая в тетрадь все адреса, до которых удалось дошлепать

1e3e1754b9bdc37afb50252bcd704e2f.png

И, наконец-то я понял, что удачи мне не видать и вспомнил метод отладки, называемый трассировкой - запись в лог исполненных команд. Сказано - сделано. Вот такую примитивную трассировку я организовал

mos6502.cpp

uint16_t cur_PC = PC;

// Извлекаем из памяти код операции
uint8_t opcode = fetch();
int base_cycles = cycle_table[opcode];
int additional_cycles = 0;

std::cout << "PC: 0x" << std::hex << cur_PC << " opcode: 0x" << std::hex << (int) opcode << std::endl;

Меня, в общем, интересовал адрес перехода и опкод. Полноценный отладчик реализовать было некогда. И я даже не стал заморачиваться с выводом а файл - просто перенаправил процесс вывода программы в файл с помощью >.

Это дало лог, который сразу (!) вскрыл причину

PC: 0xea2c opcode: 0x9
PC: 0xea2e opcode: 0x85
PC: 0xea30 opcode: 0x60
PC: 0xff5e opcode: 0xad
PC: 0xff61 opcode: 0xd0
PC: 0xff5e opcode: 0xad
PC: 0xff61 opcode: 0xd0
PC: 0xff5e opcode: 0xad

Работал процессор-работал, а с адреса 0xFF5E залез в бесконечный цикл. Почему? Листинг в студию!

FF5B   20 18 E5   JSR $E518
FF5E   AD 12 D0   LDA $D012
FF61   D0 FB      BNE $FF5E

А потому что команда BNE работает в данном случае на ноль в аккумуляторе, который загружается значением по адресу 0xD012. И это, внезапно, адрес регистра видео-чипа VIC-II.

Оказалось, что данный регистр обнуляется чипом VIC-II, когда луч ЭЛТ, пробежав все 311 строк экрана доходит до конца, генерируя аппаратное прерывание. Опа! А прерываний то я не делал вообще! И самое прикольное, что выяснилось из инициализации регистров VIC - начальное значение данного регистра - 0x137.... что ровно 311 в десятиричной форме.

До реализации аппаратных прерываний у меня дело пока не дошло, поэтому я поступил жестоко - занулял данный в конце кадра (видимо, занулив навсегда...). Вот так

c64.cpp


        static int frame_counter = 0;

        if (++frame_counter % 30000 == 0)
        {
            vic.render(render);
            vic.regs[0x12] = 0x00; // ЗАЦИКЛИВАНИЕ ПОДАВЛЕНО ПРИНУДИТЕЛЬНО!!!
            //cpu.irq();
        }
    }

Ок, думаете после этого все стало работать и бейсик запустился? А черта с два! Затык нейросети, в реализации команды JMP по опкоду 0x6C свое дело сделал - процессор не туда побежал исполнять хрень.

Напомню, что джамп на бейсик идет по адресу, лежащему в нулевом бите BACIS ROM по адресу 0xA000. Исправлено, вот лог исправления. Это безусловный бред ИИ.

    // Безусловные переходы с абсолютной адрессацией
    case 0x4C: addr_absolute(); JMP(); return base_cycles + additional_cycles;
 -  case 0x6C: addr_abs = read16(PC); PC += 2; JMP(); return base_cycles + additional_cycles;
 +  case 0x6C:
 +   {
 +      uint16_t tmp_addr = read16(PC);
 +      addr_abs = read16(tmp_addr);
 +      JMP();
 +      return base_cycles + additional_cycles;
 +  }

И после этого... да, после этого случился взрыв мозга

2ab6a7e2f385a8593c355a5331c48b6d.png

Поделие вывело на экран что-то разумное, более того, бейсик у нас READY!

Итак, к исходу четвертого вечера я получил запуск бейсика из оригинального ROM. Так себе результат, но все же меня он порадовал. И пока я писал про отладку, меня посетила мысль, что описание VIC и визуализацию лучше оставить для новой статьи. Эта и так вышла довольно объемной.

Выводы

Итак - может ли ИИ заменить программиста? По опыту работы с бесплатными LLM могу сказать однозначно - не может. Аргументы, доказательства представлены выше:

  • LLM косячит, допуская ошибки в очевидном (пример с загрузкой бинарников)

  • LLMповторяет, с завидным упорством, неверную реализацию алгоритма

  • Зачастую, но не в данном случае, LLM не знакома с предметной областью

  • LLM плевать на архитектуру. Возможно мои промпты были примитивны, наверное стоит общаться с этим помощником поизящнее)

Допустимо ли применять средства, предоставляемые LLM в практической разработке. Ответ также однозначен - да! Аргументы:

  • LLM генерирует ко, похожий на рабочий, и это хорошая отправная точка

  • LLM ранее не усвоенную и не найденную информацию. Согласитесь, создать даже такое что создано в данной статье за четыре вечера... Вряд ли, знаю по опыту.

Я - сторонник прогресса во всех его формах и проявлениях. LLM, умеющие писать код - чудо нашего времени. Но выводы я сделаю, и надеюсь, они будут услышаны

  • LLM - это хороший интерактивный справочник. Это хороший источник ключевых слов для обычного примитивного (божечки, я это сказал!) "гугления". Мне, родившемуся при товарище Брежневе гугл до сих пор представляется чудом, если что

  • Всю выдачу кода не стоит копипастить, надо вдумчиво читать что вам предлагают

  • Извлекайте полезное, убивайте нещадно ущербное. Голова - главное оружие разработчика

В заключении, хочу сказать спасибо товарищу @kiltum - вы подняли актуальную тему и побудили лично меня к исследованиям. Удачи вам в ваших проектах!

У нас еще много вопросов. Тему видеочипа я отложил на следующую статью, заодно разберусь с обработкой прерываний. Возможно требуется инициализация и другого оборудования, но это пока предел того, чего я достиг.

Даю обещанную ссылку на репозиторий. Там можно по коммитам проследить путь мучений)

Всем спасибо за уделенной внимание! До новых встреч!

Источник

  • 25.05.26 12:25 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 25.05.26 20:55 luciajessy3

    After falling victim to a fake crypto investment platform, I lost nearly $73,000 in Ethereum. The scammers disappeared overnight, and I honestly thought my money was gone forever. A friend recommended ADAM WILSON and although I was hesitant at first, I decided to give it one last try. Their team handled my case professionally, kept me updated throughout the process, and used Blockchain tracing methods I didn’t even know were possible. Within weeks, they were able to help me recover my funds. I’m incredibly grateful for their dedication and transparency. If you’ve been scammed in crypto, don’t lose hope contact ADAMWILSON . TRADING @ CONSULTANT COM What's App / + 1 { 7 1 3 } 9 1 9 - 5 1 2 3

  • 25.05.26 20:55 luciajessy3

    After falling victim to a fake crypto investment platform, I lost nearly $73,000 in Ethereum. The scammers disappeared overnight, and I honestly thought my money was gone forever. A friend recommended ADAM WILSON and although I was hesitant at first, I decided to give it one last try. Their team handled my case professionally, kept me updated throughout the process, and used Blockchain tracing methods I didn’t even know were possible. Within weeks, they were able to help me recover my funds. I’m incredibly grateful for their dedication and transparency. If you’ve been scammed in crypto, don’t lose hope contact ADAMWILSON . TRADING @ CONSULTANT COM What's App / + 1 { 7 1 3 } 9 1 9 - 5 1 2 3

  • 25.05.26 20:55 luciajessy3

    After falling victim to a fake crypto investment platform, I lost nearly $73,000 in Ethereum. The scammers disappeared overnight, and I honestly thought my money was gone forever. A friend recommended ADAM WILSON and although I was hesitant at first, I decided to give it one last try. Their team handled my case professionally, kept me updated throughout the process, and used Blockchain tracing methods I didn’t even know were possible. Within weeks, they were able to help me recover my funds. I’m incredibly grateful for their dedication and transparency. If you’ve been scammed in crypto, don’t lose hope contact ADAMWILSON . TRADING @ CONSULTANT COM What's App / + 1 { 7 1 3 } 9 1 9 - 5 1 2 3

  • 25.05.26 20:55 luciajessy3

    After falling victim to a fake crypto investment platform, I lost nearly $73,000 in Ethereum. The scammers disappeared overnight, and I honestly thought my money was gone forever. A friend recommended ADAM WILSON and although I was hesitant at first, I decided to give it one last try. Their team handled my case professionally, kept me updated throughout the process, and used Blockchain tracing methods I didn’t even know were possible. Within weeks, they were able to help me recover my funds. I’m incredibly grateful for their dedication and transparency. If you’ve been scammed in crypto, don’t lose hope contact ADAMWILSON . TRADING @ CONSULTANT COM What's App / + 1 { 7 1 3 } 9 1 9 - 5 1 2 3

  • 26.05.26 14:45 kimberlyhebert786

    I invested in bitcoin trading After losing $78.4 USDT) linked to a romance fraud scam worth of cryptocurrency through an online investment platform and later discovered it was a scam. After extensive research for recovery options, I contacted CAPITAL CRYPTO RECOVER based on positive client reviews and recommendations. Their professional security team guided me through the recovery process using advanced technology, and I was able to recover my lost cryptocurrency successfully. I am truly grateful for their support and assistance during such a difficult experience. I will advise you to contact CAPITAL CRYPTO RECOVER helped me recover my funds. For anyone facing similar issues, Website: https://recovercapital.wixsite.com/capital-crypto-rec-1 Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text Number: +1 (336) 390-6684

  • 26.05.26 14:45 kimberlyhebert786

    I invested in bitcoin trading After losing $78.4 USDT) linked to a romance fraud scam worth of cryptocurrency through an online investment platform and later discovered it was a scam. After extensive research for recovery options, I contacted CAPITAL CRYPTO RECOVER based on positive client reviews and recommendations. Their professional security team guided me through the recovery process using advanced technology, and I was able to recover my lost cryptocurrency successfully. I am truly grateful for their support and assistance during such a difficult experience. I will advise you to contact CAPITAL CRYPTO RECOVER helped me recover my funds. For anyone facing similar issues, Website: https://recovercapital.wixsite.com/capital-crypto-rec-1 Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text Number: +1 (336) 390-6684

  • 28.05.26 03:09 kientadams11

    Lot of people have lost money to scammers in so many ways which, I have been a victim as well of over 30 thousand pounds, this scammers are smart they create fake investment website, fake recovery site to swindle people of their Bitcoin. I found recoverydarek at G (M) (A) (I) (L) on Trust pilot who was able to track, investigate and expose this scammers and re coupled my funds back to me within 24 hours.

  • 28.05.26 03:09 kientadams11

    Lot of people have lost money to scammers in so many ways which, I have been a victim as well of over 30 thousand pounds, this scammers are smart they create fake investment website, fake recovery site to swindle people of their Bitcoin. I found recoverydarek at G (M) (A) (I) (L) on Trust pilot who was able to track, investigate and expose this scammers and re coupled my funds back to me within 24 hours.

  • 28.05.26 04:01 luciajessy3

    After falling victim to a fake crypto investment platform, I lost nearly $73,000 in Ethereum. The scammers disappeared overnight, and I honestly thought my money was gone forever. A friend recommended ADAM WILSON and although I was hesitant at first, I decided to give it one last try. Their team handled my case professionally, kept me updated throughout the process, and used Blockchain tracing methods I didn’t even know were possible. Within weeks, they were able to help me recover my funds. I’m incredibly grateful for their dedication and transparency. If you’ve been scammed in crypto, don’t lose hope contact ADAMWILSON . TRADING @ CONSULTANT COM What's App / + 1 { 7 1 3 } 9 1 9 - 5 1 2 3

  • 28.05.26 09:40 kientadams11

    Lot of people have lost money to scammers in so many ways which, I have been a victim as well of over 30 thousand pounds, this scammers are smart they create fake investment website, fake recovery site to swindle people of their Bitcoin. I found recoverydarek at G (M) (A) (I) (L) on Trust pilot who was able to track, investigate and expose this scammers and re coupled my funds back to me within 24 hours.

  • 28.05.26 14:04 Frankmilton

    Losing any Scent on the dollar hurts like a bad stomach ache from eating from the wrong MaC.Donalds. This stablecoin stays near one dollar. Traders use it to swap for Bitcoin or Ethereum without big price jumps. New users pick it first for its ease. Banks hold cash reserves to back it up. Losses hit fast. A wrong wallet address sends coins to strangers. Scams on Telegram steal seed phrases. DeFi bugs or hacks drain funds. Billions vanish each year from these mistakes. Blockchains track every step. Copy your transaction hash. Check it on Etherscan. Follow the trail to the wallet or contract. [email protected] +(44 7476618364) can help. Her team hunts funds across chains. They work with exchanges and devs to get assets back. People recover thousands of assets already even after being lost for years of failed agency and fake recovery experts. also teaches safety. Spot phishing in MetaMask. Secure your Ledger. Trade safe on Binance or Uniswap. Fix rookie slips into smart habits.

  • 28.05.26 18:53 kimberlyhebert786

    I invested in bitcoin trading After losing $78.4 USDT) linked to a romance fraud scam worth of cryptocurrency through an online investment platform and later discovered it was a scam. After extensive research for recovery options, I contacted CAPITAL CRYPTO RECOVER based on positive client reviews and recommendations. Their professional security team guided me through the recovery process using advanced technology, and I was able to recover my lost cryptocurrency successfully. I am truly grateful for their support and assistance during such a difficult experience. I will advise you to contact CAPITAL CRYPTO RECOVER helped me recover my funds. For anyone facing similar issues, Website: https://recovercapital.wixsite.com/capital-crypto-rec-1 Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text Number: +1 (336) 390-6684

  • 28.05.26 18:53 kimberlyhebert786

    I invested in bitcoin trading After losing $78.4 USDT) linked to a romance fraud scam worth of cryptocurrency through an online investment platform and later discovered it was a scam. After extensive research for recovery options, I contacted CAPITAL CRYPTO RECOVER based on positive client reviews and recommendations. Their professional security team guided me through the recovery process using advanced technology, and I was able to recover my lost cryptocurrency successfully. I am truly grateful for their support and assistance during such a difficult experience. I will advise you to contact CAPITAL CRYPTO RECOVER helped me recover my funds. For anyone facing similar issues, Website: https://recovercapital.wixsite.com/capital-crypto-rec-1 Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text Number: +1 (336) 390-6684

  • 28.05.26 21:56 Frankmilton

    Losing any Scent on the dollar hurts like a bad stomach ache from eating from the wrong MaC.Donalds. This stablecoin stays near one dollar. Traders use it to swap for Bitcoin or Ethereum without big price jumps. New users pick it first for its ease. Banks hold cash reserves to back it up. Losses hit fast. A wrong wallet address sends coins to strangers. Scams on Telegram steal seed phrases. DeFi bugs or hacks drain funds. Billions vanish each year from these mistakes. Blockchains track every step. Copy your transaction hash. Check it on Etherscan. Follow the trail to the wallet or contract. [email protected] +(44 7476618364) can help. Her team hunts funds across chains. They work with exchanges and devs to get assets back. People recover thousands of assets already even after being lost for years of failed agency and fake recovery experts. also teaches safety. Spot phishing in MetaMask. Secure your Ledger. Trade safe on Binance or Uniswap. Fix rookie slips into smart habits.

  • 29.05.26 02:26 luciajessy3

    After falling victim to a fake crypto investment platform, I lost nearly $73,000 in Ethereum. The scammers disappeared overnight, and I honestly thought my money was gone forever. A friend recommended ADAM WILSON and although I was hesitant at first, I decided to give it one last try. Their team handled my case professionally, kept me updated throughout the process, and used Blockchain tracing methods I didn’t even know were possible. Within weeks, they were able to help me recover my funds. I’m incredibly grateful for their dedication and transparency. If you’ve been scammed in crypto, don’t lose hope contact ADAMWILSON . TRADING @ CONSULTANT COM What's App / + 1 { 7 1 3 } 9 1 9 - 5 1 2 3

  • 29.05.26 02:27 luciajessy3

    After falling victim to a fake crypto investment platform, I lost nearly $73,000 in Ethereum. The scammers disappeared overnight, and I honestly thought my money was gone forever. A friend recommended ADAM WILSON and although I was hesitant at first, I decided to give it one last try. Their team handled my case professionally, kept me updated throughout the process, and used Blockchain tracing methods I didn’t even know were possible. Within weeks, they were able to help me recover my funds. I’m incredibly grateful for their dedication and transparency. If you’ve been scammed in crypto, don’t lose hope contact ADAMWILSON . TRADING @ CONSULTANT COM What's App / + 1 { 7 1 3 } 9 1 9 - 5 1 2 3

  • 29.05.26 04:46 Frankmilton

    Losing any Scent on the dollar hurts like a bad stomach ache from eating from the wrong MaC.Donalds. This stablecoin stays near one dollar. Traders use it to swap for Bitcoin or Ethereum without big price jumps. New users pick it first for its ease. Banks hold cash reserves to back it up. Losses hit fast. A wrong wallet address sends coins to strangers. Scams on Telegram steal seed phrases. DeFi bugs or hacks drain funds. Billions vanish each year from these mistakes. Blockchains track every step. Copy your transaction hash. Check it on Etherscan. Follow the trail to the wallet or contract. [email protected] +(44 7476618364) can help. Her team hunts funds across chains. They work with exchanges and devs to get assets back. People recover thousands of assets already even after being lost for years of failed agency and fake recovery experts. also teaches safety. Spot phishing in MetaMask. Secure your Ledger. Trade safe on Binance or Uniswap. Fix rookie slips into smart habits

  • 31.05.26 10:06 wendytaylor015

    My name is Wendy Taylor, I'm from Los Angeles, i want to announce to you Viewer how Capital Crypto Recover help me to restore my Lost Bitcoin, I invested with a Crypto broker without proper research to know what I was hoarding my hard-earned money into scammers, i lost access to my crypto wallet or had your funds stolen? Don’t worry Capital Crypto Recover is here to help you recover your cryptocurrency with cutting-edge technical expertise, With years of experience in the crypto world, Capital Crypto Recover employs the best latest tools and ethical hacking techniques to help you recover lost assets, unlock hacked accounts, Whether it’s a forgotten password, Capital Crypto Recover has the expertise to help you get your crypto back. a security company service that has a 100% success rate in the recovery of crypto assets, i lost wallet and hacked accounts. I provided them the information they requested and they began their investigation. To my surprise, Capital Crypto Recover was able to trace and recover my crypto assets successfully within 24hours. Thank you for your service in helping me recover my $647,734 worth of crypto funds and I highly recommend their recovery services, they are reliable and a trusted company to any individuals looking to recover lost money. Contact email [email protected] OR Telegram @Capitalcryptorecover Call/Text Number +1 (336)390-6684 his contact: [email protected] His website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 31.05.26 10:06 wendytaylor015

    My name is Wendy Taylor, I'm from Los Angeles, i want to announce to you Viewer how Capital Crypto Recover help me to restore my Lost Bitcoin, I invested with a Crypto broker without proper research to know what I was hoarding my hard-earned money into scammers, i lost access to my crypto wallet or had your funds stolen? Don’t worry Capital Crypto Recover is here to help you recover your cryptocurrency with cutting-edge technical expertise, With years of experience in the crypto world, Capital Crypto Recover employs the best latest tools and ethical hacking techniques to help you recover lost assets, unlock hacked accounts, Whether it’s a forgotten password, Capital Crypto Recover has the expertise to help you get your crypto back. a security company service that has a 100% success rate in the recovery of crypto assets, i lost wallet and hacked accounts. I provided them the information they requested and they began their investigation. To my surprise, Capital Crypto Recover was able to trace and recover my crypto assets successfully within 24hours. Thank you for your service in helping me recover my $647,734 worth of crypto funds and I highly recommend their recovery services, they are reliable and a trusted company to any individuals looking to recover lost money. Contact email [email protected] OR Telegram @Capitalcryptorecover Call/Text Number +1 (336)390-6684 his contact: [email protected] His website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 05.06.26 18:26 edengarcia

    When most people hear the words crypto recovery service, their guard immediately goes up—and for good reason. In today’s online environment, finding a legitimate service feels like finding a needle in a haystack. Ask about trusted crypto recovery on any major forum, and you’ll be met with hostility. It’s become a cultural bias that victims often prefer filing police reports rather than seeking private help, fearing that speaking openly will only attract more scammers. But silence doesn’t bring your funds back. Website https://techyforcecyberretrieval.com Whatsapp +15617263697 The reality is harsh: Less than 10% of “recovery agencies” online are genuine. Fraudsters have mastered the art of mimicking trust. So, how do you separate the wolves from the professionals? The Golden Rule: No Upfront Fees If there is one sign that separates a scam from a legitimate operation, it is the payment model. Legitimate recovery companies never ask for upfront fees. Predatory scams will demand "processing fees," "software licenses," or "tax payments" before they lift a finger. A genuine agency knows its value lies in results, not promises. They operate on a success-based fee —typically around 10% of the recovered amount. Simply put: No recovery, no payment. Enter TechY Force Cyber Retrieval At TechY Force Cyber Retrieval, we understand why you’re skeptical. We built our model to eliminate that risk. We specialize in the fast, forensic tracking of lost crypto assets. Because we are confident in our technology and methodology, we don’t need your money to start working—we need your trust. We only get paid once you receive your crypto. How to Spot a Legitimate Partner Beyond the fee structure, keep these signs in mind: 1. Transparency: They explain how without asking for your private keys or seed phrase. 2. Realism: They don’t promise 100% success on impossible cases but offer honest assessments. 3. Speed: Time is critical in blockchain tracing. Legitimate firms act fast. Website https://techyforcecyberretrieval.com Whatsapp +15617263697 Don’t let the fear of secondary scams prevent you from seeking justice. Choose a partner who puts their money where their mouth is. TechY Force Cyber Retrieval: Fast. Secure. Success-based. Disclaimer: Always conduct your own due diligence. Legitimate firms will never ask for your wallet credentials.

  • 07.06.26 08:58 keithwilson9899

    ETHEREUM RECOVERY ASSISTANCE: CAPITAL CRYPTO RECOVER HELPED ME RECOVER $98,000 WORTH OF LOST ETH In cases of cryptocurrency scams, having accurate information and trusted support is essential. I would like to recommend Capital Crypto Recover Service, a professional team that specializes in assisting individuals with the recovery of lost or stolen Bitcoin and Ethereum (ETH). Their experienced experts are dedicated to helping victims of digital asset fraud by carefully analyzing each case, developing strategic recovery plans, Capital Crypto Recover Service knowledgeable team's primary goals are to satisfy clients and offer significant support and working diligently toward fund retrieval. The team is committed to providing reliable assistance and maintaining a high level of client satisfaction. Based on my assessment, their reputation professionalism and a strong commitment to their clients. If you have experienced a cryptocurrency loss, you can contacting them for further assistance Phone (Call/Text): +1 (336) 390-6684 Email: [email protected] Alternate Email: [email protected] Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 07.06.26 08:58 keithwilson9899

    ETHEREUM RECOVERY ASSISTANCE: CAPITAL CRYPTO RECOVER HELPED ME RECOVER $98,000 WORTH OF LOST ETH In cases of cryptocurrency scams, having accurate information and trusted support is essential. I would like to recommend Capital Crypto Recover Service, a professional team that specializes in assisting individuals with the recovery of lost or stolen Bitcoin and Ethereum (ETH). Their experienced experts are dedicated to helping victims of digital asset fraud by carefully analyzing each case, developing strategic recovery plans, Capital Crypto Recover Service knowledgeable team's primary goals are to satisfy clients and offer significant support and working diligently toward fund retrieval. The team is committed to providing reliable assistance and maintaining a high level of client satisfaction. Based on my assessment, their reputation professionalism and a strong commitment to their clients. If you have experienced a cryptocurrency loss, you can contacting them for further assistance Phone (Call/Text): +1 (336) 390-6684 Email: [email protected] Alternate Email: [email protected] Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 07.06.26 21:00 gordondowney9

    Email: [email protected] Telegram —digitallightsolution, https://t.me/digitallightsolution Losing my USDT to a fraudulent cryptocurrency platform was one of the most painful and overwhelming experiences I have ever faced. I felt devastated, confused, and ashamed that something I had placed my trust in had turned out to be a scam. For a while, I did not know where to turn or whether there was any real hope of recovering what I had lost. During that very difficult time, a trusted pastor recommended Digital-Light-Solution, and although I was hesitant at first, I decided to visit their website https://digitallightsolution.com/. From my first interaction with them, I felt a sense of relief. They listened to my situation with patience and understanding, and they treated me with kindness at a time when I felt completely broken. Their team explained the process clearly, answered my questions, and kept me informed throughout. What meant the most to me was not just their professionalism, but the way they made me feel supported when I was struggling emotionally. As the process continued, I began to regain a sense of hope. They remained consistent, responsive, and committed to my case, which gave me comfort during an incredibly stressful period. In the end, Digital-Light-Solutions was able to assist with tracing my lost USDT and supporting the recovery process. The relief my family and I felt is difficult to put into words. I will always be grateful for the support, compassion, and professionalism they showed me during one of the hardest moments of my life, I highly recommend their services to anyone in need. Contact them today for assistance

  • 07.06.26 21:00 gordondowney9

    Email: [email protected] Telegram —digitallightsolution, https://t.me/digitallightsolution Losing my USDT to a fraudulent cryptocurrency platform was one of the most painful and overwhelming experiences I have ever faced. I felt devastated, confused, and ashamed that something I had placed my trust in had turned out to be a scam. For a while, I did not know where to turn or whether there was any real hope of recovering what I had lost. During that very difficult time, a trusted pastor recommended Digital-Light-Solution, and although I was hesitant at first, I decided to visit their website https://digitallightsolution.com/. From my first interaction with them, I felt a sense of relief. They listened to my situation with patience and understanding, and they treated me with kindness at a time when I felt completely broken. Their team explained the process clearly, answered my questions, and kept me informed throughout. What meant the most to me was not just their professionalism, but the way they made me feel supported when I was struggling emotionally. As the process continued, I began to regain a sense of hope. They remained consistent, responsive, and committed to my case, which gave me comfort during an incredibly stressful period. In the end, Digital-Light-Solutions was able to assist with tracing my lost USDT and supporting the recovery process. The relief my family and I felt is difficult to put into words. I will always be grateful for the support, compassion, and professionalism they showed me during one of the hardest moments of my life, I highly recommend their services to anyone in need. Contact them today for assistance

  • 07.06.26 21:02 gordondowney9

    Email: [email protected] Telegram —digitallightsolution, https://t.me/digitallightsolution Losing my USDT to a fraudulent cryptocurrency platform was one of the most painful and overwhelming experiences I have ever faced. I felt devastated, confused, and ashamed that something I had placed my trust in had turned out to be a scam. For a while, I did not know where to turn or whether there was any real hope of recovering what I had lost. During that very difficult time, a trusted pastor recommended Digital-Light-Solution, and although I was hesitant at first, I decided to visit their website https://digitallightsolution.com/. From my first interaction with them, I felt a sense of relief. They listened to my situation with patience and understanding, and they treated me with kindness at a time when I felt completely broken. Their team explained the process clearly, answered my questions, and kept me informed throughout. What meant the most to me was not just their professionalism, but the way they made me feel supported when I was struggling emotionally. As the process continued, I began to regain a sense of hope. They remained consistent, responsive, and committed to my case, which gave me comfort during an incredibly stressful period. In the end, Digital-Light-Solutions was able to assist with tracing my lost USDT and supporting the recovery process. The relief my family and I felt is difficult to put into words. I will always be grateful for the support, compassion, and professionalism they showed me during one of the hardest moments of my life, I highly recommend their services to anyone in need. Contact them today for assistance

  • 07.06.26 21:02 gordondowney9

    Email: [email protected] Telegram —digitallightsolution, https://t.me/digitallightsolution Losing my USDT to a fraudulent cryptocurrency platform was one of the most painful and overwhelming experiences I have ever faced. I felt devastated, confused, and ashamed that something I had placed my trust in had turned out to be a scam. For a while, I did not know where to turn or whether there was any real hope of recovering what I had lost. During that very difficult time, a trusted pastor recommended Digital-Light-Solution, and although I was hesitant at first, I decided to visit their website https://digitallightsolution.com/. From my first interaction with them, I felt a sense of relief. They listened to my situation with patience and understanding, and they treated me with kindness at a time when I felt completely broken. Their team explained the process clearly, answered my questions, and kept me informed throughout. What meant the most to me was not just their professionalism, but the way they made me feel supported when I was struggling emotionally. As the process continued, I began to regain a sense of hope. They remained consistent, responsive, and committed to my case, which gave me comfort during an incredibly stressful period. In the end, Digital-Light-Solutions was able to assist with tracing my lost USDT and supporting the recovery process. The relief my family and I felt is difficult to put into words. I will always be grateful for the support, compassion, and professionalism they showed me during one of the hardest moments of my life, I highly recommend their services to anyone in need. Contact them today for assistance

  • 07.06.26 21:03 gordondowney9

    Email: [email protected] Telegram —digitallightsolution, https://t.me/digitallightsolution Losing my USDT to a fraudulent cryptocurrency platform was one of the most painful and overwhelming experiences I have ever faced. I felt devastated, confused, and ashamed that something I had placed my trust in had turned out to be a scam. For a while, I did not know where to turn or whether there was any real hope of recovering what I had lost. During that very difficult time, a trusted pastor recommended Digital-Light-Solution, and although I was hesitant at first, I decided to visit their website https://digitallightsolution.com/. From my first interaction with them, I felt a sense of relief. They listened to my situation with patience and understanding, and they treated me with kindness at a time when I felt completely broken. Their team explained the process clearly, answered my questions, and kept me informed throughout. What meant the most to me was not just their professionalism, but the way they made me feel supported when I was struggling emotionally. As the process continued, I began to regain a sense of hope. They remained consistent, responsive, and committed to my case, which gave me comfort during an incredibly stressful period. In the end, Digital-Light-Solutions was able to assist with tracing my lost USDT and supporting the recovery process. The relief my family and I felt is difficult to put into words. I will always be grateful for the support, compassion, and professionalism they showed me during one of the hardest moments of my life, I highly recommend their services to anyone in need. Contact them today for assistance

  • 07.06.26 21:04 gordondowney9

    Email: [email protected] Telegram —digitallightsolution, https://t.me/digitallightsolution Losing my USDT to a fraudulent cryptocurrency platform was one of the most painful and overwhelming experiences I have ever faced. I felt devastated, confused, and ashamed that something I had placed my trust in had turned out to be a scam. For a while, I did not know where to turn or whether there was any real hope of recovering what I had lost. During that very difficult time, a trusted pastor recommended Digital-Light-Solution, and although I was hesitant at first, I decided to visit their website https://digitallightsolution.com/. From my first interaction with them, I felt a sense of relief. They listened to my situation with patience and understanding, and they treated me with kindness at a time when I felt completely broken. Their team explained the process clearly, answered my questions, and kept me informed throughout. What meant the most to me was not just their professionalism, but the way they made me feel supported when I was struggling emotionally. As the process continued, I began to regain a sense of hope. They remained consistent, responsive, and committed to my case, which gave me comfort during an incredibly stressful period. In the end, Digital-Light-Solutions was able to assist with tracing my lost USDT and supporting the recovery process. The relief my family and I felt is difficult to put into words. I will always be grateful for the support, compassion, and professionalism they showed me during one of the hardest moments of my life, I highly recommend their services to anyone in need. Contact them today for assistance

  • 10.06.26 06:21 wendytaylor015

    My name is Wendy Taylor, I'm from Los Angeles, i want to announce to you Viewer how Capital Crypto Recover help me to restore my Lost Bitcoin, I invested with a Crypto broker without proper research to know what I was hoarding my hard-earned money into scammers, i lost access to my crypto wallet or had your funds stolen? Don’t worry Capital Crypto Recover is here to help you recover your cryptocurrency with cutting-edge technical expertise, With years of experience in the crypto world, Capital Crypto Recover employs the best latest tools and ethical hacking techniques to help you recover lost assets, unlock hacked accounts, Whether it’s a forgotten password, Capital Crypto Recover has the expertise to help you get your crypto back. a security company service that has a 100% success rate in the recovery of crypto assets, i lost wallet and hacked accounts. I provided them the information they requested and they began their investigation. To my surprise, Capital Crypto Recover was able to trace and recover my crypto assets successfully within 24hours. Thank you for your service in helping me recover my $647,734 worth of crypto funds and I highly recommend their recovery services, they are reliable and a trusted company to any individuals looking to recover lost money. Contact email [email protected] OR Telegram @Capitalcryptorecover Call/Text Number +1 (336)390-6684 his contact: [email protected] His website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 10.06.26 06:21 wendytaylor015

    My name is Wendy Taylor, I'm from Los Angeles, i want to announce to you Viewer how Capital Crypto Recover help me to restore my Lost Bitcoin, I invested with a Crypto broker without proper research to know what I was hoarding my hard-earned money into scammers, i lost access to my crypto wallet or had your funds stolen? Don’t worry Capital Crypto Recover is here to help you recover your cryptocurrency with cutting-edge technical expertise, With years of experience in the crypto world, Capital Crypto Recover employs the best latest tools and ethical hacking techniques to help you recover lost assets, unlock hacked accounts, Whether it’s a forgotten password, Capital Crypto Recover has the expertise to help you get your crypto back. a security company service that has a 100% success rate in the recovery of crypto assets, i lost wallet and hacked accounts. I provided them the information they requested and they began their investigation. To my surprise, Capital Crypto Recover was able to trace and recover my crypto assets successfully within 24hours. Thank you for your service in helping me recover my $647,734 worth of crypto funds and I highly recommend their recovery services, they are reliable and a trusted company to any individuals looking to recover lost money. Contact email [email protected] OR Telegram @Capitalcryptorecover Call/Text Number +1 (336)390-6684 his contact: [email protected] His website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 10.06.26 18:09 david

    Look, engaging with the authorities is a marathon, not a sprint. By methodically filing these reports, you’re not just fighting for your own funds—you’re contributing to the broader battle against crypto crime. For a deeper dive into what to do after a theft, check out [email protected] for complete guide on how to recover stolen crypto

  • 12.06.26 17:13 keithwilson9899

    ETHEREUM RECOVERY ASSISTANCE: CAPITAL CRYPTO RECOVER HELPED ME RECOVER $98,000 WORTH OF LOST ETH In cases of cryptocurrency scams, having accurate information and trusted support is essential. I would like to recommend Capital Crypto Recover Service, a professional team that specializes in assisting individuals with the recovery of lost or stolen Bitcoin and Ethereum (ETH). Their experienced experts are dedicated to helping victims of digital asset fraud by carefully analyzing each case, developing strategic recovery plans, Capital Crypto Recover Service knowledgeable team's primary goals are to satisfy clients and offer significant support and working diligently toward fund retrieval. The team is committed to providing reliable assistance and maintaining a high level of client satisfaction. Based on my assessment, their reputation professionalism and a strong commitment to their clients. If you have experienced a cryptocurrency loss, you can contacting them for further assistance Phone (Call/Text): +1 (336) 390-6684 Email: [email protected] Alternate Email: [email protected] Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 12.06.26 17:13 keithwilson9899

    ETHEREUM RECOVERY ASSISTANCE: CAPITAL CRYPTO RECOVER HELPED ME RECOVER $98,000 WORTH OF LOST ETH In cases of cryptocurrency scams, having accurate information and trusted support is essential. I would like to recommend Capital Crypto Recover Service, a professional team that specializes in assisting individuals with the recovery of lost or stolen Bitcoin and Ethereum (ETH). Their experienced experts are dedicated to helping victims of digital asset fraud by carefully analyzing each case, developing strategic recovery plans, Capital Crypto Recover Service knowledgeable team's primary goals are to satisfy clients and offer significant support and working diligently toward fund retrieval. The team is committed to providing reliable assistance and maintaining a high level of client satisfaction. Based on my assessment, their reputation professionalism and a strong commitment to their clients. If you have experienced a cryptocurrency loss, you can contacting them for further assistance Phone (Call/Text): +1 (336) 390-6684 Email: [email protected] Alternate Email: [email protected] Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 14.06.26 14:53 Freeman James

    Recently, I was scammed out of $332,000 in a fraudulent Bitcoin investment scheme. This devastating loss added significant stress to my already difficult health challenges, as I was also facing surgery expenses for cancer. Desperate to recover my funds, I spent countless hours researching and speaking with other victims. That effort led me to a Google post that revealed the excellent reputation of FundsRetriever. Only after many hours of digging and consulting others did I learn about their stellar track record. I decided to contact them because of their successful recovery history and encouraging client testimonials. I had no idea that this decision would become the turning point in my fight against cryptocurrency theft. Thanks to their expert team, I was able to recover my lost funds. The process was complex, but FundsRetriever's commitment to using the latest technology ensured a successful outcome. I highly recommend their services to anyone who has fallen victim to cryptocurrency fraud. For assistance, contact: 📧 [email protected] 📞 WhatsApp: +1 603 512 144 8, Telegram: @FundsRetriever

  • 14.06.26 15:37 kimberlyhebert786

    I invested in bitcoin trading After losing $78.4 USDT) linked to a romance fraud scam worth of cryptocurrency through an online investment platform and later discovered it was a scam. After extensive research for recovery options, I contacted CAPITAL CRYPTO RECOVER based on positive client reviews and recommendations. Their professional security team guided me through the recovery process using advanced technology, and I was able to recover my lost cryptocurrency successfully. I am truly grateful for their support and assistance during such a difficult experience. I will advise you to contact CAPITAL CRYPTO RECOVER helped me recover my funds. For anyone facing similar issues, Website: https://recovercapital.wixsite.com/capital-crypto-rec-1 Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text Number: +1 (336) 390-6684

  • 14.06.26 15:37 kimberlyhebert786

    I invested in bitcoin trading After losing $78.4 USDT) linked to a romance fraud scam worth of cryptocurrency through an online investment platform and later discovered it was a scam. After extensive research for recovery options, I contacted CAPITAL CRYPTO RECOVER based on positive client reviews and recommendations. Their professional security team guided me through the recovery process using advanced technology, and I was able to recover my lost cryptocurrency successfully. I am truly grateful for their support and assistance during such a difficult experience. I will advise you to contact CAPITAL CRYPTO RECOVER helped me recover my funds. For anyone facing similar issues, Website: https://recovercapital.wixsite.com/capital-crypto-rec-1 Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text Number: +1 (336) 390-6684

  • 14.06.26 16:34 Emmi Hakola

    I’m open about my experience with Bitcoin investment and losing money to scammers. That said, it is possible to recover stolen Bitcoin. I used to think recovery was impossible because that’s what I had been told. But last October, I fell for a forex scam promising extremely high returns and ended up losing nearly $87,600. After searching for help for a month, I came across a Reddit article about recovering stolen cryptocurrency. I reached out to the contact provided: [email protected] and WhatsApp +19852969146. I was scared and skeptical, having heard many bad stories, but I decided to give them a try. To my amazement, I got all my stolen Bitcoin back within a very short time. I’m not sure if I’m allowed to post links here, but you can reach out to them if you also need help.

  • 14.06.26 16:53 James willson

    I lost $328,650 to a fraudulent website that claimed to be a legitimate investment platform offering high returns. I was drawn in by the desire to earn more for myself and my family. Unfortunately, by the end of 2024, I realized it was a scam when the broker stopped responding to my emails and messages. A colleague then introduced me to ResQPro Firm, and to my surprise, they were able to trace and recover my stolen funds. Contact them at: resqprofirm AT AOL dot com | WhatsApp: +1 985 296 9146 | Telegram: ResQproFirm

  • 14.06.26 19:38 riley777

    G`DAY, I lost more than 119,000 Australian dollars to a crypto scam and it took almost everything I had saved which left me feeling like I had no future. I was stuck. I did not know where to go or how to find the money again. The wallet company is no help at all and they make it so hard to see where the coins go once they leave your account so you just feel lost. I spent days looking for a way out. Then I saw a post for a person who finds stolen money. The ad said they can track any crypto that goes missing. I wanted to check if it was real. I sent an email to [email protected] +44//// 7476618364\ to see if they could help me get my funds back. They did an amazing job. My money was back in my account in less than a week after they did a fast search and return.

  • 15.06.26 06:12 Evan Garrison

    When investing in staking platforms, proceed with caution. If your funds are stolen by a fake staking pool, the experience can be very frustrating. Rather than giving in to frustration, it's important to act quickly to improve your chances of recovering your money. Unfortunately, many victims never get their money back because scammers are often in another country or using fake identities. However, in some cases, tracking the funds is easier, especially for smart contract forensics specialists. I lost €18,500 to StakeKing. FundsRetriever found a backdoor in the contract and recovered my stake. Contact [email protected], WhatsApp +1(603)5121(448), or Telegram FUNDSRETRIEVER for assistance.

  • 15.06.26 06:25 Glenn robble

    Stop putting money into platforms promising guaranteed monthly returns of 10%, 20%, or more. These are Ponzi schemes. Your "profits" are just other victims' deposits. The moment withdrawals slow down, the scam is about to collapse. If you already have money trapped, do not send more to "unlock" your funds. That is a second scam. Instead, gather all transaction hashes and wallet addresses. Bitcoin Evolution Pro took €25,000 from me. FundsRetriever traced the funds through KYC exchanges and recovered my principal. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 06:34 Sallymarch

    If IQ Option or any similar platform blocks your withdrawal citing "bonus terms" or "abnormal activity," do not argue with their chat support. They are not empowered to help you. Instead, request all trade logs and bonus terms in writing. Then get FundsRetrievers forensic specialist to audit your account. IQ Option held my €9,200 for two months. FundsRetriever reviewed my case, identified regulatory violations, and secured my full payout within 72 hours. Professional pressure works. Do it immediately. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 06:38 Sallymarch

    If IQ Option or any similar platform blocks your withdrawal citing "bonus terms" or "abnormal activity," do not argue with their chat support. They are not empowered to help you. Instead, request all trade logs and bonus terms in writing. Then get FundsRetrievers forensic specialist to audit your account. IQ Option held my €9,200 for two months. FundsRetriever reviewed my case, identified regulatory violations, and secured my full payout within 72 hours. Professional pressure works. Do it immediately. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 06:41 Ewaguz

    Cloud mining contracts are almost always too good to be true. I learned that the hard way with MineMax. First two months, small daily payouts. Then "maintenance fees" ate everything. Then my account was frozen. Then the website disappeared. I was heartbroken. FundsRetriever traced my payments through three shell companies to a real bank account. They froze it and got my €11,000 back. Recovery is possible even from complex scams. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 12:49 Jason

    Did a scammer take your money? Fake loan, crypto fraud, romance trap, phishing—they count on you feeling helpless. Prove them wrong. FundsRetriever recovers stolen digital assets fast. No upfront payment. Ever. Backed by the FBI, Interpol, and cybercrime units. Blockchain tracing, legal freezing, and full recovery—for Bitcoin, Ethereum, USDT, Ponzi schemes, you name it. Your move: get a free case review right now. Then forensics, legal action, and your funds back. ⏳ Time is everything. 📧 FUNDSRETRIEVER @ PROTON.ME 📞 +16035121448 (WhatsApp) 📱 Telegram: @FUNDSRETRIEVER

  • 15.06.26 12:56 Hillary

    As a blockchain forensic analyst, I’ve reviewed numerous recovery cases. Fundsretriever demonstrates proper on-chain tracing, evidence preservation, and legal coordination. Their methodology helped several of my clients retrieve stolen or stuck assets. Recommended for victims seeking verifiable solutions. 📧 [email protected] Telegram @FUNDSRETRIEVER WhatsApp +1 603 512 1448

  • 15.06.26 13:03 Feliksa Stegniy

    A woman added me on Facebook, and after she suggested we become friends, we started communicating. Over time, she introduced me to a crypto trading platform called btctradingfx.com. She shared a lot of information about it, along with screenshots that made the platform seem trustworthy. Convinced by her claims, I decided to give it a try. I was promised a 10% weekly return, so I made an initial investment of $500. To my surprise, I received $5,000 back. That success encouraged me to invest more, so I put in $20,000. But when I tried to withdraw my funds, I was denied access and told I needed to deposit even more money before I could make a withdrawal. In the end, I lost a total of $43,850. It was an extremely difficult and painful experience. Fortunately, I later found a professional recovery service called ResQprofirm while searching on Google. I contacted them and provided all the evidence I had. They took my case seriously and were able to track down and recover my capital from the platform, which had been inaccessible for a long time. If you find yourself in a similar situation, you might consider reaching out to them via email at [email protected] or on WhatsApp at +19852969146, Telegram @resqprofirm Thank you, ResQPro, for your support.

  • 15.06.26 13:05 James willson

    The Most Credible Crypto Recovery Service: RESQPROFIRM RESQPROFIRM is a reliable, legitimate company that helps recover lost cryptocurrency assets. After weeks of doubting whether my lost BTC could ever be restored, I realized how widespread crypto scams have become. Caution is essential when dealing with strangers online, especially about money. While recovering stolen crypto is possible, avoiding fake "recovery companies" is just as important. Real hackers work discreetly and don't advertise openly. I was scammed multiple times while desperately seeking help. Finally, a friend introduced me to RESQPROFIRM—a trustworthy, discreet team. They handle everything from website security to crypto asset recovery. With their help, I recovered $320,000 in USDT within a week. Their professionalism, discretion, and speed were outstanding. If you've been compromised, don't lose hope—but beware of fraudsters posing as saviors. RESQPROFIRM are true professionals. I'm living proof. Contact them at [email protected], WhatsApp +19852969146, or Telegram @resqprofirm.

  • 15.06.26 13:06 Tansy

    Lost $18,500 to a fake Elon Musk crypto giveaway. Sent ETH, got nothing. Recovery pages demanded more gas fees. I stopped believing. FuNds rEtRiEveR on Te.le_gram was the real one. Email: [email protected] – WhatsApp: +1 603 512 1448

  • 15.06.26 13:08 Sarahy billy

    A REAL EXPERIENCE, EVERYONE ... PLEASE BE CAREFUL ONLINE A few weeks ago, I lost around $64,000 to a fake crypto trading platform. I was drawn in by the promise of earning 15% profit daily. It was a devastating time—I struggled to pay my bills and was financially ruined. I eventually opened up to a close friend, who recommended a crypto recovery team with highly effective methods. I contacted them, and they successfully recovered all my stolen digital assets with ease. Their service was excellent, and they acted quickly—within just 5 working days, they tracked down the scammers and returned my funds. I strongly urge anyone facing investment theft or similar issues to reach out to this team for the right solution and avoid losing large sums to fraudsters... Email: Resqprofirm @aol.com WhatsApp: +19852969146, telegram @resqprofirm

  • 15.06.26 13:12 Cole donald

    "I strongly recommend RESQPRO FIRM to anyone trying to recover lost cryptocurrency assets, including Bitcoin, USDC, USDT, Ethereum, and Trump Coin. Like many others, I was shocked to learn that crypto holdings can be stolen even when private keys are carefully protected. After a sophisticated hack wiped out my entire portfolio, I felt completely helpless. Fortunately, I was referred to RESQPRO FIRM. Their team understood the complexity of my situation and successfully recovered my funds. They were responsive, communicated clearly, and followed a careful, step-by-step process—which gave me a lot of reassurance during a stressful time. If you've experienced a similar financial loss, I encourage you to reach out to them. Their professionalism and ethical hacking skills exceeded my expectations." Contact Info: · WhatsApp: +1 (985) 2969146 · Email: [email protected] · Telegram: Resqprofirm

  • 15.06.26 13:16 Meral Yetkiner

    I recently lost $38,000 to an online platform. Initially, they requested additional deposits to grant me access to my portfolio. Despite complying, my withdrawal requests were repeatedly denied, and they continued asking for more funds. Suspecting fraudulent activity, I ceased further payments and promptly reported the matter to ResQProfirm, a firm I discovered through Google. They listened to my situation, initiated communication regarding the sequence of events, and requested all relevant evidence to support their investigation. Through their dedicated efforts, they successfully traced and recovered my funds. I extend my thanks to ResQProfirm at [email protected] and via WhatsApp at +19852969146. I urge everyone to exercise caution and thoroughly research any platform before investing.

  • 15.06.26 13:18 Silas Olsen

    A fraudulent investment scheme operated by BTCMining.limited functions as a fake return scam. In this setup, scammers lure victims with false promises of high returns. Through manipulative tactics, they gain individuals' trust and convince them to invest, ultimately leading to financial loss. If you have ever faced a cyber threat or fallen victim to an online crypto scam and need to reach the authorities, I recommend contacting [email protected]. They are a legitimate team that helps victims of online crypto scams using advanced tools.

  • 15.06.26 13:59 Ewaguz

    If a binary options broker refuses your withdrawal, do not pay any "verification fees" or "tax fees." These are lies designed to extract more money. Stop communicating with their support team – they are trained to stall. Instead, immediately document every transaction, screenshot your account balance, and contact a professional recovery specialist. BinaryBook stole €14,500 from me before I learned this. FundsRetriever traced the deposits and recovered everything within two weeks. Do not wait. Do not pay more fees. Act now. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 14:16 Martina k.

    Stop putting money into platforms promising guaranteed monthly returns of 10%, 20%, or more. These are Ponzi schemes. Your "profits" are just other victims' deposits. The moment withdrawals slow down, the scam is about to collapse. If you already have money trapped, do not send more to "unlock" your funds. That is a second scam. Instead, gather all transaction hashes and wallet addresses. Bitcoin Evolution Pro took €25,000 from me. FundsRetriever traced the funds through KYC exchanges and recovered my principal. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 14:18 Garrison Good

    If IQ Option or any similar platform blocks your withdrawal citing "bonus terms" or "abnormal activity," do not argue with their chat support. They are not empowered to help you. Instead, request all trade logs and bonus terms in writing. Then hire a forensic specialist to audit your account. IQ Option held my €9,200 for two months. FundsRetriever reviewed my case, identified regulatory violations, and secured my full payout within 72 hours. Professional pressure works. Do it immediately. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 14:22 Sallymarch

    Never grant API keys with withdrawal permissions to any third-party software. This is how crypto arbitrage bots steal your funds. If you have already done this, revoke all API keys immediately. Then check your exchange transaction history. CryptoArb AI drained €7,800 from my account within hours. FundsRetriever reverse-engineered the bot's code, traced the scammer's wallet, and recovered everything. Always use "read-only" API permissions only. If you made the mistake, act fast. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 14:23 Glennrobble

    If a binary options broker closes your account and confiscates your profits, do not accept their explanation. Demand a full audit of your trade history. Most brokers cannot justify their actions when challenged by professionals. ExpertOption stole €6,200 from me claiming "abnormal activity." FundsRetriever audited my trades, proved they were legitimate, and threatened legal action. The broker paid within 10 days. Do not let them intimidate you. Get professional help. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 14:25 Evan Garrison

    Cloud mining contracts are almost always too good to be true. I learned that the hard way with MineMax. First two months, small daily payouts. Then "maintenance fees" ate everything. Then my account was frozen. Then the website disappeared. I was heartbroken. FundsRetriever traced my payments through three shell companies to a real bank account. They froze it and got my €11,000 back. Recovery is possible even from complex scams. Contact [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 14:26 Ewaguz

    That 100% deposit bonus looks tempting, doesn't it? I took it. Big mistake. When I tried to withdraw my €4,500, Olymp Trade demanded I trade 50 times the bonus amount. Impossible by design. My money was trapped. FundsRetriever reviewed the terms and found they violated consumer protection laws in my country. They negotiated directly with Olymp Trade's legal team. Within a week, my funds were released. My advice? Never accept bonuses. But if you're already trapped, call [email protected], WhatsApp +1(603)5121(448) or Telegram FUNDSRETRIEVER.

  • 15.06.26 16:34 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 15.06.26 16:34 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 15.06.26 16:41 Louane Mercier

    It is crucial to act quickly and consult a reputable, experienced recovery specialist who will support you throughout the entire recovery process. You must provide them with transaction evidence, scammer information, and any other relevant details that could aid the investigation. With this data, the experts can trace and attempt to recover your funds from the scammers' concealed accounts or wallets. R£sQprofirm company offers recovery assistance with no upfront fees. Contact them via Telegram (@ResQprofirm), WhatsApp (+19852969146), or email ([email protected]).

  • 15.06.26 16:45 Andrés Montero

    I’m open about my experience with Bitcoin investment and losing money to scammers. That said, it is possible to recover stolen Bitcoin. I used to think recovery was impossible because that’s what I had been told. But last October, I fell for a forex scam promising extremely high returns and ended up losing nearly $87,600. After searching for help for a month, I came across a Reddit article about recovering stolen cryptocurrency. I reached out to the contact provided: [email protected] and WhatsApp +19852969146. I was scared and skeptical, having heard many bad stories, but I decided to give them a try. To my amazement, I got all my stolen Bitcoin back within a very short time. I’m not sure if I’m allowed to post links here, but you can reach out to them if you also need help.

  • 15.06.26 16:48 Olivia Sørensen

    Several months ago, investing in Bitcoin proved to be one of my most lucrative endeavors. I achieved considerable profits across multiple platforms and felt a strong sense of accomplishment. Unfortunately, the situation deteriorated when I inadvertently engaged with a fraudulent Bitcoin platform. This entity swindled me out of $92,000 USD, refused to honor my withdrawal requests, and persistently demanded further deposits. Fortunately, I encountered (R£SQPRO FIRM) online. After reporting my case to them, they acted promptly and effectively recovered my lost Bitcoin. I am sincerely grateful for their professionalism and continuous assistance. Contact: ResQprofirm AT aol.com, Telegram @resqprofirm, WhatsApp +1 9 8 5 2 9 6 9 1 4 6.

  • 15.06.26 16:51 Viljar Yohannes

    I'm willing to share my experience with Bitcoin investment and losing money to scammers. But yes, recovering stolen Bitcoin is possible. I never believed in Bitcoin recovery myself, because I was told it couldn't be done. Then, last October, I fell for a forex scam that promised unrealistically high returns, and I ended up losing nearly $70,000. I searched for help for about a month until I finally found a Reddit article about recovering stolen cryptocurrency. I reached out to the contact mentioned: [RESQPROFIRM [at] AOL DOT com] and [WhatsApp +19852969146]. I was scared and skeptical because I'd heard horror stories, but I decided to give them a try. To my surprise, I got all my stolen Bitcoin back from the scammers in a very short time. I'm not sure if I'm allowed to post links here, but you can contact them if you need help too.

  • 15.06.26 16:58 Guimar da Rosa

    Withdrawal troubles shouldn’t stress you out. I faced a similar problem, and this firm stepped in and recovered my funds. Their support truly mattered. Contact them: [ResQProFirm @aol.com] telegram @resqprofirm, WhatsApp: <+198> <5296> <9146>.

  • 15.06.26 17:03 Andrea Escalante

    If withdrawals keep getting denied, stay calm. I went through the same, and this firm helped me recover everything. Their assistance was outstanding. Contact: [[email protected]], Telegram: ResQprofirm, WhatsApp: <+198> <5296> <9146>. Withdrawal troubles shouldn’t

  • 16.06.26 11:40 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 16.06.26 11:43 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 16.06.26 13:37 Felix Steve

    MY CRYPTO WAS STOLEN – HERE'S HOW I GOT IT BACK I'm Felix Steve from Canada, and I lost $115,000 USDC to a fraudulent broker who locked me out of my wallet. After sleepless nights, a friend told me about RESQPROFIRM Recovery Service. I sent them my wallet addresses, transaction history, and chat logs. Their team used blockchain tracking to trace the stolen funds, identified the scammer's wallet, and froze the assets before they could be moved. Within 24 hours, most of my crypto was recovered. I can't thank them enough. If you need help, reach out via WhatsApp: +19852969146, email: [email protected], or TG: @resqprofirm.

  • 16.06.26 13:45 Wills ben

    SUCCESSFUL CRYPTO SCAM RECOVERY – HOW I REGAINED ACCESS TO MY LOST WALLET My name is Felix Steve, and I'm from Canada. I'm sharing my story to help others who have fallen victim to crypto fraud. A few months ago, I was lured into a fake investment scheme promoted by a broker company. With Bitcoin prices climbing, I invested heavily—only to lose $115,000 USDC when the broker locked me out of my wallet and assets. It was a harrowing experience that left me sleepless and desperate. Crypto scams are on the rise, often involving bogus trading platforms, phishing, and misleading promises. In my search for help, a fellow crypto enthusiast recommended RESQPROFIRM Recovery Service, which specializes in recovering lost or stolen funds. After checking their reviews, I reached out and supplied all the evidence—wallet addresses, transaction records, and communication logs. Their team responded immediately and launched an investigation. Using advanced blockchain tracking, they traced the stolen funds, pinpointed the scammer's wallet, and worked with authorities to freeze the assets in time. Remarkably, within just 24 hours, RESQPROFIRM recovered the bulk of my stolen crypto. I was overwhelmed with relief and gratitude. Their professionalism, transparency, and steady communication made all the difference during a very dark period. If you've been scammed, I wholeheartedly recommend contacting them via WhatsApp: +19852969146, email: [email protected], or Telegram: @resqprofirm.

  • 18.06.26 13:31 Noemi Bernard

    I never expected such outstanding results. The outcome far exceeded my expectations, and I am extremely satisfied with the successful recovery of my stolen funds totaling $49,360 from my blockchain wallet. I hold this team in the highest regard. Without a doubt, they are among the most dedicated professionals in the field of fund recovery. Keep up the exceptional work! Email: [email protected] WhatsApp: +1 985 296 9146

  • 18.06.26 13:35 Carter Morris

    My experience improved significantly thanks to ResQprofirm's expert assistance and attentive customer care. Their professionalism was evident every step of the way they were able to track and recover my stolen crypto $88,360, email: [email protected], WhatsApp +19852969146.

  • 18.06.26 13:40 Kuybida Andriyiv

    I recovered my $232,000 refund through the assistance of [email protected] and WhatsApp +19852969146. Their guidance was very helpful.

  • 20.06.26 14:57 michaeldavenport218

    I was recently scammed out of $53,000 by a fraudulent Bitcoin investment scheme, which added significant stress to my already difficult health issues, as I was also facing cancer surgery expenses. Desperate to recover my funds, I spent hours researching and consulting other victims, which led me to discover the excellent reputation of Capital Crypto Recover, I came across a Google post It was only after spending many hours researching and asking other victims for advice that I discovered Capital Crypto Recovery’s stellar reputation. I decided to contact them because of their successful recovery record and encouraging client testimonials. I had no idea that this would be the pivotal moment in my fight against cryptocurrency theft. Thanks to their expert team, I was able to recover my lost cryptocurrency back. The process was intricate, but Capital Crypto Recovery's commitment to utilizing the latest technology ensured a successful outcome. I highly recommend their services to anyone who has fallen victim to cryptocurrency fraud. For assistance contact [email protected] and on Telegram OR Call Number +1 (336)390-6684 via email: [email protected] you can visit his website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 20.06.26 14:57 michaeldavenport218

    I was recently scammed out of $53,000 by a fraudulent Bitcoin investment scheme, which added significant stress to my already difficult health issues, as I was also facing cancer surgery expenses. Desperate to recover my funds, I spent hours researching and consulting other victims, which led me to discover the excellent reputation of Capital Crypto Recover, I came across a Google post It was only after spending many hours researching and asking other victims for advice that I discovered Capital Crypto Recovery’s stellar reputation. I decided to contact them because of their successful recovery record and encouraging client testimonials. I had no idea that this would be the pivotal moment in my fight against cryptocurrency theft. Thanks to their expert team, I was able to recover my lost cryptocurrency back. The process was intricate, but Capital Crypto Recovery's commitment to utilizing the latest technology ensured a successful outcome. I highly recommend their services to anyone who has fallen victim to cryptocurrency fraud. For assistance contact [email protected] and on Telegram OR Call Number +1 (336)390-6684 via email: [email protected] you can visit his website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 21.06.26 11:09 Maurizio Rolland

    I would like to express my sincere appreciation to RESQPRO FIRM for their outstanding assistance in helping victims of online fraud. Many scammers deceive investors by blocking withdrawals and continuously demanding additional deposits, making the loss of hard-earned funds a painful experience. Fortunately, RESQPRO FIRM provides support to individuals seeking to recover funds lost to fraudulent online schemes. Contact: Email: RESQPRO FIRM at Gmail Telegram: RESQPROFIRM, [email protected], WhatsApp: +1 985 296 9146

  • 21.06.26 11:13 Buse Fahri

    It is important for more people to stand together in the fight against online fraud. Those who target innocent individuals especially vulnerable people such as seniors should be held fully accountable for their actions. Every effort to raise awareness and support victims makes a meaningful difference. The team at RESQPRO FIRM is committed to helping expose fraudulent schemes and assisting those affected by online scams. Their dedication, persistence, and passion for protecting victims are truly commendable. I sincerely appreciate the hard work and commitment shown toward this mission. Together, we can continue to educate others, support victims, and work toward a safer online environment for everyone. Contact Information: Telegram: RESQPROFIRM WhatsApp: +1 985 296 9146 Email: [email protected], [email protected]

  • 21.06.26 11:16 علیرضا گلشن

    The successful recovery of my stolen funds, totaling $1,310,000, would not have been possible without your unwavering support, dedication, and tireless efforts. I am truly grateful for the opportunity to work with such a skilled and professional team. From the very beginning, I had confidence in your ability to handle this challenging situation, and you exceeded my expectations by delivering remarkable results. Your expertise, persistence, and commitment throughout the process were exceptional. I encourage you to continue maintaining the high standards of professionalism and excellence that distinguish your work. You exemplify the qualities of a trustworthy, dedicated, and hardworking professional, and your efforts deserve sincere recognition and appreciation. Contact: Email: [email protected], [email protected], Telegram: Resqprofirm WhatsApp: +1 985 296 9146

  • 22.06.26 21:51 kimberlyhebert786

    I invested in bitcoin trading After losing $78.4 USDT) linked to a romance fraud scam worth of cryptocurrency through an online investment platform and later discovered it was a scam. After extensive research for recovery options, I contacted CAPITAL CRYPTO RECOVER based on positive client reviews and recommendations. Their professional security team guided me through the recovery process using advanced technology, and I was able to recover my lost cryptocurrency successfully. I am truly grateful for their support and assistance during such a difficult experience. I will advise you to contact CAPITAL CRYPTO RECOVER helped me recover my funds. For anyone facing similar issues, Website: https://recovercapital.wixsite.com/capital-crypto-rec-1 Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text Number: +1 (336) 390-6684

  • 22.06.26 21:51 kimberlyhebert786

    I invested in bitcoin trading After losing $78.4 USDT) linked to a romance fraud scam worth of cryptocurrency through an online investment platform and later discovered it was a scam. After extensive research for recovery options, I contacted CAPITAL CRYPTO RECOVER based on positive client reviews and recommendations. Their professional security team guided me through the recovery process using advanced technology, and I was able to recover my lost cryptocurrency successfully. I am truly grateful for their support and assistance during such a difficult experience. I will advise you to contact CAPITAL CRYPTO RECOVER helped me recover my funds. For anyone facing similar issues, Website: https://recovercapital.wixsite.com/capital-crypto-rec-1 Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text Number: +1 (336) 390-6684

  • 24.06.26 01:25 Fraddy Pual

    I never thought it would happen to me—but I lost $256,100 in Bitcoin through a shady investment deal. I was shattered, panicked, and convinced my savings were gone forever. Just when I was about to give up, I stumbled upon reviews for FUNDSRETRIEVER, a cyber recovery team with a solid reputation. I decided to give it a shot, and to my absolute shock, they recovered every single cent in record time. Working with them was a lifesaver. If you've been tricked by fake investment platforms, don't lose hope—FUNDSRETRIEVER can help. Contact them here: Email: [email protected] | WhatsApp: +1603512144 8| Telegram: @Fundsretriever

  • 24.06.26 01:27 Fraddy Pual

    I never thought it would happen to me—but I lost $256,100 in Bitcoin through a shady investment deal. I was shattered, panicked, and convinced my savings were gone forever. Just when I was about to give up, I stumbled upon reviews for FUNDSRETRIEVER, a cyber recovery team with a solid reputation. I decided to give it a shot, and to my absolute shock, they recovered every single cent in record time. Working with them was a lifesaver. If you've been tricked by fake investment platforms, don't lose hope—FUNDSRETRIEVER can help. Contact them here: Email: [email protected] | WhatsApp: +16035121448 | Telegram: @Fundsretriever

  • 24.06.26 01:28 Fraddy Pual

    I never thought it would happen to me—but I lost $256,100 in Bitcoin through a shady investment deal. I was shattered, panicked, and convinced my savings were gone forever. Just when I was about to give up, I stumbled upon reviews for FUNDSRETRIEVER, a cyber recovery team with a solid reputation. I decided to give it a shot, and to my absolute shock, they recovered every single cent in record time. Working with them was a lifesaver. If you've been tricked by fake investment platforms, don't lose hope—FUNDSRETRIEVER can help. Contact them here: Email: [email protected] | WhatsApp: +16035121448 | Telegram: @Fundsretriever.

  • 24.06.26 01:58 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 24.06.26 01:58 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 24.06.26 14:16 Universina da Mota

    Becoming a victim of an investment scam is never anyone's intention it often happens because fraudsters exploit trust and a lack of awareness. I would like to express my sincere gratitude to the dedicated team at ResQpro for their professionalism and commitment to helping victims of online investment fraud. Their efforts in assisting individuals with the recovery of stolen assets and holding scammers accountable are truly commendable. If you need assistance or would like to learn more, you can contact them through: Email: [email protected] Alternative Email: [email protected] Telegram: @ResQprofirm WhatsApp: +1 (985) 296-9146

  • 24.06.26 14:21 Elizabeth Thompson

    If you believe you have been the victim of an investment scam, it is important to act promptly and gather all relevant information. Keep records of transaction receipts, wallet addresses, communication logs, account details, and any other evidence related to the incident. Providing accurate documentation can help investigators, financial institutions, legal professionals, or recovery specialists review your case and determine what options may be available. Be cautious of anyone who guarantees the recovery of lost funds or requests large upfront payments. For additional information, you may contact: Email: [email protected] Telegram: @ResQprofirm WhatsApp: +1 (985) 296-9146

  • 24.06.26 15:33 Júlia Castro

    If you have fallen victim to an investment scam, it is important to act quickly and gather all available evidence related to the incident. This may include transaction records, wallet addresses, screenshots of conversations, emails, account details, and any information connected to the individuals or entities involved. Having complete documentation can help professionals assess your situation and explore possible recovery options. Always exercise caution when seeking assistance and carefully verify the credentials of any service provider before proceeding. For further information, you may contact: Email: [email protected] Telegram: @ResQprofirm WhatsApp: +1 (985) 296-9146

  • 24.06.26 22:01 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 24.06.26 22:01 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 25.06.26 21:13 Emilie Safi

    A fraudulent investment scheme operated by BTCMining.limited functions as a fake return scam. In this setup, scammers lure victims with false promises of high returns. Through manipulative tactics, they gain individuals' trust and convince them to invest, ultimately leading to financial loss. If you have ever faced a cyber threat or fallen victim to an online crypto scam and need to reach the authorities, I recommend contacting [email protected], [email protected], WhatsApp +19852969146, telegram @resqprofirm. They are a legitimate team that helps victims of online crypto scams using advanced tools.

  • 25.06.26 21:25 Emilie Safi

    So I ended up losing $38,000 to this platform. At first, they kept asking me to put in more money so I could get into my portfolio. I did that, but then they wouldn’t let me withdraw anything—just kept asking for more deposits. It got way too suspicious, so I stopped. I found this company called ResQProfirm on Google and told them what happened. They got in touch, asked me to walk them through everything, and I gave them all the proof I had. They did an amazing job tracking down my money and getting it back. Big thanks to them at [email protected] and on WhatsApp at +19852969146. Please be careful out there and always research before investing.

  • 01:04 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 01:04 robertalfred175

    CRYPTO SCAM RECOVERY SUCCESSFUL – A TESTIMONIAL OF LOST PASSWORD TO YOUR DIGITAL WALLET BACK. My name is Robert Alfred, Am from Australia. I’m sharing my experience in the hope that it helps others who have been victims of crypto scams. A few months ago, I fell victim to a fraudulent crypto investment scheme linked to a broker company. I had invested heavily during a time when Bitcoin prices were rising, thinking it was a good opportunity. Unfortunately, I was scammed out of $120,000 AUD and the broker denied me access to my digital wallet and assets. It was a devastating experience that caused many sleepless nights. Crypto scams are increasingly common and often involve fake trading platforms, phishing attacks, and misleading investment opportunities. In my desperation, a friend from the crypto community recommended Capital Crypto Recovery Service, known for helping victims recover lost or stolen funds. After doing some research and reading multiple positive reviews, I reached out to Capital Crypto Recovery. I provided all the necessary information—wallet addresses, transaction history, and communication logs. Their expert team responded immediately and began investigating. Using advanced blockchain tracking techniques, they were able to trace the stolen Dogecoin, identify the scammer’s wallet, and coordinate with relevant authorities to freeze the funds before they could be moved. Incredibly, within 24 hours, Capital Crypto Recovery successfully recovered the majority of my stolen crypto assets. I was beyond relieved and truly grateful. Their professionalism, transparency, and constant communication throughout the process gave me hope during a very difficult time. If you’ve been a victim of a crypto scam, I highly recommend them with full confidence contacting: Email: [email protected] Telegram: @Capitalcryptorecover Contact: [email protected] Call/Text: +1 (336) 390-6684 Website: https://recovercapital.wixsite.com/capital-crypto-rec-1

  • 02:48 Miriam Rocha

    I trusted this platform with $120,000 of my hard-earned money. Then they started asking for more deposits just so I could access my own portfolio. I paid, but every withdrawal request was denied. They kept pushing for more money. I finally stopped it just felt wrong. Desperate, I found ResQProfirm on Google. They didn't just hear me out; they truly listened. I shared all my proof, and they launched an investigation. Thanks to their hard work, they tracked and returned my funds. From the bottom of my heart, thank you to [email protected] and their WhatsApp +19852969146. Please stay safe and always verify a platform before investing

  • 02:52 Miško Bakić

    I got my $232,000 refund thanks to [email protected] and WhatsApp +19852969146. Highly recommended for anyone in a similar situation.

  • 02:56 Asunción Herrera

    A recovery of $48,330 was facilitated by [email protected]. Individuals who have experienced financial fraud may consider contacting this service.

Для участия в Чате вам необходим бесплатный аккаунт pro-blockchain.com Войти Регистрация
Есть вопросы?
С вами на связи 24/7
Help Icon