[net.micro.atari16] GENLIB fix for reading standard input from the keyboard

TPC862@ESTEC.BITNET (10/22/86)

This is a fix for gemlib distributed with the toolkit (not the latest version)
that has the problem of not correctly reading standard input from the keyboard.
I did some disassembling with SID and found a fix by changing the routines
read() and _pc_read() in gemlib. Read calls _rdasc() for ASCII files (CRLF->LF
conversion) and _rdbin() for binary files. _rdasc() and _rdbin() call
_pc_read() which (finally) calls the GEMDOS Fread routine.

I know the real fix is to throw all those CPM68K fileio routines out
and replace them completely, but this works for the time being.
It works correctly with and without standard input/output redirection (tested
with Beckemeyers Micro C-Shell, single user version).

Assemble pcrnew.s and rename the object file to pcr.o.
Compile readnew.c and rename the object file to read.o
Replace the modules read.o and pcr.o in gemlib with AR68 or with ARXX (an
AR68 replacement I wrote, which will be posted within the next few days).
-----------------cut here-----------pcrnew.s-----------------------------------
*	pcrnew.s  Together with readnew.c a fix for reading from stdin
*	          in original Atari Toolkit gemlib
*
*	Author:	Ton van Overbeek
*		TPC862@ESTEC.BITNET

		.globl	__pc_read
		.globl	__pc_write
		.globl	lmul
		.globl	_trap

		.text

__pc_read:	link	a6,#-2
		movem.l	d5-d7,-(a7)
		move.l	8(a6),a0	fd
		move.w	-$e(a0),-$2(a6)	GEMDOS handle
		move.l	$10(a6),(a7)	buffer
		move.w	$16(a6),a0	# of sectors
		move.l	a0,-(a7)
		move.w	$14(a6),a0	sectorsize
		move.l	a0,-(a7)
		jsr	lmul		# of sectors * sectorsize
		addq.l	#8,a7
		move.l	d0,d6		save count		
		move.l	d0,-(a7)	count
		move.w	-$2(a6),-(a7)	handle
		move.w	#$3f,-(a7)	F_Read
		jsr	_trap
		addq.l	#8,a7

*	Now we test if we deal with stdin from the keyboard
*	This is so if 1. GEMDOS handle = 0
*	              2. F_Read didn't return with an error
*	              3. Handle 0 is not redirected (Tested by
*	                 Fseek returning 0 if not redirected)
*                and  4. Read count is less than the max count

		tst.w	-2(a6)		filehandle = 0 ?
		bne	pcrend		no
		tst.l	d0		yes, GEMDOS error ?
		blt	pcrend		yes
		move.l	d0,d7		no, save read count in d7
		move.w	#$1,(a7)	handle 0 redirected ?
		clr.w	-(a7)
		clr.l	-(a7)
		move.w	#$42,-(a7)
		jsr	_trap
		addq.l	#$8,a7
		tst.l	d0		yes, if seek result > 0
		bne	restord0
		cmp.l	d7,d6		read count = max count ?
		beq	restord0	yes, no action

*	Now we are dealing with a read from the keyboard terminated
*	by CR. The CR is not put in the buffer by GEMDOS. Because
*	the C library wants LF, we add a LF to the buffer.
*	To stop the calling routine (__rdasc) from calling us again
*	we also put in ^Z to signal End-Of-File. This is corrected
*	in read again (See readnew.c)

		move.l	#LF,(a7)	
		move.l	#$1,-(a7)	1 char to write
		move.w	#-$1,-(a7)	handle -1 is always screen
		move.w	#$40,-(a7)	F_Write
		jsr	_trap
		addq.l	#$8,a7
		move.l	d7,d0		restore count
		movea.l	$10(a6),a0	buffer
		adda.l	d0,a0		last char in buff + 1
		move.b	#$a,(a0)+	put in '\n'
		move.b	#$1a,(a0)	and ^Z to stop __rdasc reading
		addq.l	#$2,d0		adjust # of chars in buffer
		bra	pcrend

restord0:	move.l	d7,d0
pcrend:		tst.l	(a7)+
		movem.l	(a7)+,d6-d7
		unlk	a6
		rts

		.data
LF:		dc.b	$a
		.even

		.text
__pc_write:	link	a6,#-6
		move.l	8(a6),a0
		move.w	-$e(a0),-$2(a6)		handle
		move.l	$10(a6),(a7)		buffer
		move.w	$16(a6),a0
		move.l	a0,-(a7)
		move.w	$14(a6),a0
		move.l	a0,-(a7)
		jsr	lmul
		addq.l	#8,a7
		move.l	d0,-(a7)
		move.w	-$2(a6),-(a7)
		move.w	#$40,-(a7)
		jsr	_trap
		addq.l	#8,a7
		unlk	a6
		rts
---------------cut here--------end of pcrnew.s---------------------------------

---------------cut here--------readnew.c---------------------------------------
/*
 *	readnew.c  Together with pcrnew.s a fix for reading from stdin
 *	           in original Atari Toolkit gemlib
 *
 *	Author:	Ton van Overbeek
 *		TPC862@ESTEC.BITNET
 */

extern int errno;
extern int _errcpm;
extern int __cpmrv;

read(fd, buffer, bytes)
int fd;
char *buffer;
int bytes;
{
   register int *fp, retval;
   register long count;
   int *_chkc();

   if (!(fp = _chkc(fd))) return -1;		/* check channel */
   if (*fp & 0x20) return 0;			/* End-Of-File bit */
   if (*fp & 0x04) {				/* Error bit */
      errno = 9;
      _errcpm = __cpmrv;
      return -1;
   }
   if (*fp & 0x10) {				/* ASCII bit */
      retval = _rdasc(fp, buffer, (count = bytes));
      if (fd == 0 && retval > 0) {		/* if stdin and some chars */
						/* read, reset the EOF bit */
						/* set by pcrnew to stop   */
						/* _rdasc() reading        */
         *fp &= ~0x20;
      }
      return retval;
   } else {					/* read binary */
      return _rdbin(fp, buffer, (count = bytes));
   }
}
---------------cut here--------end of readnew.c--------------------------------
Ton van Overbeek
European Space Research and Technology Centre (ESTEC)
Control Systems Section
P.O.Box 299
2200 AG Noordwijk, The Netherlands.
Phone: +31 1719 83041
Email: TPC862%ESTEC.BITNET@WISCVM.WISC.EDU  (ARPA)
       ...!ucbvax!tpc862@estec.bitnet       (USENET/UUCP)
       TPC862@ESTEC                         (EARN/BITNET)