#ifndef _EMU68_MEM68_H_
#define _EMU68_MEM68_H_
#include "emu68_api.h"
#include "struct68.h"
enum {
EMU68_R = 0x01,
EMU68_W = 0x02,
EMU68_X = 0x04,
EMU68_B = 0x08,
EMU68_M = 0xF0
};
EMU68_EXTERN
addr68_t (*const get_eab68[8])(emu68_t * const,int reg);
EMU68_EXTERN
addr68_t (*const get_eaw68[8])(emu68_t * const,int reg);
EMU68_EXTERN
addr68_t (*const get_eal68[8])(emu68_t * const,int reg);
#define get_EAB(MODE,REG) get_eab68[MODE](emu68,REG)
#define get_EAW(MODE,REG) get_eaw68[MODE](emu68,REG)
#define get_EAL(MODE,REG) get_eal68[MODE](emu68,REG)
EMU68_EXTERN
void mem68_read_b(emu68_t * const emu68);
EMU68_EXTERN
void mem68_read_w(emu68_t * const emu68);
EMU68_EXTERN
void mem68_read_l(emu68_t * const emu68);
EMU68_EXTERN
void mem68_write_b(emu68_t * const emu68);
EMU68_EXTERN
void mem68_write_w(emu68_t * const emu68);
EMU68_EXTERN
void mem68_write_l(emu68_t * const emu68);
static inline uint68_t _read_B(emu68_t * const emu68,
const addr68_t addr)
{
emu68->bus_addr = addr;
mem68_read_b(emu68);
return (u8) emu68->bus_data;
}
static inline uint68_t _read_EAB(emu68_t * const emu68,
const int mode, const int reg)
{
emu68->bus_addr = get_eab68[mode](emu68,reg);
mem68_read_b(emu68);
return (u8) emu68->bus_data;
}
static inline uint68_t _read_W(emu68_t * const emu68,
const addr68_t addr)
{
emu68->bus_addr = addr;
mem68_read_w(emu68);
return (u16) emu68->bus_data;
}
static inline uint68_t _read_EAW(emu68_t * const emu68,
const int mode, const int reg)
{
emu68->bus_addr = get_eaw68[mode](emu68,reg);
mem68_read_w(emu68);
return (u16) emu68->bus_data;
}
static inline uint68_t _read_L(emu68_t * const emu68,
const addr68_t addr)
{
emu68->bus_addr = addr;
mem68_read_l(emu68);
return (u32) emu68->bus_data;
}
static inline uint68_t _read_EAL(emu68_t * const emu68,
const int mode, const int reg)
{
emu68->bus_addr = get_eal68[mode](emu68,reg);
mem68_read_l(emu68);
return (u32) emu68->bus_data;
}
#define read_B(ADDR) _read_B(emu68,(ADDR))
#define read_W(ADDR) _read_W(emu68,(ADDR))
#define read_L(ADDR) _read_L(emu68,(ADDR))
#define read_EAB(MODE,PARM) _read_EAB(emu68,(MODE),(PARM))
#define read_EAW(MODE,PARM) _read_EAW(emu68,(MODE),(PARM))
#define read_EAL(MODE,PARM) _read_EAL(emu68,(MODE),(PARM))
static inline void _write_B(emu68_t * const emu68,
const addr68_t addr, const int68_t v)
{
emu68->bus_addr = addr;
emu68->bus_data = v;
mem68_write_b(emu68);
}
static inline void _write_EAB(emu68_t * const emu68,
const int mode, const int reg, const int68_t v)
{
emu68->bus_addr = get_eab68[mode](emu68,reg);
emu68->bus_data = v;
mem68_write_b(emu68);
}
static inline void _write_W(emu68_t * const emu68, addr68_t addr, int68_t v)
{
emu68->bus_addr = addr;
emu68->bus_data = v;
mem68_write_w(emu68);
}
static inline void _write_EAW(emu68_t * const emu68,
const int mode, const int reg, const int68_t v)
{
emu68->bus_addr = get_eaw68[mode](emu68,reg);
emu68->bus_data = v;
mem68_write_w(emu68);
}
static inline void _write_L(emu68_t * const emu68, addr68_t addr, int68_t v)
{
emu68->bus_addr = addr;
emu68->bus_data = v;
mem68_write_l(emu68);
}
static inline void _write_EAL(emu68_t * const emu68,
const int mode, const int reg, const int68_t v)
{
emu68->bus_addr = get_eal68[mode](emu68,reg);
emu68->bus_data = v;
mem68_write_l(emu68);
}
#define write_B(ADDR,V) _write_B(emu68,(ADDR),(V))
#define write_W(ADDR,V) _write_W(emu68,(ADDR),(V))
#define write_L(ADDR,V) _write_L(emu68,(ADDR),(V))
#define write_EAB(MODE,PARM,V) _write_EAB(emu68,(MODE),(PARM),(V))
#define write_EAW(MODE,PARM,V) _write_EAW(emu68,(MODE),(PARM),(V))
#define write_EAL(MODE,PARM,V) _write_EAL(emu68,(MODE),(PARM),(V))
EMU68_EXTERN
int68_t mem68_nextw(emu68_t * emu68);
EMU68_EXTERN
int68_t mem68_nextl(emu68_t * emu68);
#define get_nextw() mem68_nextw(emu68)
#define get_nextl() mem68_nextl(emu68)
EMU68_EXTERN void mem68_pushl(emu68_t * emu68, int68_t v);
EMU68_EXTERN void mem68_pushw(emu68_t * emu68, int68_t v);
EMU68_EXTERN int68_t mem68_popl(emu68_t * emu68);
EMU68_EXTERN int68_t mem68_popw(emu68_t * emu68);
#define pushl(V) mem68_pushl(emu68,(V));
#define pushw(V) mem68_pushw(emu68,(V));
#define popl() mem68_popl(emu68);
#define popw() mem68_popw(emu68);
EMU68_EXTERN
void emu68_mem_init(emu68_t * const emu68);
EMU68_EXTERN
void emu68_mem_reset(emu68_t * const emu68);
EMU68_EXTERN
void emu68_mem_new_area(emu68_t * const emu68, u8 area,
memfunc68_t *read_bwl,
memfunc68_t *write_bwl);
EMU68_EXTERN
void emu68_mem_reset_area(emu68_t * const emu68, u8 area);
#endif