#include <stdio.h>

#include "lisp.h"
#include "globals.h"
#include "validate.h"
#include "os.h"
#include "arch.h"
#include "lispregs.h"
#include "signal.h"

char *arch_init()
{
    return NULL;
}

os_vm_address_t arch_get_bad_addr(scp)
struct sigcontext *scp;
{
    return 0;
}

boolean arch_pseudo_atomic_atomic(struct sigcontext *scp)
{
    /* We don't need pseudo_atomic on the x86 because we don't take */
    /* signals at random places. */

    return FALSE;
}

void arch_set_pseudo_atomic_interrupted(struct sigcontext *scp)
{
    lose("Can't set pseudo_atomic_interrupted on the x86.");
}

void arch_skip_instruction(scp)
struct sigcontext *scp;
{
    /* This should only ever used to skip over ``INT n'' instructions. */
    /* The only complication is that if the ``n'' is trap_Cerror, then */
    /* we want to skip over the error description noise also. */

    char *pc = (char *)scp->sc_eip;

    if (*pc++ != 0xcd)
	lose("bad use of arch_skip_instruction.");
    if (*pc++ == trap_Cerror)
	pc += *pc;

    scp->sc_eip += (unsigned long)pc;
}

unsigned long arch_install_breakpoint(void *pc)
{
    unsigned char orig_inst = *(unsigned char *)pc;

    *(unsigned char *)pc = 0xcc;

    return orig_inst;
}

void arch_remove_breakpoint(void *pc, unsigned long orig_inst)
{
    *(unsigned char *)pc = orig_inst;
}

void arch_do_displaced_inst(struct sigcontext *scp, unsigned long orig_inst)
{
    /* We put the orignal instruction back in, turn on the single step */
    /* trap flag, and then sigreturn.  We will end up in the breakpoint trap */
    /* handler after that instruction has run.  It will put the breakpoint */
    /* back in, turn off the single step trap bit and then just return. */

    *(unsigned char *)pc = orig_inst;
    scp->sc_efl |= 0x00000200;
    sigreturn(scp);
}

void arch_install_interrupt_handlers(void)
{
}
