// // Created by bruno on 2.2.2025. // #include "memory.h" uint8_t write_mem(CPU *cpu, uint32_t addr, uint8_t value) { if (addr >= MEM_SIZE) { return 1; } switch (addr) { default: cpu->memory[addr] = value; } return 0; } uint8_t read_mem(CPU *cpu, uint32_t addr) { if (addr >= MEM_SIZE) { return 0; } switch (addr) { default: return cpu->memory[addr]; } } uint16_t read_mem16(CPU *cpu, uint32_t addr) { return read_mem(cpu, addr) | (read_mem(cpu, addr + 1) << 8); } uint32_t read_mem32(CPU *cpu, uint32_t addr) { return read_mem16(cpu, addr) | (read_mem16(cpu, addr + 2) << 16); } uint32_t read_address_argument(CPU *cpu) { uint32_t out = read_mem32(cpu, cpu->pc); cpu->pc += 4; if (out >= MEM_SIZE) { out = MEM_SIZE - 1; } return out; } // Push a 32-bit program counter (PC) onto the stack void write_stack(CPU *cpu) { if (cpu->pc >= MEM_SIZE) { return; // Invalid memory address } if (cpu->stack_ptr >= STACK_SIZE - 1) { return; // Stack overflow protection } cpu->stack[++cpu->stack_ptr] = cpu->pc; for (uint32_t reg = 0; reg < REG_COUNT; reg += 4) { uint32_t packed = cpu->regs[reg] | ((reg + 1 < REG_COUNT) ? (cpu->regs[reg + 1] << 8) : 0) | ((reg + 2 < REG_COUNT) ? (cpu->regs[reg + 2] << 16) : 0) | ((reg + 3 < REG_COUNT) ? (cpu->regs[reg + 3] << 24) : 0); cpu->stack[++cpu->stack_ptr] = packed; } cpu->stack[++cpu->stack_ptr] = cpu->flags; } // Pop a 32-bit program counter (PC) and registers from the stack void read_stack(CPU *cpu) { if (cpu->stack_ptr == 0) { return; // Stack underflow protection } // Restore flags cpu->flags = cpu->stack[cpu->stack_ptr--]; // Restore registers for (int32_t reg = REG_COUNT - 1; reg >= 0; reg -= 4) { if (cpu->stack_ptr == 0) { return; // Stack underflow protection } uint32_t packed = cpu->stack[cpu->stack_ptr--]; cpu->regs[reg] = (packed & 0xFF); if (reg - 1 >= 0) cpu->regs[reg - 1] = ((packed >> 8) & 0xFF); if (reg - 2 >= 0) cpu->regs[reg - 2] = ((packed >> 16) & 0xFF); if (reg - 3 >= 0) cpu->regs[reg - 3] = ((packed >> 24) & 0xFF); } // Restore PC if (cpu->stack_ptr == 0) { return; // Stack underflow protection } cpu->pc = cpu->stack[cpu->stack_ptr--]; } uint8_t read_reg_number(CPU *cpu) { uint8_t out = read_mem(cpu, cpu->pc++); if (out >= REG_COUNT) { return 0; } return out; } uint8_t read_reg(CPU *cpu, uint8_t number) { if (number >= REG_COUNT) { return 0; } return cpu->regs[number]; } uint8_t write_reg(CPU *cpu, uint8_t number, uint8_t value) { if (number >= REG_COUNT) { return 1; } cpu->regs[number] = value; return 0; } uint8_t write_mem16(CPU *cpu, uint32_t addr, uint16_t value) { uint8_t status = write_mem(cpu, addr, value & 0xFF); if (status) { return status; } status = write_mem(cpu, addr + 1, (value >> 8) & 0xFF); if (status) { return status; } return 0; } uint8_t write_mem32(CPU *cpu, uint32_t addr, uint32_t value) { uint8_t status = write_mem16(cpu, addr, value & 0xFFFF); if (status) { return status; } status = write_mem16(cpu, addr + 2, (value >> 16) & 0xFFFF); if (status) { return status; } return 0; }