/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:pcifmove.c 12.0$ */
/* $ACIS:pcifmove.c 12.0$ */
/* $Source: /ibm/acis/usr/sys/os2code/RCS/pcifmove.c,v $ */

/*
 * Copyright University of Southern California, 1988
 */

#include    	<subcalls.h>
#include    	<doscalls.h>
#include	<stdio.h>
#include	"pctype.h"
#include	"pcparam.h"
#include	"rb.h"
#include	"os2ioctl.h"
#include	"os2data.h"


u_long	set_window();

/* move count bytes from pcaddr on PS/2 to unixaddr on ROMP */
moveout(unixaddr, pcaddr, count)
	u_long          unixaddr;
	char far       *pcaddr;
	u_short         count;
{
	char far *pcif_addr;
	u_short		offset;
	u_short		left_seg;
	long		resid;

	unixaddr &= 0x00ffffff;

	cbcbptr->write_count++;
	cbcbptr->write_bytes += count;
	/* translate unixaddr into PS/2 address */
	cli();
	offset = (u_short)set_window(0, unixaddr);

	left_seg = ~offset;	/* magic which means 0xffff -offset */
	resid = ((long)count - ((long)left_seg+1));
	count = (resid > 0 ? left_seg+1:count);
	pcif_copy(pcaddr,(pc_wind1 + offset),count);
	if (resid > 0) {
		pcaddr += count;
		pcif_copy(pcaddr,pc_wind2,(u_short)resid);
	}
	sti();
	return(0);
}

/* move count bytes from pcaddr on PS/2 to unixaddr on ROMP */
movein(unixaddr, pcaddr, count)
	u_long          unixaddr;
	char far       *pcaddr;
	u_short         count;
{
	char far *pcif_addr;
	u_short		offset;
	u_short		left_seg;
	long		resid;

	unixaddr &= 0x00ffffff;

	cbcbptr->read_count++;
	cbcbptr->read_bytes += count;
	/* translate unixaddr into PS/2 address */
	cli();
	offset = (u_short)set_window(0, unixaddr);
	left_seg = 0xffff-offset;
	resid = ((long)count - ((long)left_seg+1));
	count = (resid > 0 ? left_seg+1:count);
	pcif_copy((pc_wind1 + offset),pcaddr,count);
	if (resid > 0) {
		pcaddr += count;
		pcif_copy(pc_wind2,pcaddr,(u_short)resid);
	}
	sti();
	return(0);
}

u_long
set_window(window, rompaddr)
	int             window;
	u_long          rompaddr;
{
	u_long          rval;
	u_short         wval = LOBYTE(HIWORD(rompaddr));

	if (window > 3)		/* Value check window, only 0-3 valid */
		return (-1);

	IOOUT(r_base + window, wval);

	/*
	 * Set up the next window. 
	 */
	if (window < 3)
		IOOUT(r_base + window + 1, wval + 1);

	rval =  (u_long)LOWORD(rompaddr);

	return (rval);
}

