#include <stdint.h>
#include <stdbool.h>
#include <display.h>
#include <memory.h>
#pragma once

typedef struct{
    int32_t r[16];
    uint32_t pc;
    uint32_t pr;
    uint32_t sr;
    uint32_t mach;
    uint32_t macl;
    uint32_t gbr;

    uint8_t* rom;
    uint8_t ram[524288]; // 0x08100000
    uint8_t vram[1024]; // 0x01100000

    uint32_t program_size;

    uint8_t t;
    uint8_t q;
    uint8_t m;

    uint32_t cursor_x;
    uint32_t cursor_y;

    malloc_table_t malloc;

    display_t* display;

    uint32_t ipr[9];

    uint8_t saved_disps[5][1024];

    bool log;
}cpu_status_t;

int cpu_setup_addin(cpu_status_t*, char*);

int cpu_execute(cpu_status_t*);
int cpu_run_from(cpu_status_t*, uint32_t);

uint32_t cpu_read32(cpu_status_t*, uint32_t);
uint16_t cpu_read16(cpu_status_t*, uint32_t);
uint8_t cpu_read8(cpu_status_t*, uint32_t);

void display_update(display_t* display, cpu_status_t* status);
void display_set_data_register(display_t* display, uint8_t value, cpu_status_t* status);

void cpu_write32(cpu_status_t* status, uint32_t addr, uint32_t data);
void cpu_write16(cpu_status_t* status, uint32_t addr, uint16_t data);
void cpu_write8(cpu_status_t* status, uint32_t addr, uint8_t data);