In     -
Out    UUDecode
Type   Util
Ver    1.01c

.Start
# REM OFF
   STMFD   (sp)!,{r0-r10,link}           ; Stack registers
   REM     "Reading variables %$1"
   ADR     r0,$`syntax                   ; string to use as compare
   ADR     r2,$`buffer                   ; buffer for result
   MOV     r3,#512                       ; size of buffer
   SWI     "XOS_ReadArgs"                ; do processing
   BVS     $err_system
   REM     "Args read"

   LDR     r1,$`buffer                   ; get pointer to input
   BL      openinput
   CMP     r8,#0
   BEQ     $err_filenotfound
   BL      findheader
   BEQ     $err_notuuencoded
   REM     "Starting get"
   BL      getfilename
   REM     "Ending get"
   LDR     r1,$`buffer+4                 ; get pointer to output
   BL      openoutput
   BL      decodefile
   BL      checkrotype
   BL      closeinput
   LDMFD   (sp)!,{r0-r10,pc}             ; Return from call

$`syntax
   EQUZA   "In/A,Out/A"
$`buffer
   RES     512

$err_filenotfound
   REMP    "File not found"
   LDMFD   (sp)!,{r0-r10,pc}             ; Return from call

$err_notuuencoded
   BL      closeinput
   REMP    "No uuencoded data to process"
   LDMFD   (sp)!,{r0-r10,pc}             ; Return from call

$err_badparams
   REMP    "Syntax: UUDecode <Input> <Output>"
   LDMFD   (sp)!,{r0-r10,pc}             ; Return from call

$err_system
   ADD     sp,sp,#4
   LDMFD   (sp)!,{r1-r10,pc}

.findheader
   STMFD   (sp)!,{r0-r5,link}            ; Stack registers
   REM     "Finding header"
   B       $checkbegin
$loop
   BL      getbyte
$inloop
   CMP     r0,#32
   BGE     $loop
   CMP     r0,#0
   LDMEQFD (sp)!,{r0-r5,pc}              ; Return from call if end of file
$checkbegin
   BL      getbyte
   CMP     r0,#ASC("b")
   BNE     $inloop
   BL      getbyte
   CMP     r0,#ASC("e")
   BNE     $inloop
   BL      getbyte
   CMP     r0,#ASC("g")
   BNE     $inloop
   BL      getbyte
   CMP     r0,#ASC("i")
   BNE     $inloop
   BL      getbyte
   CMP     r0,#ASC("n")
   BNE     $inloop
   CMP     r0,#0                         ; clear Z flag
   LDMFD   (sp)!,{r0-r5,pc}              ; Return from call

.getfilename
   STMFD   (sp)!,{r0-r5,link}            ; Stack registers
   BL      getbyte                       ; space
   BL      getbyte                       ; mode 1
   BL      getbyte                       ; mode 2
   BL      getbyte                       ; mode 3
   BL      getbyte                       ; space
   BL      getoutputname
   REM     "Filename got"
   LDMFD   (sp)!,{r0-r5,pc}              ; Return from call

.getoutputname
   STMFD   (sp)!,{r0-r5,link}            ; Stack registers
   ADR     r2,`outputname
$loop
   BL      getbyte
   STRB    r0,[r2],#1
;    REM     "Reading name = %r0"
   CMP     r0,#32
   BGE     $loop
   REM     "Exiting get output name"
   ADR     r0,`outputvar
   ADR     r1,`outputname
   SUB     r2,r2,r1                      ; length of string
   MOV     r3,#0
   MOV     r4,#0                         ; String type
   SWI     "OS_SetVarVal"
   REM     "Var set"
   LDMFD   (sp)!,{r0-r5,pc}              ; Return from call

.`outputname
   RES     256

.`outputvar
   EQUZA   "UUDecode$Name"

.decodefile
   STMFD   (sp)!,{r0-r5,link}            ; Stack registers
$fileloop
   BL      getvalue
   CMP     r0,#0
   BEQ     $exit
   MOV     r6,r0                         ; r6=bytes in line
;   REMP    "Bytes per line %r6"
   MOV     r5,#0                         ; r5=sub-total
   MOV     r3,#10                        ; current shift
$lineloop
;    REM     "Starting byte process, shift = %&3"
   BL      processbyte
   SUBS    r6,r6,#1
   BNE     $lineloop
   CMP     r5,#0
   BNE     $err_buffer
$findreturn
   BL      getbyte
   CMP     r0,#32
   BGE     $findreturn
   B       $fileloop

$err_buffer
   REMP    "Buffer not empty! value %&5, shift %&3"
$exit
   BL      closeoutput
   LDMFD   (sp)!,{r0-r5,pc}              ; Return from call

.processbyte
   STMFD   (sp)!,{r0-r2,link}            ; Stack registers
$nextchar
   BL      getvalue
;    REM     "Got value = %&0, shift = %&3"
   MOV     r0,r0,LSL r3                  ; r0=r0<<shift
   ORR     r5,r5,r0                      ; subtotal OR this
;    REM     "New subtot= %&5"
   ADD     r3,r3,#2                      ; r3+=2
   CMP     r3,#12
   MOVEQ   r3,#4
   BEQ     $nextchar
   MOV     r0,r5,LSR #8                  ; r0=top part of subtotal
   BL      putbyte
   BIC     r5,r5,#255<<8                 ; clear top part
   MOV     r5,r5,LSL #8                  ; shift subtotal left 8
   LDMFD   (sp)!,{r0-r2,pc}              ; Return from call

.getvalue
   STMFD   (sp)!,{r1-r5,link}            ; Stack registers
   BL      getbyte
;    REM     "Got byte %r0"
   CMP     r0,#ASC("`")                  ; ` = space in uuencode
   MOVEQ   r0,#ASC(" ")
   SUB     r0,r0,#ASC(" ")
   LDMFD   (sp)!,{r1-r5,pc}              ; Return from call

.checkrotype
   STMFD   (sp)!,{r0-r5,link}            ; Stack registers
   LDMFD   (sp)!,{r0-r5,pc}              ; Return from call


; ***** File input output routines

.openinput
; > r1=filename
; < r8=file handle
   STMFD   (sp)!,{r0-r5,link}
   REM     "Opening input"
   MOV     r0,#&40                  ; open file for input
   SWI     "XOS_Find"
   MOV     r8,r0                    ; r8 = input file handle
   LDMFD   (sp)!,{r0-r5,pc}

.closeinput
   STMFD   (sp)!,{r0-r5,link}
   REM     "Closing input"
   MOV     r1,r8
   MOV     r0,#&00                  ; close input file
   SWI     "XOS_Find"
   LDMFD   (sp)!,{r0-r5,pc}

.openoutput
; > r1=filename
; < r9=output file handle
   STMFD   (sp)!,{r0-r5,link}
   REM     "Opening output"
   MOV     r0,#&80                  ; open file for output
   SWI     "XOS_Find"
   MOV     r9,r0                    ; r9 = output file handle
   LDMFD   (sp)!,{r0-r5,pc}

.closeoutput
   STMFD   (sp)!,{r0-r5,link}
   REM     "Closing output"
   MOV     r1,r9
   MOV     r0,#&00                  ; close output file
   SWI     "XOS_Find"
   LDMFD   (sp)!,{r0-r5,pc}

.putbyte
; > r0=byte to put
   STMFD   (sp)!,{r0-r2,link}            ; Stack registers
   MOV     r1,r9
   SWI     "XOS_BPut"
   LDMFD   (sp)!,{r0-r2,pc}              ; Return from call

.getbyte
; < r0=byte got
   STMFD   (sp)!,{r1-r2,link}            ; Stack registers
   MOV     r1,r8
   SWI     "XOS_BGet"
   MOVVS   r0,#0
   LDMFD   (sp)!,{r1-r2,pc}              ; Return from call

#POST
P."Press any key":G=GET
VDU14
#RUN <CODE> Justin:.Patch.UUDecode.file_uue $.Out

