[comp.sys.cbm] inputting from the modem port in commdore basic

treesh@vangogh.helios.nd.edu (01/04/91)

Hello everyone, I have run into a small snag in programming project that
Im currently involved with.  I have written a subroutine in basic that
looks at the Commodore 128's RS232 port, and waits for a string of ascii
(petascii) data to come into it, then will terminate and RETURN from the
subroutine once a carrage-return charector is transmitted.  The received
string will be in the variable a$.  This subroutine also needs to monitor
two other conditions.   "Timeout" and "Carrier Drop".  Upon any of these
three conditions, the subroutine will terminate with a RETURN, and a$
will contain the valid data, or the error message if either of the two
error conditions are ture.  This is the code I have that will do the job
in C128 basic.

1000 for t=1to1500:get#131,a$:a=peek(rs232status)
1010 ifa=<carrierok>anda$=""then next:a$="timeout":return
1020 ifa=<nocarrier>thena$="Loss of Carrier":return
1030 ifa$=chr$(13)thena$=a1$:return
1040 a1$=a1$+a$:goto1000

In 128 basic, this code does the job perfectly so long as the string size
does not get too large, since the C128 has a 512 byte rs232 buffer, and
the typical string size that this thing will be dealing with is under 100
bytes, it works fine even at 2400 baud connect.

So whats the problem??

Well, a 100 byte string sent into this routine will take over 15 solid
seconds to return with the received data in a$.  The checks for time out
and carriere detect are a MUST, and thus thats why I dont use INPUT#131
instead of a incremented GET#131 command.  I need a faster way to do all
three conditions (valid data, error message 1, error message 2).  1 second
is all the time delay I want for the entire string, not 1 second per byte!!
 
Anyone have any ideas for me on this???

ctfm
 

cs4344af@evax.arl.utexas.edu (Fuzzy Fox) (01/04/91)

In article <1991Jan3.204035.20778@news.nd.edu> treesh@vangogh.helios.nd.edu writes:
>1000 for t=1to1500:get#131,a$:a=peek(rs232status)
>1010 ifa=<carrierok>anda$=""then next:a$="timeout":return
>1020 ifa=<nocarrier>thena$="Loss of Carrier":return
>1030 ifa$=chr$(13)thena$=a1$:return
>1040 a1$=a1$+a$:goto1000

Two things I noticed first off.  First, you are looping from 1 to 1500.
There is no guarantee that looping from 1 to 1500 will produce a one-
second delay.  C128 and C64 Basic are written differently and take
different amounts of time to do their tasks, even if you discount 1 MHz/
2 Mhz modes.

Second, I noticed you have a "conditional NEXT" statement, which means
that the FOR loop may or may not hit its corresponding NEXT statement
before you RETURN from the subroutine.  This can cause stack overflows,
depending on how the Basic is written.  It is definitely not a good
programming practice.  I suppose this is more a "peeve" of mine than
anything else.

>In 128 basic, this code does the job perfectly so long as the string size
>does not get too large, since the C128 has a 512 byte rs232 buffer...

The C128 and C64 both have a 256 byte input buffer and a 256 byte output
buffer.  The RS-232 routines are almost identical.

Here's how I would write the above routine (for what it's worth):

1000 a1$=""
1010 t=ti
1020 ifti<tthen1010
1030 ifti-t>60thena$="Timeout":return
1040 a=peek(rs232status):ifa=<nocarrier>thena$="Loss of Carrier":return
1050 get#131,a$:ifa$=chr$(13)thena$=a1$:return
1060 a1$=a1$+a$:goto1020

The use of the variable TI allows you to use the Jiffy Clock (accurate
enough over 1 second) to measure the amount of time since input began,
and works regardless of whether the Basic is compiled, running on a C128
or C64, 1 or 2 MHz, whatever.

Line 1020 is only there to check that the Jiffy Clock hasn't wrapped
around from 235959 to 000000.  It will turn a 1-second delay into a
2-second delay if it occurs at a 24-hour boundary.  Big deal.  :)

I'm using code almost identical to this in my own BBS software, so I
think it works.  :)
-- 
begin 644 .signature
G5&AI<R!S<&%C92!I;G1E;G1I;VYA;&QY(&QE9G0@8FQA;FLN#0H:
 
end

treesh@vangogh.helios.nd.edu (01/04/91)

Looking at your code, it would appear that your trying to achive a one second
time limit on the input.  Thats not exactaly what I was trying to get at,
the dealy before timeout would actually be about 1 full miniute before
it gives up with a time out error.  I guess all I need to do is change
the value at line 1030.
 
Also, looking at your logic of GETTING a$ from the modem port, your not making
a check for a null, instead your popping right into your a1$=a1$+a$.  If
a$ was a null, and then it was added, would that change a1$?  Probabaly not
right?  Or would it acutally insert a ton of chr$(0)'s into a1$??
 
Time to do some checking on that one, Im not sure!!

Hopefully this will do the job for me, I have been up all night trying 
different ML approaches to this problem, suffering deeper and deeper brain
dammage!!! hahaha
 
ctfm

an207@cleveland.Freenet.Edu (David DeSimone) (01/07/91)

In a previous article, treesh@vangogh.helios.nd.edu writes:
>Also, looking at your logic of GETTING a$ from the modem port, your not making
>a check for a null, instead your popping right into your a1$=a1$+a$.  If
>a$ was a null, and then it was added, would that change a1$?  Probabaly not
>right?  Or would it acutally insert a ton of chr$(0)'s into a1$??

When GET gets a CHR$(0), it changes it to "" (a null string) I believe.
So you could check for a null if you wish, but only if you need to speed
up the code some.  Couldn't hurt.  The biggest danger is overflowing a1$
with more than 255 characters, which I didn't check for.

>Hopefully this will do the job for me, I have been up all night trying 
>different ML approaches to this problem, suffering deeper and deeper brain
>dammage!!! hahaha

Who needs ML?  Just use compiled Basic.  :)

--
begin 644 .signature
G5&AI<R!S<&%C92!I;G1E;G1I;VYA;&QY(&QE9G0@8FQA;FLN#0H:
 
end

treesh@bach.helios.nd.edu (01/07/91)

I have put your code to use, and the overall speed imporvment was good
but still not good enough.  It still took an average of about 1 second 
per byte to process.  This extreemly slow time may also be the 
result of having arround 200 or some other variables in ram at the time
thus making any string functions extreemly slow to execute when dealing
with variables.
 
I have written an ML routine that will speed-slam bytes from the modem
into ram.  It also keeps track of the total length of the string, and
a chr$(13) actally is the only way out of the ML before it RTS's back
to basic.  
 
What I need now is a fast (Super Fast ML) way to get this data into the 
basic variable A$.  Using a loop of basic peeks will put be right back
into the same boat as before with a speed problem.  Anyone know a good way
to take a set of ascii bytes in sequential ram and get them into a 
basic string variable via the use of ML???   I sure dont!!
 
Any hot-shots out there?  These are the specs:
 
 
ram : 7377 - 7461 : this is the buffer of ascii thats received by the
      previously mentioned ML routine, the last byte of the string
      will have a 13 signifing that the end.
ram : 7376 : This is the lenght of the string including the 13.

Can someone tell me how to use ML, knowing these things how to put 
that string of bytes into the basic varable A$??

PS - This is on a C128 in 80 colum mode.

ctfm