[comp.sys.m6809] Uudecode for Microware BASIC

jimomura@lsuc.UUCP (05/10/87)

     The following is the first program I've gotten to work on Microware
BASIC under OS-9 68K.  As far as I can see it should work under 6809
versions without change, but I haven't tried it yet.  It seems to me
that BASIC09/Microware BASIC programs will be important for a while
because it is the language supplied with future "Personal OS-9" systems.
Those who have not seen Microware BASIC may be interested in knowing
that this is in fact a fairly old language, yet has features which
weren't seen commonly in BASICs until later (BOOLEAN types and
structures, automatic formatting just to name a few):

PROCEDURE udecode

      (* Udecode.bas -- decode a uuencoded file back to binary form
      (*
      (* Hacked for OS-9 by Jim Omura -- 87/05/08
      (* from Patrick Simon's Atari BASIC version and a
      (* couple of versions in C for Atari ST and Amiga.
      (* Some credit to Berie Roehl and who knows who else.
      (* This version is Public Domain.
      (*
      (* The following notes are from Simon's version:
      (*
      (* Slightly modified from a version posted to net.sources once;
      (* suitable for compilation on an IBM PC.
      (*
      (* modified for Lattice C on the ST - 11.05.86 by MSD
      (*
      (* rewritten for ST BASIC on the Atari ST - September 9, 1986,
      (* by Patrick Simon
      (*
      (* *********************************************************
      (*
      (* USAGE:
      (*
      (* udecode <inputfile >outputfile
      (*
      (* *********************************************************

      (* Declarations: *)

      BASE 1

      DIM bdeclen:INTEGER
      DIM byteout:INTEGER
      DIM cchar:STRING[1]\ (* Current Character *)
      DIM cntr:INTEGER\ (* Local counter for For Next Lps. *)

      DIM infile:STRING[80]
      DIM inline:STRING[80]
      DIM mask:INTEGER
      DIM more:BOOLEAN

      DIM numl:INTEGER

      DIM obuf:STRING[45]
      DIM obfoffst:INTEGER
      DIM obfpntr:INTEGER
      DIM outbyte(4):INTEGER
      DIM outfile:STRING[80]

      DIM stderr:INTEGER
      DIM stdin:INTEGER
      DIM stdout:INTEGER
      DIM spc:INTEGER
      DIM sptr:INTEGER\ (* String Pointer *)

      (* Set Constants: *)

      mask=63
      spc=ASC(" ")
      stdin=0
      stdout=1
      stderr=2

      (* Initializations: *)

      byteout=0
      obfpntr=ADDR(obuf)
      more=TRUE
      numl=0

      READ #stdin,obuf\ (* Input and ignore original filename. *)

      (* Now set up screen for user.
      (* CLEARW 2
      (* GOTOXY 1,2 \ PRINT "Decoding "; infile; " to "; OFILEN$
      (* GOTOXY 1,4 \ PRINT "# lines read in: "
      (* GOTOXY 1,5 \ PRINT "# bytes output: "

      IF EOF(#stdin) THEN
        more=FALSE
      ENDIF

      LOOP

      EXITIF NOT(more) THEN
      ENDEXIT

        READ #stdin,inline\ (* Get a Line *)
        IF inline="end" THEN
          more=FALSE\ (* All done *)
        ELSE

          numl=numl+1

          (* For each line, must "decode" each byte.
          (* First byte contains # bytes to ***output*** from this
          (* line.  Then, after decoding, each set of 4 input bytes
          (* contains 6*4 = 24 bits of information to output, 8
          (* bits per output byte, thus 3 output bytes.

          sptr=1\ (* Set up string position pointer for inline *)

          GOSUB 1000\ (* Get first byte = # bytes to output *)

          bdeclen=C
          N=bdeclen

          IF bdeclen=0 THEN \ (* No Data - 2nd end of file exit *)
            more=FALSE
          ELSE \ (* Process one line of input *)

            obfoffst=0\ (* Reset Offset pseudo-register *)

            WHILE N>0 DO \ (* Decode set of 4 input bytes. *)

              FOR cntr=1 TO 4
                GOSUB 1000
                outbyte(cntr)=C
              NEXT cntr

              C1=LAND(outbyte(1)*4,$ff)+INT(outbyte(2)/16)
              C2=LAND(outbyte(2)*16,$ff)+INT(outbyte(3)/4)
              C3=LAND(outbyte(3)*64,$ff)+outbyte(4)

              IF N>0 THEN \ (* Write up to 3 bytes dep. on No. decoded *)
                POKE obfpntr+obfoffst,C1
                obfoffst=obfoffst+1
              ENDIF
              IF N>1 THEN
                POKE obfpntr+obfoffst,C2
                obfoffst=obfoffst+1
              ENDIF
              IF N>2 THEN
                POKE obfpntr+obfoffst,C3
                obfoffst=obfoffst+1
              ENDIF

              N=N-3\ (* Dec. waiting *)

            ENDWHILE \ (* If more in this line, go back again. *)

            (* Finished processing line. *)

            PUT #stdout,obuf\ (* Send decoded stuff to output file. *)

            byteout=byteout+bdeclen\ (* Show status to user. *)
            (* GOTOXY 20,4 \ PRINT numl
            (* GOTOXY 20,5 \ PRINT byteout
          ENDIF \ (* 2nd EOF exit *)
        ENDIF \ (* 1st EOF exit *)
      ENDLOOP

      (* Close files if openned *)
      END

      (* ********************************************* *)

 1000 (* Subroutine to decode a single character *)
      IF LEN(inline)-sptr=0 THEN
        inline=inline+" "
      ENDIF
      cchar=MID$(inline,sptr,1)
      sptr=sptr+1
      C=LAND(ASC(cchar)-spc,mask)
      RETURN
-- 
Jim Omura, 2A King George's Drive, Toronto, (416) 652-3880
ihnp4!utzoo!lsuc!jimomura
Byte Information eXchange: jimomura