static void handle_4_opcode(opcode instr, chip_8_cpu cpu) {
    uint8_t last_byte = get_last_byte(instr);
    nibble reg_number = get_second_nibble(instr);
    if (cpu->registers[reg_number] != last_byte) {
        cpu->skip_opcode = true;
    }
}
static void handle_F_opcode(opcode instr, chip_8_cpu cpu) {
    int8_t reg_num = get_second_nibble(instr);
    switch (get_last_byte(instr)) {
        case 0x07:
            cpu->registers[reg_num] = cpu->delay_timer;
            break;
        case 0x0A:
            not_implemented(cpu, instr);
            break;
        case 0x15:
            pthread_mutex_lock(&(cpu->delay_mutex));
            cpu->delay_timer = cpu->registers[reg_num];
            pthread_mutex_unlock(&(cpu->delay_mutex));
            break;
        case 0x18:
            cpu->sound_timer = cpu->registers[reg_num];
            break;
        case 0x1E:
            cpu->address_register = cpu->address_register + cpu->registers[reg_num];
            break;
        case 0x29:
            cpu->address_register = reg_num;
            break;
        case 0x33:
            not_implemented(cpu, instr);
        case 0x55: {
            int8_t register_index;
            address start_addr = cpu->address_register;

            for (register_index = 0; register_index < reg_num; register_index++) {
                if (start_addr + register_index >= MEMORY_SIZE) {
                    invalid_mem_access(start_addr + register_index, cpu);
                }
                cpu->memory[start_addr + register_index] = cpu->registers[register_index];
            }
            break;
        }
        case 0x65: {
            int8_t register_index;
            address start_addr = cpu->address_register;

            for (register_index = 0; register_index < reg_num; register_index++) {
                if (start_addr + register_index >= MEMORY_SIZE) {
                    invalid_mem_access(instr, cpu);
                }
                cpu->registers[register_index] = cpu->memory[start_addr + register_index];
            }
            break;
        }
        default:
            not_implemented(cpu, instr);
    }
}
static void handle_0_opcode(opcode instr, chip_8_cpu cpu) {
    // 0nnn opcode not implemented
    switch (get_last_byte(instr)) {
        case 0xE0:
            clear_display();
            break;
        case 0xEE: {
            int8_t stack_pointer = cpu->stack_pointer - 1;
            if (stack_pointer == -1) {
                stack_underflow(cpu);
            }
            cpu->stack_pointer = stack_pointer;
            cpu->program_counter = cpu->stack[stack_pointer];
            cpu->performed_jump = true;
            break;
        }
        case 0xFD:
            cpu->halt = true;
            return;
        default:
            not_implemented(cpu, instr);
    }
}
Exemplo n.º 4
0
/*!
  Функция распознаёт содержимое шага трассы, записанное в текстовом виде.
  \param step Указатель на структуру, описывающую шаг (туда и пишем)
  \param trace_line Строка, описывающая шаг трассы (непустая, без пробелов и комментариев)
  \return В случае успешного чтения возвращается 1,
  в случае ошибки при чтении возвращается -1. 
 */
static int
trace_step_parse(TraceStep *step, char *trace_line)
{
    errno = 0;
    long long value;
    char size;
    int data_read = sscanf(trace_line, "%c%c %x %c %lld",
        &step->op, &step->mem, &step->addr, &size, &value);
    if (errno) {
        return -1;
    }
    if (data_read == 3) {
        step->size = 1;
        step->value[0].flags = 1;
        return 1;
    } else if (data_read == 5 && is_size(size)) {
        step->size = size - '0';
        for (int i = step->size - 1; i >= 0; i--) {
            step->value[i].value = get_last_byte(value);
            value >>= BITS_IN_BYTE;
            step->value[i].flags = 1;
        } 
        return 1;
    } else {
static void handle_C_opcode(opcode instr, chip_8_cpu cpu) {
    uint8_t last_byte = get_last_byte(instr);
    chip_8_register reg_num = get_second_nibble(instr);
    uint8_t rand_byte = rand();
    cpu->registers[reg_num] = (last_byte & rand_byte);
}
static void handle_7_opcode(opcode instr, chip_8_cpu cpu) {
    nibble reg_number = get_second_nibble(instr);
    uint8_t last_byte = get_last_byte(instr);
    cpu->registers[reg_number] += last_byte;
}