/*
 * Z80SIM  -  a Z80-CPU simulator
 *
 * Copyright (C) 2016 by Udo Munk
 *
 * This module implements memory management for an Altair 8800 system
 *
 * History:
 * 22-NOV-16 stuff moved to here and implemented as inline functions
 */

static inline BYTE *mem_base(void);
extern void init_memory(void), wait_step(void), wait_int_step(void);
extern BYTE memory[], mem_wp;
extern int p_tab[];

#define MEM_RW		0	/* memory is readable and writable */
#define MEM_RO		1	/* memory is read-only */
#define MEM_WPROT	2	/* memory is write protected */
#define MEM_NONE	3	/* no memory available */

/*
 * memory access for the CPU cores
 */
static inline void memwrt(WORD addr, BYTE data)
{
	cpu_bus &= ~(CPU_WO | CPU_MEMR);

	fp_clock += 20;
	fp_led_address = addr;
	fp_led_data = 0xff;
	fp_sampleData();
	wait_step();

	if (p_tab[addr >> 8] == MEM_RW) {
		memory[addr] = data;
		mem_wp = 0;
	}
}

static inline BYTE memrdr(WORD addr)
{
	cpu_bus |= CPU_WO | CPU_MEMR;

	fp_clock += 20;
	fp_led_address = addr;
	fp_led_data = *(mem_base() + addr);
	fp_sampleData();
	wait_step();

	if (p_tab[addr >> 8] != MEM_NONE)
		return(memory[addr]);
	else
		return(0xff);
}

/*
 * memory access for DMA devices
 */
static inline BYTE dma_read(WORD addr)
{
	if (p_tab[addr >> 8] != MEM_NONE)
		return(memory[addr]);
	else
		return(0xff);
}

static inline void dma_write(WORD addr, BYTE data)
{
	if (p_tab[addr >> 8] == MEM_RW)
		memory[addr] = data;
}

/*
 * return memory base pointer for the simulation frame
 */
static inline BYTE *mem_base(void)
{
	return(&memory[0]);
}
