/***********************************************************************\

	Product Number: PROXLIB-01-2.0

	Version: rev2.0

	Product Name: Proximity Subroutine Library

	Filename: proxio.c


	This document contains private and confidential information and
	its disclosure does not constitute publication.  Some of the
	information herein also may appear in United States and or
	Foreign Patents Pending.  All rights are reserved by Proximity
	Technology Inc., except those specifically granted by license.

\***********************************************************************/

#include <prodos.h>
#include <stdio.h>
#include <memory.h>
#include "proxio.h"
#include "spdef.h"
#include "driver.h"

/* These are the routines that we use which call standard I/O.  Note that 
	the functions provided are a small subset of the capability of standard 
	I/O, and therefor the programmer may wish to dispense with standard I/O 
	and use the system's I/O directly.  */
	

/*
 * take a C string & copy it into a Class 1 string, allocated.
 */
char *c2pstr1(src)
char *src;
{
	char *dest;
	unsigned size;
	
	size = strlen(src);						    /*  2 bytes for the length & 1 for the trailing null */
	dest = *D_MUSTHANDLE((unsigned long) (size + 3),attrLocked);
	asm {
		bcc gotit
		lda #0xFFFF
		sta dest
		sta dest+2
		bra exit
	}
gotit:
	strcpy(dest+2,src);
	*(unsigned *) dest = size;

exit:	
	return dest;
}


/*
 * take a Class 1 string & copy it into a C string, allocated.
 *
char *p1str2c(src)
char *src;
{
	char *dest
	unsigned size;
	
	size = *(unsigned *) src;
	dest = *D_MUSTHANDLE((unsigned long) size+1, attrLocked);
	asm {
		bcc gotit
		lda #0xFFFF
		sta dest
		sta dest+2
		bra exit
	}
gotit:
	BlockMove(src+2,dest,(unsigned long) size);
	dest[size] = '\0';
exit:
	return dest;
}
 */

HANDLE stdopen(name, mode)
char    *name;                  /* The file name */
unsigned mode;                   /* The file mode */
{
unsigned refnum;
char *name1;
unsigned err;

	err = 0;
	name1 = c2pstr1(name);
	refnum = D_OPEN2(name1,(mode == H_RDWR) ? READ_ENABLE|WRITE_ENABLE : READ_ENABLE);
	asm { bcc OK }
		err = 0xFFFF;

OK:
	D_DISPOSEPTR(name1);
	
	if (err)
		return(H_ERROR);
	
	return((HANDLE) refnum);
}

/* This create opens too, for convenience */

HANDLE stdcreate(name, ftype, atype)
char    *name;                  /* The file name */
unsigned ftype;
long    atype;
{
char *name1;
unsigned err;

	err = 0;
	name1 = c2pstr1(name);
	D_CREATE2(name1,ftype,atype);
	asm { bcc OK }
		err = 0xFFFF;
OK:
	D_DISPOSEPTR(name1);
	
	if (err)
		return(H_ERROR);
	
						/* if you're creating it, surely you'll be writing to it */
	return(stdopen(name, H_RDWR)); 
}

stdclose(file)
HANDLE  file;
{
	D_CLOSE2((short) file);
}

stdread(ptr, cnt, file)
char    *ptr;
unsigned cnt;
HANDLE  file;
{
	return (short) D_READ2((short) file,ptr,(unsigned long) cnt);
}

stdwrite(ptr, cnt, file)
char    *ptr;
unsigned cnt;
HANDLE  file;
{
	return (short) D_WRITE2((short) file,ptr,(unsigned long) cnt);
}

stdseek(posn, file)
long    posn;
HANDLE  file;
{
MarkRec mrec;
unsigned err;

	/* if ... */
	asm {
		phx
		pha
		pei file
		pea #0
		pei posn+2
		pei posn
		jsl >D_SETMARK2
		sta err
		pla
		plx
		bcc exit

		lda err
		cmp #positionRangeErr
		bne exit
	}
	/* then ... */
		asm {
			phx
			pha
			pei file
			pea #0
			pei posn+2
			pei posn
			jsl >D_SETEOF2
			sta err
			pla
			plx

			lda err			
			bne exit

			phx
			pha
			pei file
			pea #0
			pei posn+2
			pei posn
			jsl >D_SETMARK2
			sta err
			pla
			plx
		}

exit:
	return(err ? ERROR : OKAY);
}

long stdend(file)
HANDLE  file;
{
	return D_GETEOF2((short) file);
}
