shithub: psxe

ref: 5fa5cd2f88b50957bc8ac463c463bd73cfff83d0
dir: /psx/bus.c/

View raw version
#include <stdint.h>
#include <stdlib.h>

#include "bus.h"
#include "bus_init.h"
#include "log.h"

#define RANGE(v, s, e) ((v >= s) && (v < e))

const uint32_t g_psx_bus_region_mask_table[] = {
    0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    0x7fffffff, 0x1fffffff, 0xffffffff, 0xffffffff
};

psx_bus_t* psx_bus_create() {
    return (psx_bus_t*)malloc(sizeof(psx_bus_t));
}

// Does nothing for now
void psx_bus_init(psx_bus_t* bus) {}

void psx_bus_destroy(psx_bus_t* bus) {
    free(bus);
}

#define HANDLE_READ(dev, bits) \
    if (RANGE(addr, bus->dev->io_base, bus->dev->io_base + bus->dev->io_size)) \
        return psx_ ## dev ## _read ## bits (bus->dev, addr - bus->dev->io_base);

#define HANDLE_WRITE(dev, bits) \
    if (RANGE(addr, bus->dev->io_base, bus->dev->io_base + bus->dev->io_size)) { \
        psx_ ## dev ## _write ## bits (bus->dev, addr - bus->dev->io_base, value); \
        return; \
    }

uint32_t psx_bus_read32(psx_bus_t* bus, uint32_t addr) {
    bus->access_cycles = 2;

    uint32_t vaddr = addr;

    addr &= g_psx_bus_region_mask_table[addr >> 29];

    if (addr & 0x3) {
        log_warn("Unaligned 32-bit read from %08x:%08x", vaddr, addr);
    }

    HANDLE_READ(bios, 32);
    HANDLE_READ(ram, 32);
    HANDLE_READ(dma, 32);
    HANDLE_READ(exp1, 32);
    HANDLE_READ(mc1, 32);
    HANDLE_READ(mc2, 32);
    HANDLE_READ(mc3, 32);
    HANDLE_READ(ic, 32);
    HANDLE_READ(scratchpad, 32);
    HANDLE_READ(gpu, 32);
    HANDLE_READ(spu, 32);
    HANDLE_READ(timer, 32);
    HANDLE_READ(cdrom, 32);
    HANDLE_READ(pad, 32);

    log_warn("Unhandled 32-bit read from %08x:%08x", vaddr, addr);

    return 0x00000000;
}

uint16_t psx_bus_read16(psx_bus_t* bus, uint32_t addr) {
    bus->access_cycles = 2;

    uint32_t vaddr = addr;

    addr &= g_psx_bus_region_mask_table[addr >> 29];

    if (addr & 0x1) {
        log_warn("Unaligned 16-bit read from %08x:%08x", vaddr, addr);
    }

    HANDLE_READ(bios, 16);
    HANDLE_READ(ram, 16);
    HANDLE_READ(dma, 16);
    HANDLE_READ(exp1, 16);
    HANDLE_READ(mc1, 16);
    HANDLE_READ(mc2, 16);
    HANDLE_READ(mc3, 16);
    HANDLE_READ(ic, 16);
    HANDLE_READ(scratchpad, 16);
    HANDLE_READ(gpu, 16);
    HANDLE_READ(spu, 16);
    HANDLE_READ(timer, 16);
    HANDLE_READ(cdrom, 16);
    HANDLE_READ(pad, 16);

    log_warn("Unhandled 16-bit read from %08x:%08x", vaddr, addr);

    return 0x0000;
}

uint8_t psx_bus_read8(psx_bus_t* bus, uint32_t addr) {
    bus->access_cycles = 2;

    uint32_t vaddr = addr;

    addr &= g_psx_bus_region_mask_table[addr >> 29];

    HANDLE_READ(bios, 8);
    HANDLE_READ(ram, 8);
    HANDLE_READ(dma, 8);
    HANDLE_READ(exp1, 8);
    HANDLE_READ(mc1, 8);
    HANDLE_READ(mc2, 8);
    HANDLE_READ(mc3, 8);
    HANDLE_READ(ic, 8);
    HANDLE_READ(scratchpad, 8);
    HANDLE_READ(gpu, 8);
    HANDLE_READ(spu, 8);
    HANDLE_READ(timer, 8);
    HANDLE_READ(cdrom, 8);
    HANDLE_READ(pad, 8);

    log_warn("Unhandled 8-bit read from %08x:%08x", vaddr, addr);

    return 0x00;
}

void psx_bus_write32(psx_bus_t* bus, uint32_t addr, uint32_t value) {
    bus->access_cycles = 0;

    uint32_t vaddr = addr;

    addr &= g_psx_bus_region_mask_table[addr >> 29];

    if (addr & 0x3) {
        log_warn("Unaligned 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);
    }

    HANDLE_WRITE(bios, 32);
    HANDLE_WRITE(ram, 32);
    HANDLE_WRITE(dma, 32);
    HANDLE_WRITE(exp1, 32);
    HANDLE_WRITE(mc1, 32);
    HANDLE_WRITE(mc2, 32);
    HANDLE_WRITE(mc3, 32);
    HANDLE_WRITE(ic, 32);
    HANDLE_WRITE(scratchpad, 32);
    HANDLE_WRITE(gpu, 32);
    HANDLE_WRITE(spu, 32);
    HANDLE_WRITE(timer, 32);
    HANDLE_WRITE(cdrom, 32);
    HANDLE_WRITE(pad, 32);

    log_warn("Unhandled 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);
}

void psx_bus_write16(psx_bus_t* bus, uint32_t addr, uint16_t value) {
    bus->access_cycles = 0;

    uint32_t vaddr = addr;

    addr &= g_psx_bus_region_mask_table[addr >> 29];

    if (addr & 0x1) {
        log_warn("Unaligned 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);
    }

    HANDLE_WRITE(bios, 16);
    HANDLE_WRITE(ram, 16);
    HANDLE_WRITE(dma, 16);
    HANDLE_WRITE(exp1, 16);
    HANDLE_WRITE(mc1, 16);
    HANDLE_WRITE(mc2, 16);
    HANDLE_WRITE(mc3, 16);
    HANDLE_WRITE(ic, 16);
    HANDLE_WRITE(scratchpad, 16);
    HANDLE_WRITE(gpu, 16);
    HANDLE_WRITE(spu, 16);
    HANDLE_WRITE(timer, 16);
    HANDLE_WRITE(cdrom, 16);
    HANDLE_WRITE(pad, 16);

    log_warn("Unhandled 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);
}

void psx_bus_write8(psx_bus_t* bus, uint32_t addr, uint8_t value) {
    bus->access_cycles = 0;

    uint32_t vaddr = addr;

    addr &= g_psx_bus_region_mask_table[addr >> 29];

    HANDLE_WRITE(bios, 8);
    HANDLE_WRITE(ram, 8);
    HANDLE_WRITE(dma, 8);
    HANDLE_WRITE(exp1, 8);
    HANDLE_WRITE(mc1, 8);
    HANDLE_WRITE(mc2, 8);
    HANDLE_WRITE(mc3, 8);
    HANDLE_WRITE(ic, 8);
    HANDLE_WRITE(scratchpad, 8);
    HANDLE_WRITE(gpu, 8);
    HANDLE_WRITE(spu, 8);
    HANDLE_WRITE(timer, 8);
    HANDLE_WRITE(cdrom, 8);
    HANDLE_WRITE(pad, 8);

    log_warn("Unhandled 8-bit write to %08x:%08x (%02x)", vaddr, addr, value);
}

void psx_bus_init_bios(psx_bus_t* bus, psx_bios_t* bios) {
    bus->bios = bios;
}

void psx_bus_init_ram(psx_bus_t* bus, psx_ram_t* ram) {
    bus->ram = ram;
}

void psx_bus_init_dma(psx_bus_t* bus, psx_dma_t* dma) {
    bus->dma = dma;
}

void psx_bus_init_exp1(psx_bus_t* bus, psx_exp1_t* exp1) {
    bus->exp1 = exp1;
}

void psx_bus_init_mc1(psx_bus_t* bus, psx_mc1_t* mc1) {
    bus->mc1 = mc1;
}

void psx_bus_init_mc2(psx_bus_t* bus, psx_mc2_t* mc2) {
    bus->mc2 = mc2;
}

void psx_bus_init_mc3(psx_bus_t* bus, psx_mc3_t* mc3) {
    bus->mc3 = mc3;
}

void psx_bus_init_ic(psx_bus_t* bus, psx_ic_t* ic) {
    bus->ic = ic;
}

void psx_bus_init_scratchpad(psx_bus_t* bus, psx_scratchpad_t* scratchpad) {
    bus->scratchpad = scratchpad;
}

void psx_bus_init_gpu(psx_bus_t* bus, psx_gpu_t* gpu) {
    bus->gpu = gpu;
}

void psx_bus_init_spu(psx_bus_t* bus, psx_spu_t* spu) {
    bus->spu = spu;
}

void psx_bus_init_timer(psx_bus_t* bus, psx_timer_t* timer) {
    bus->timer = timer;
}

void psx_bus_init_cdrom(psx_bus_t* bus, psx_cdrom_t* cdrom) {
    bus->cdrom = cdrom;
}

void psx_bus_init_pad(psx_bus_t* bus, psx_pad_t* pad) {
    bus->pad = pad;
}

uint32_t psx_bus_get_access_cycles(psx_bus_t* bus) {
    uint32_t cycles = bus->access_cycles;

    bus->access_cycles = 0;

    return cycles;
}

#undef HANDLE_READ
#undef HANDLE_WRITE