/*
 * $Date: $
 * $Source: $
 * $Revision: $
 * $State: $
 *
 * $Log: $
 *
 * DANG_END_CHANGELOG
 */

#ifndef _BOCHS_CPU_H
#define _BOCHS_CPU_H

#include "types.h"

#include "bx_bochs.h"

typedef unsigned char  ubyte_t;
typedef unsigned short uword_t;
typedef unsigned long  udword_t;

ubyte_t read_byte(ubyte_t *addr);
void write_byte(ubyte_t *addr, ubyte_t val);
uword_t read_word(uword_t *addr);
void write_word(uword_t *addr, uword_t val);
udword_t read_dword(udword_t *addr);
void write_dword(udword_t *addr, udword_t val);


#define READ_BYTE(addr)         read_byte((ubyte_t *) (addr))
#define WRITE_BYTE(addr, val)   write_byte((ubyte_t *) (addr), val)
#define READ_WORD(addr)         read_word((uword_t *) (addr))
#define WRITE_WORD(addr, val)   write_word((uword_t *) (addr), val)
#define READ_DWORD(addr)        read_dword((udword_t *) (addr))
#define WRITE_DWORD(addr, val)  write_dword((udword_t *) (addr), val)

#ifndef WORD
#define WORD(val)   ((uword_t) val)
#endif


/* this is used like: REG(eax) = 0xFFFFFFF */
#define REG(reg) (bx_cpu.##reg)
#define REGS  vm86s.regs   /* hack to keep inte8() happy */

#define READ_SEG_REG(reg) (bx_cpu.##reg.selector.value)
#define WRITE_SEG_REG(reg, val) bx_load_seg_reg(&bx_cpu.##reg, val)

/* these are used like:  LO(ax) = 2 (sets al to 2) */
#define LO(reg)  (*(((Bit8u *) &bx_cpu.e##reg) + BX_REG8L_OFFSET))
#define HI(reg)  (*(((Bit8u *) &bx_cpu.e##reg) + BX_REG8H_OFFSET))

#define _LO(reg) error("macro _LO() not supported!\n")
#define _HI(reg) error("macro _HI() not supported!\n")

/* these are used like: LWORD(eax) = 65535 (sets ax to 65535) */
#define LWORD(reg) (*(((Bit16u *) &bx_cpu.##reg) + BX_REG16_OFFSET))
#define HWORD(reg) (*(((Bit16u *) &bx_cpu.##reg) + (2-BX_REG16_OFFSET)))

#define _LWORD(reg)   error("macro _LWORD() not supported!\n")
#define _HWORD(reg)   error("macro _HWORD() not supported!\n")

/* this is used like: SEG_ADR((char *), es, bx) */
#define SEG_ADR(type, seg, reg) \
                 type((bx_cpu.##seg.selector.value << 4) + LWORD(e##reg))

#define WRITE_FLAGS(val)  bx_write_eflags((Bit32u) val)
#define READ_FLAGS()      bx_read_eflags()

#define MEMCPY_2UNIX(unix_addr, dos_addr, n) \
	memcpy_2unix(unix_addr, dos_addr, n)

#define MEMCPY_2DOS(dos_addr, unix_addr, n) \
	memcpy_2dos(dos_addr, unix_addr, n)

#define MEMCPY_DOS2DOS(dos_addr, unix_addr, n) \
	memcpy_dos2dos(dos_addr, unix_addr, n)

#define MEMCMP_DOS_VS_UNIX(dos_addr, unix_addr, n) \
	memcmp_dos_vs_unix(dos_addr, unix_addr, n)

#endif /* _BOCHS_CPU_H */
