[comp.sources.atari.st] v01i088: mx2v230 -- Multitasking kernel with utilities part08/08

koreth@ssyx.ucsc.edu.ucsc.edu (Steven Grimm) (12/28/88)

Submitted-by: madsen@sask.usask.ca (Jorgen Madsen)
Posting-number: Volume 1, Issue 88
Archive-name: mx2v230/part08

#!/bin/sh
# this is part 8 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file XMODEM.MOD continued
#
CurArch=8
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
sed 's/^X//' << 'SHAR_EOF' >> XMODEM.MOD
X        WriteInt(mdmBadPackets,12);
X        WriteLn;
X        WriteString(" Naked packets sent  ");
X        WriteInt(mdmNakedPackets,12);
X        WriteLn;
X        WriteString(" Bytes transferred   ");
X        WriteAdr(ADDRESS(mdmBytesXferred),12);
X        WriteLn;
XEND             xmodemstat;
X
XPROCEDURE       setbuffer(char: CharPtr; length: CARDINAL; value: CHAR);
XVAR             data            :        POINTER TO CHAR;
XBEGIN
X        WHILE length#0 DO
X              data:=ADDRESS(char);
X              data^:=value;
X              INC(char);
X              DEC(length);
X        END;
XEND             setbuffer;
X
XPROCEDURE       writeModem(char: CharPtr; count: LONGCARD);
XVAR             data             :        POINTER TO CHAR;
XBEGIN
X        WHILE count#0 DO
X              DEC(count);
X              data:=ADDRESS(char);
X              INC(char);
X
X              sendchar(data^);
X        END;
XEND             writeModem;
X
XPROCEDURE       readModem(VAR char: CHAR; time: INTEGER);
XVAR             data         :  CHAR;
X                longchar     :  LONGCARD;
X                t            :  BITSET;
X                WaitTime     :  LONGCARD;
X                ticks        :  CARDINAL;
XBEGIN
X        IF time=0 THEN
X           IF BConStat(AUX) THEN (* return char *)
X              longchar:=BConIn(AUX);
X              t:=BITSET(longchar);
X              EXCL(t,8);
X              char:=CHAR(t);
X              RETURN; 
X           ELSE
X              char:=CHAR(255);
X              RETURN;
X           END;
X        END;
X
X        WaitTime:=LONGCARD(time)+(GetTime() DIV 20);
X        ticks:=0;
X        LOOP
X                IF BConStat(AUX) THEN
X                   longchar:=BConIn(AUX);
X                   t:=BITSET(longchar);
X                   EXCL(t,8);
X                   char:=CHAR(t);
X                   RETURN;
X                END;
X        IF ((GetTime() DIV 20)>WaitTime) 
X        OR ((GetTime() DIV 20)=WaitTime) THEN
X           INC(ticks);
X           WaitTime:=LONGCARD(time)+(GetTime() DIV 20);
X           IF ticks=2 THEN
X              char:=CHAR(255);
X              RETURN;
X           END;
X        END;
X        END; (* loop *)
XEND             readModem;
X
XPROCEDURE       flushinput();
XVAR             char    :       LONGCARD;
XBEGIN
X        WHILE BConStat(AUX) DO
X              char:=BConIn(AUX);
X        END;
XEND             flushinput;
X
XPROCEDURE       sendchar(char: CHAR);
XBEGIN
X        BConOut(AUX,char);
XEND             sendchar;
X
XPROCEDURE       xmodemrec(filename: ARRAY OF CHAR): BOOLEAN;
XVAR             sectnum,sectcurr,sectcomp,fd            :       INTEGER;
X                errors                                  :       INTEGER;
X                firstchar                               :       CHAR;
X                errorflag,goodcheck,crc1,crc2           :       BOOLEAN;
X                checksum,j,bufptr                       :       CARDINAL;
X                b                                       :       LONGCARD;
X                bufr                                    :       ARRAY [0..BUFSIZ] OF CHAR;
XBEGIN
X        IF rec OR snd THEN
X           WriteLn;
X           WriteString(" XMODEM already active! ");
X           WriteLn;
X           RETURN FALSE;
X        END;
X        rec:=TRUE;
X        mdmini();
X        SFirst(filename,0,result);
X        IF result=0 THEN
X           WriteLn;
X           WriteString(filename);
X           WriteString(" already exists! ");
X           WriteLn;
X           errorbells;
X           xmodemerror:=(-1);
X           rec:=FALSE;
X           RETURN FALSE;
X        END;
X        Create(filename,0,fd);
X        IF fd<0 THEN
X           WriteLn;
X           WriteString("GEMDOS ERROR # ");
X           WriteInt(fd,2);
X           WriteLn;
X           xmodemerror:=fd;
X           IF Close(fd) THEN END;
X           rec:=FALSE;
X           RETURN FALSE;
X      ELSE
X           Assign(xfrname,filename);
X           WriteString(" receiving ");
X           WriteString(filename);
X           WriteLn;
X        END;
X(*        crcmode:=TRUE; *)
X        sectnum:=0; errors:=0; bufptr:=0;
X        flushinput();
X        IF crcmode THEN
X           sendchar(C);
X        ELSE
X           sendchar(NAK);
X        END;
X
X        WHILE (firstchar#EOT) AND (errors#ERRORMAX) DO
X              errorflag:=FALSE;
X
X              t1:=timerset(50);
X              REPEAT
X                readModem(readchar,5);
X                firstchar:=readchar;
X                IF xmodemabort THEN
X                   IF Close(fd) THEN END;
X                   xmodemerror:=(-11);
X                   rec:=FALSE;
X                   RETURN FALSE;
X                END;
X                IF timeup(t1) THEN
X                   t1:=timerset(50);
X                   flushinput();
X                   IF crcmode THEN
X                      sendchar(C);
X                   ELSE
X                      sendchar(NAK);
X                   END;
X                   IF errors>ERRORMAX DIV 2 THEN crcmode:=NOT crcmode END;
X                   INC(errors);
X                   IF errors>ERRORMAX THEN 
X                      IF Close(fd) THEN END;
X                      xmodemerror:=(-1);
X                      rec:=FALSE;
X                      RETURN FALSE;
X                   END;
X                END;
X              UNTIL (firstchar=SOH) OR (firstchar=EOT);
X
X              IF firstchar=SOH THEN
X                 readModem(readchar,5);
X                 sectcurr:=INTEGER(readchar);
X                 readModem(readchar,5);
X                 sectcomp:=INTEGER(readchar);
X                 IF sectcurr+sectcomp=255 THEN
X                    IF sectcurr=IAnd255(sectnum+1) THEN
X                       checksum:=0;
X                       FOR j:=bufptr TO bufptr+SECSIZ-1 DO
X                           IF xmodemabort THEN
X                              IF Close(fd) THEN END;
X                              xmodemerror:=(-11);
X                              rec:=FALSE;
X                              RETURN FALSE;
X                           END;
X                           readModem(readchar,5);
X                           bufr[j]:=readchar;
X                           IF crcmode THEN
X                              checksum:=crcupdate(checksum,bufr[j]);
X                           ELSE
X                              checksum:=checksum+CARDINAL(bufr[j]);
X                           END;
X                       END; (* for *)
X
X                  IF crcmode THEN
X                     crc1:=FALSE; crc2:=FALSE;
X                     (*
X                     FOR j:=bufptr TO bufptr+SECSIZ-1 DO
X                         checksum:=crcupdate(checksum,bufr[j]);
X                     END;
X                     *)
X                     checksum:=crcfinish(checksum);
X                     readModem(readchar,5);
X                     IF readchar=CHAR(IAnd255(CARDINAL(WShr(checksum,8)))) THEN
X                        crc1:=TRUE;
X                     END;
X                     readModem(readchar,5);
X                     IF readchar=CHAR(IAnd255(checksum)) THEN
X                        crc2:=TRUE;
X                     END;
X                     IF crc1 AND crc1 THEN
X                        goodcheck:=TRUE;
X                     ELSE
X                        goodcheck:=FALSE;
X                     END;
X                  ELSE
X                  (*
X                     FOR j:=bufptr TO bufptr+SECSIZ-1 DO
X                         checksum:=checksum+CARDINAL(bufr[j]);
X                     END;
X                  *)
X                     readModem(readchar,5);
X                     IF checksum=CARDINAL(readchar) THEN
X                        goodcheck:=TRUE;
X                     ELSE
X                        goodcheck:=FALSE;
X                     END;
X                  END;
X
X
X                       IF goodcheck THEN
X                          INC(mdmPacketsReceived);
X                          errors:=0;
X                          INC(sectnum);
X                          bufptr:=bufptr+SECSIZ;
X                          mdmBytesXferred:=mdmBytesXferred+SECSIZ;
X                          IF bufptr=BUFSIZ THEN
X                             bufptr:=0;
X                             b:=BUFSIZ;
X                             Write(fd,b,ADR(bufr));
X                          END;
X(*     this is for error checking for the write *)
X                          flushinput;
X                          sendchar(ACK);
X                       ELSE
X                          INC(mdmBadPackets);
X                          errorflag:=TRUE;
X                       END; (* if *)
X                    ELSE
X                       IF sectnum=IAnd255(sectnum) THEN
X                          flushinput;
X                          sendchar(ACK);
X                       ELSE
X                          INC(mdmBadPackets);
X                          errorflag:=TRUE;
X                       END;
X                    END; (* if *)
X                 ELSE
X                    INC(mdmBadPackets);
X                    errorflag:=TRUE;
X                 END; (* if *)
X              IF errorflag THEN
X                 INC(errors);
X                 flushinput;
X                 IF crcmode THEN
X                    sendchar(C);
X                 ELSE
X                    sendchar(NAK);
X                 END;
X              END;
X              END; (* if *)
X        END; (* while *)
X        IF (firstchar=EOT) AND (errors< ERRORMAX) THEN
X           sendchar(ACK);
X           b:=LONGCARD(bufptr);
X           Write(fd,b,ADR(bufr));
X           IF Close(fd) THEN END;
X           xmodemerror:=0;
X           rec:=FALSE;
X           ok:=TRUE;
X           RETURN TRUE;
X        END;
X        IF Close(fd) THEN END;
X        xmodemerror:=(-1);
X        rec:=FALSE;
X        RETURN FALSE;
XEND             xmodemrec;
X
XPROCEDURE       xmodemsnd(filename: ARRAY OF CHAR): BOOLEAN;
XVAR             sectnum,attempts,fd          :   INTEGER;
X                checksum,j,bufptr            :   CARDINAL;
X                readchar,c,nak               :   CHAR;
X                b                            :   LONGCARD;
X                dtaAdr                       :   ADDRESS;
X                bufr                         :   ARRAY [0..BUFSIZ] OF CHAR;
XBEGIN
X        IF rec OR snd THEN
X           WriteLn;
X           WriteString(" XMODEM already active! ");
X           WriteLn;
X           RETURN FALSE;
X        END;
X        snd:=TRUE;
X(*        crcmode:=TRUE; *)
X        mdmini();
X        setbuffer(ADR(bufr),BUFSIZ,0c); (* clear buffer *)
X        Open(filename,0,fd);
X        IF fd<0 THEN
X           WriteLn;
X           WriteString("GEMDOS ERROR # ");
X           WriteInt(fd,2);
X           WriteLn;
X           xmodemerror:=fd;
X           IF Close(fd) THEN END;
X           snd:=FALSE;
X           RETURN FALSE;
X        ELSE
X           GetDTA(dtaAdr);
X           SFirst(filename,0,result);
X           filesize:=dtaAdr+26;
X           endblk:=INTEGER(((filesize^+127) DIV 128)+1);
X           Assign(xfrname,filename);
X           WriteString(" sending ");
X           WriteString(filename );
X           WriteInt(endblk,5);
X           WriteString(" block(s)");
X           WriteLn;
X        END;
X        attempts:=0;
X        sectnum:=1;
X        j:=0;
X        IF crcmode THEN
X           nak:=C;
X        ELSE
X           nak:=NAK;
X        END;
X        readModem(readchar,5);
X        c:=readchar;
X        WHILE (c#nak) AND (j<ERRORMAX) DO
X              readModem(readchar,20);
X              c:=readchar;
X              IF j> ERRORMAX DIV 2 THEN
X                 crcmode:=NOT crcmode;
X                 IF crcmode THEN
X                    nak:=C;
X                 ELSE
X                    nak:=NAK;
X                 END;
X              END;
X              INC(j);
X              IF xmodemabort OR (j=ERRORMAX) THEN
X                 IF Close(fd) THEN END;
X                 xmodemerror:=(-11);
X                 snd:=FALSE;
X                 RETURN FALSE;
X              END;
X        END; (* while *)
X        flushinput;
X        WHILE (endblk#0) AND (attempts#RETRYMAX) DO
X              setbuffer(ADR(bufr),BUFSIZ,CTRLZ); 
X              b:=BUFSIZ;
X              Read(fd,b,ADR(bufr));
X              bufptr:=0;
X              REPEAT
X                attempts:=0;
X                REPEAT
X                  IF xmodemabort THEN
X                     IF Close(fd) THEN END;
X                     xmodemerror:=(-11);
X                     snd:=FALSE;
X                     RETURN FALSE;
X                  END;
X                  sendchar(SOH);
X                  sendchar(CHAR(IAnd255(sectnum)));
X                  sendchar(CHAR(255-IAnd255(sectnum)));
X                  checksum:=0;
X                  writeModem(ADR(bufr[bufptr]),SECSIZ);
X                  IF crcmode THEN
X                     FOR j:=bufptr TO bufptr+SECSIZ-1 DO
X                         checksum:=crcupdate(checksum,bufr[j]);
X                     END;
X                     checksum:=crcfinish(checksum);
X                     sendchar(CHAR(IAnd255(CARDINAL(WShr(checksum,8)))));
X                     sendchar(CHAR(IAnd255(checksum)));
X                  ELSE
X                     FOR j:=bufptr TO bufptr+SECSIZ-1 DO
X                         checksum:=checksum+CARDINAL(bufr[j]);
X                     END;
X                     sendchar(CHAR(IAnd255(checksum)));
X                  END;
X                  flushinput;
X                  INC(mdmPacketsSent);
X                  INC(attempts);
X                  readModem(readchar,mtimeout);
X                  c:=readchar;
X                  IF c#ACK THEN 
X                     INC(mdmNakedPackets);
X                  END;
X                UNTIL (c=ACK) OR (attempts=RETRYMAX);
X                IF attempts#RETRYMAX THEN
X                   DEC(endblk);
X                   bufptr:=bufptr+SECSIZ;
X                   mdmBytesXferred:=mdmBytesXferred+SECSIZ;
X                   INC(sectnum);
X                END;
X              UNTIL (bufptr=BUFSIZ) OR (attempts=RETRYMAX) OR (endblk=0);
X        END; (* while *)
X
X        IF Close(fd) THEN END;
X        IF attempts=RETRYMAX THEN
X           xmodemerror:=(-1);
X           snd:=FALSE;
X           RETURN FALSE;
X        ELSE
X           attempts:=0;
X           REPEAT
X                sendchar(EOT);
X                INC(attempts);
X                readModem(readchar,5);
X                c:=readchar;
X           UNTIL (c=ACK) OR (attempts=RETRYMAX);
X           xmodemerror:=0;
X           snd:=FALSE;
X           ok:=TRUE;
X           RETURN TRUE;
X        END;
XEND             xmodemsnd;
X
XBEGIN
XEND XMODEM.
SHAR_EOF
chmod 0600 XMODEM.MOD || echo "restore of XMODEM.MOD fails"
sed 's/^X//' << 'SHAR_EOF' > XMODEMR.MOD &&
X(*
X        1       check xmodem status
X        2       change error-check method
X        99      abort xmodem
X*)
XMODULE  xmodemr;
XFROM    SYSCALL IMPORT  EnableSpint,DisableSpint;
XFROM    GEMDOS  IMPORT  OldTerm,ConOut;
XFROM    GEMX    IMPORT  BasePageAddress;
XFROM    SYSTEM  IMPORT  ADR,ADDRESS;
XFROM    XMODEM  IMPORT  xmodemrec,xmodemabort,crcmode,xmodemerror,
X                        xmodemstat;
XVAR     ok                              : BOOLEAN;
X        spintcmd                        : ARRAY [0..2] OF LONGCARD;
X        cmd                             : ARRAY [0..81] OF CHAR;
X        i,delay                         : CARDINAL;
X
XPROCEDURE       run;
XBEGIN
X        IF spintcmd[0]=1 THEN xmodemstat END;
X        IF spintcmd[0]=99 THEN xmodemabort:=TRUE END;
XEND             run;
X
XBEGIN
X        IF EnableSpint(1,run,ADR(spintcmd)) THEN
X           spintcmd[1]:=LONGCARD(xmodemstat);
X           crcmode:=TRUE;
X           FOR i:=1 TO ORD(BasePageAddress^.CmdLine[0])+1 DO
X              cmd[i-1]:=BasePageAddress^.CmdLine[i];
X           END;
X           cmd[ORD(BasePageAddress^.CmdLine[0])]:=0c;
X           IF BasePageAddress^.CmdLine[0]#0c THEN
X              IF cmd[0]='-' THEN
X                 crcmode:=FALSE;
X                 FOR i:=0 TO ORD(BasePageAddress^.CmdLine[0]) DO
X                    cmd[i]:=cmd[i+1];
X                 END;
X              END;
X           IF xmodemrec(cmd) THEN
X              ConOut(7c);
X           ELSE
X              FOR i:=0 TO 3 DO
X                 FOR delay:=0 TO 10000 DO END;
X                 ConOut(7c);
X              END;
X           END; (* get the file *)
X           END;
X           DisableSpint(1);
X           OldTerm;
X        END;
XEND     xmodemr.
X
SHAR_EOF
chmod 0600 XMODEMR.MOD || echo "restore of XMODEMR.MOD fails"
sed 's/^X//' << 'SHAR_EOF' > XMODEMT.MOD &&
X(*
X        1       check xmodem status
X        2       change error-check method
X        99      abort xmodem
X*)
XMODULE  xmodemt;
XFROM    SYSCALL IMPORT  EnableSpint,DisableSpint;
XFROM    GEMDOS  IMPORT  OldTerm,ConOut;
XFROM    GEMX    IMPORT  BasePageAddress;
XFROM    SYSTEM  IMPORT  ADR,ADDRESS;
XFROM    XMODEM  IMPORT  xmodemsnd,xmodemabort,crcmode,xmodemerror,
X                        xmodemstat;
XVAR     ok                              : BOOLEAN;
X        spintcmd                        : ARRAY [0..2] OF LONGCARD;
X        cmd                             : ARRAY [0..81] OF CHAR;
X        i,delay                         : CARDINAL;
X
XPROCEDURE       run;
XBEGIN
X        IF spintcmd[0]=1 THEN xmodemstat END;
X        IF spintcmd[0]=99 THEN xmodemabort:=TRUE END;
XEND             run;
X
XBEGIN
X        IF EnableSpint(1,run,ADR(spintcmd)) THEN
X           spintcmd[1]:=LONGCARD(xmodemstat);
X           crcmode:=TRUE;
X           FOR i:=1 TO ORD(BasePageAddress^.CmdLine[0])+1 DO
X              cmd[i-1]:=BasePageAddress^.CmdLine[i];
X           END;
X           cmd[ORD(BasePageAddress^.CmdLine[0])]:=0c;
X           IF BasePageAddress^.CmdLine[0]#0c THEN
X              IF cmd[0]='-' THEN
X                 crcmode:=FALSE;
X                 FOR i:=0 TO ORD(BasePageAddress^.CmdLine[0]) DO
X                    cmd[i]:=cmd[i+1];
X                 END;
X              END;
X           IF xmodemsnd(cmd) THEN
X              ConOut(7c);
X           ELSE
X              FOR i:=0 TO 3 DO
X                 FOR delay:=0 TO 10000 DO END;
X                 ConOut(7c);
X              END;
X           END; (* send the file *)
X           END;
X           DisableSpint(1);
X           OldTerm;
X        END;
XEND     xmodemt.
X
SHAR_EOF
chmod 0600 XMODEMT.MOD || echo "restore of XMODEMT.MOD fails"
sed 's/^X//' << 'SHAR_EOF' > XS.MOD &&
XMODULE  xs;
XFROM    SYSCALL         IMPORT  SpintInfo;
XFROM    GEMDOS          IMPORT  Term;
XFROM    Terminal        IMPORT  WriteString,WriteLn;
XVAR     spintcmd        :       POINTER TO ARRAY [0..2] OF LONGCARD;
X        XS              :       PROC;
X        ok              :       BOOLEAN;
XBEGIN
X        IF SpintInfo(1,spintcmd) THEN
X           XS:=PROC(spintcmd^[1]);
X           XS();
X        ELSE
X           WriteLn;
X           WriteString("Background xmodem not running");
X           WriteLn;
X           ok:=Term(-1);
X        END;
X        ok:=Term(0);
XEND     xs.
SHAR_EOF
chmod 0600 XS.MOD || echo "restore of XS.MOD fails"
rm -f s2_seq_.tmp
echo "You have unpacked the last part"
exit 0