#include "fw.h"
#include "io.h"
#include "abcio.h"
#include "sys.h"

/* Configure ABC memory map */
struct abc_mem_init {
    unsigned int addr;
    uint16_t len;
    uint8_t flags;
    const char *data;		/* May not be const, but... */
};
#define RD (ABCMEMMAP_RD >> 24)
#define WR (ABCMEMMAP_WR >> 24)

extern const char rom_ufddos80[];

static char __dram_bss abc80_nvram[2 << 10]; /* Not really NV... */
static char __dram_bss abc80_extmem[16 << 10];

static const struct abc_mem_init mem_init[] = {
    { 0x5000,  2 << 10, RD|WR, abc80_nvram },
    { 0x6000,  4 << 10, RD, rom_ufddos80 },
    { 0x8000, 16 << 10, RD|WR, abc80_extmem },
    { -1U, 0, 0, NULL }
};

void abc_init_memmap(void)
{

    volatile uint32_t *pg = &ABCMEMMAP_PAGE(0);
    const struct abc_mem_init *next = &mem_init[0];

    for (unsigned int addr = 0; addr < 0x10000; addr += 512) {
	if (addr >= next->addr + next->len)
	    next++;

	if (addr < next->addr) {
	    *pg++ = 0;
	} else {
	    *pg++ = ((size_t)(next->data + (addr - next->addr))
		     & SDRAM_MASK) | (next->flags << 24);
	}
    }
}
