#ifndef _MEMORY_H_
#define _MEMORY_H_

#include "defs.h"

typedef struct _memory_ {
    /* public */
#   include "public_template.h"

    /* private */
} t_memory;

extern t_memory i_memory;

/*
 * The main communication system within the system: memory mapped I/O.
 * A few functions to help things along.
 * NOTE: These macros can cause problems in that they will evaluate ``addr''
 * twice hence having possible side effects.
 */
extern byte (*special_mem_r[])(word addr);
extern byte (*special_mem_w[])(word addr, byte val);
extern byte mem[];

#define readb(addr) special_mem_r[(addr)]((addr))

#define writeb(addr, val) special_mem_w[(addr)]((addr), (val))

#define writew(addr, val) writeb((addr),  (val) / 0x100); \
			      writeb(1+(addr),(val) & 0x0ff)

#define readw(addr) (readb((addr)) + 0x100 * readb(1+(addr)))

#ifdef SUPERFAST
#    undef readb
#    undef readw
#    undef writeb
#    undef writew
#    define readb readbq
#    define readw readwq
#    define writeb writebq
#    define writew writewq
#endif

/* fast mem access when we KNOW it's ok to cheat (eg pull/push) */
#define readbq(addr) mem[(addr)]
#define writebq(addr, val) (mem[(addr)] = (val))
#define readwq(addr) (mem[(addr)] + 0x100 * mem[(addr)+1])
#define writewq(addr, val) mem[(addr)] = (val) / 0x100; \
			   mem[(addr)] = (val) & 0x0ff

#endif /* _MEMORY_H */
