home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.uni-stuttgart.de/pub/systems/acorn/
/
Acorn.tar
/
Acorn
/
6502
/
beginner
/
uudecode.bas
< prev
next >
Wrap
BASIC Source File
|
1992-05-25
|
9KB
|
307 lines
10REM DecoSrc - Source for UUDecod
20REM Create the specified file, decoding as you go - used with UUEncode
30REM
40REM Written by Mark Horton, ported by Gerben Vos - Public Domain
50REM Machine code version for BBC Microcomputer, Acorn Electron and Master
60REM Creates a file which can be *Run, with load & exec addresses of &880
70REM
80REM Usage: *UUDecode <Inputfile>
90REM
100REM Notes/bugs:
110REM + occupies the printer, speech and serial buffer and envelope storage
120REM + uses BASIC string buffer at &600
130REM + doesn't complain when newlines are missing in the translation table
140REM + the code is sometimes too overloaded, cryptic and brittle
150
160osfind=&FFCE:osbput=&FFD4:osbget=&FFD7:osargs=&FFDA:osasci=&FFE3
170in=&70:out=&71:num=&72:bytesleft=&73:temp=&74
180nfil=&75:seq=&76:useseq=&77:quad=&78:text=&7C
190
200name =&100:REM output file name buffer
210table=&600:REM character table, 256 bytes
220
230p%=&880
240FORQ=0TO3STEP2
250P%=p%
260[OPT Q
270
280.decode
290
300\ get address of command args
310 LDA #1:LDX #text:LDY #0:STY nfil:STY useseq:JSR osargs
320
330\ set up default character table
340 JSR cleartable
350 LDY #64
360.loop
370 TYA:AND #63:STA table+32,Y:DEY:BPL loop
380
390\ skip leading spaces; Y=255 after loop
400.skipspaces2
410 INY:LDA (text),Y:CMP #32:BEQ skipspaces2
420 CMP #13:BNE no_usage
430 BRK
440 EQUB &71 \hopefully unused error number
450 EQUS "Usage: UUDecode <Inputfile>"
460
470.inexistsnot
480 BRK
490 EQUB &D6
500 EQUS "Not found"
510 BRK
520
530\ open given file for input
540.no_usage
550 TYA:CLC:ADC text:TAX:LDA text+1:ADC #0:TAY \address of name now in YX
560 LDA #&40:JSR osfind:STA in
570 TAX:BEQ inexistsnot \TAX influences Z(ero) flag
580
590\ scan file for occurence of "begin" or "table"
600.searchbeginline
610 LDX #0 \for checkbeginline and checktableline
620 JSR byte_in_or_endoffile
630 CMP begintext:BEQ checkbeginline
640 CMP tabletext:BEQ checktableline
650.searchnewline \this is garbage, skip the line
660 JSR is_eol:BEQ searchbeginline \new line found, check again
670 JSR byte_in_or_endoffile:BCC searchnewline\JMP
680
690\ look for "begin "
700.checkbeginline
710 JSR byte_in_or_endoffile:INX:CMP begintext,X:BNE searchnewline
720 CPX #5:BNE checkbeginline
730 BEQ beginfound\JMP
740
750\ look for "table"
760.checktableline
770 JSR byte_in_or_endoffile:INX:CMP tabletext,X:BNE searchnewline
780 CPX #4:BNE checktableline
790
800\ read translation table
810.tablefound
820 JSR cleartable
830 LDA #0:STA temp
840.loop
850 JSR byte_in_or_endoffile:JSR is_eol:BEQ table_newline
860 TAX:LDA table,X:BPL badtable \entry is already in use
870 LDA temp:STA table,X
880 INC temp:BPL loop \if char count>127, fall thru to error routine
890
900\ if newline, char count must be 0, 32 or 64
910.table_newline
920 LDA temp:TAY:AND #31:BNE badtable
930 CPY #64:BCC loop \not at end of table
940 BEQ searchbeginline \table is finished, go looking for begin lines again
950\char count>64, so table was too big; fall thru to error message
960
970.badtable
980 JSR close_in
990 BRK
1000 EQUB &77
1010 EQUS "Bad "
1020.tabletext
1030 EQUS "table"
1040 BRK
1050
1060\ skip file mode
1070.beginfound
1080 JSR byte_in_or_endoffile:CMP #32:BNE beginfound
1090
1100\ get output file name and store it temporarily
1110 LDX #255
1120.getname
1130 JSR byte_in_or_endoffile:INX:STA name,X
1140 JSR is_eol:BNE getname
1150
1160\ delimit file name with cr
1170.endname
1180 LDA #13:STA name,X \delimit file name with cr
1190
1200\ print message
1210 LDY #11
1220.printmess
1230 LDA messtext-1,Y:JSR osasci
1240 DEY:BNE printmess
1250
1260\ print output file name; Y=0 at start
1270.printname \Y=0 at start
1280 LDA name,Y:INY:JSR osasci
1290 CMP #13:BNE printname
1300
1310\ open for input to check for existence
1320 LDX #name MOD256:LDY #name DIV256
1330 LDA #&40:JSR osfind:STA out
1340 CMP #0:BEQ outexistsnot
1350 JSR close_out_in \output file exists, won't overwrite
1360 BRK
1370 EQUB &C4
1380 EQUS "Already exists"
1390 BRK
1400
1410\ prepare for the real work
1420.outexistsnot
1430 LDA #ASC"z":STA seq
1440 INC nfil \note that decoding has been attempted
1450 LDA #&80:JSR osfind:STA out \open for output, X and Y are still OK
1460
1470\ main decoding loop
1480.nextline
1490 JSR skipcrlfs \A=first char now
1500 JSR dec_byte:STA num:STA bytesleft
1510
1520\ read a group of four chars
1530.nextquad
1540 DEC bytesleft:BMI linedecoded
1550 LDX #3
1560.readquad
1570 JSR dec_in:STA quad,X
1580 DEX:BPL readquad
1590
1600\ now decode the group of four bytes into three
1610 LDA quad+3:ASL A:ASL A:STA temp
1620 LDA quad+2:LSR A:LSR A:LSR A:LSR A:ORA temp:JSR byte_out
1630 DEC bytesleft:BMI linedecoded
1640 LDA quad+2:ASL A:ASL A:ASL A:ASL A:STA temp
1650 LDA quad+1:LSR A:LSR A:ORA temp:JSR byte_out
1660 DEC bytesleft:BMI linedecoded
1670 LDA quad+1:ASL A:ASL A:ASL A:ASL A:ASL A:ASL A
1680 ORA quad:JSR byte_out
1690 JMP nextquad
1700
1710\ check if there is a sequence letter
1720.linedecoded
1730 JSR byte_in_or_fileerror:JSR is_eol:BNE checkseq
1740 LDA useseq:BEQ seq_ok \check if sequence letter has been used before
1750\ sequence letter omitted, fall thru to badseq since previous seq<>seq
1760
1770\ check if sequence letter is right
1780.checkseq
1790 STA useseq \note that sequence letters are in use by making useseq<>0
1800 CMP seq:BNE badseq
1810
1820\ skip rest of line
1830.skipgarbage
1840 JSR byte_in_or_fileerror:JSR is_eol:BNE skipgarbage
1850
1860\ finished one line
1870.seq_ok
1880 LDA seq:DEC seq:CMP #ASC"a":BNE noseqwrap:LDA #ASC"z":STA seq
1890.noseqwrap
1900 LDA num:BNE nextline \num<>0, so more lines follow
1910
1920\ ready with output file, check for end line
1930.fileend \ready with output file, check for end line
1940 JSR skipcrlfs
1950 LDX #253 \X becomes 0 when 3 characters further
1960.checkend
1970 CMP endtext-253,X:BNE noend
1980 JSR byte_in:BCS noend
1990 INX:BNE checkend
2000 JSR is_eol:BNE noend
2010 JSR close_out
2020 JMP searchbeginline
2030
2040.badseq
2050 JSR close_out_in
2060 BRK
2070 EQUB &75
2080 EQUS "Sequence"
2090 BRK
2100
2110.noend
2120 JSR close_out_in
2130 BRK
2140 EQUB &74
2150 EQUS "No "
2160.endtext
2170 EQUS "end"
2180 EQUS " line"
2190 BRK
2200
2210\ miscellaneous routines
2220
2230\ close input and/or output files
2240.close_out_in
2250 JSR close_out
2260.close_in
2270 LDA #0:LDY in:JMP osfind
2280
2290.close_out
2300 LDA #0:LDY out:JMP osfind
2310
2320\ clear the translation table
2330.cleartable
2340 LDA #255:LDY #0
2350.loop
2360 STA table,Y:INY:BNE loop
2370\ RTS is not needed, since next routine is harmless
2380
2390\ check if A is a return or linefeed
2400.is_eol
2410 CMP #13:BEQ rts
2420 CMP #10
2430.rts
2440 RTS
2450
2460\ write A to output file
2470.byte_out
2480 LDY out:JMP osbput
2490
2500\ read from input file into A
2510.byte_in
2520 LDY in:JMP osbget
2530
2540\ read a byte and decode it
2550.dec_in
2560 JSR byte_in_or_fileerror
2570
2580\ decode A
2590.dec_byte
2600 TAY:LDA table,Y:BPL rts
2610 JSR close_out_in
2620 BRK
2630 EQUB &76
2640 EQUS "Bad char"
2650 BRK
2660
2670\ read a byte; at EOF, only close input file, then check if any files have
2680\ been decoded; if so, return
2690\ don't call this routine from within another subroutine!!
2700.byte_in_or_endoffile
2710 JSR byte_in:BCC rts
2720 JSR close_in
2730 PLA:PLA \remove return address
2740 LDA nfil:BNE rts
2750 BRK
2760 EQUB &72
2770 EQUS "No "
2780.begintext
2790 EQUS "begin "
2800 EQUS "line"
2810 BRK
2820
2830\ read a byte; at EOF, complain and close both output and input files
2840.byte_in_or_fileerror
2850 JSR byte_in:BCC rts2
2860 JSR close_out_in
2870 BRK
2880 EQUB &73
2890 EQUS "Premature EOF"
2900 BRK
2910
2920\ skip extra cr's and lf's in e.g. MesSy-LOSS text file format
2930.skipcrlfs
2940 JSR byte_in_or_fileerror:JSR is_eol:BEQ skipcrlfs
2950\ return with A=first character of line
2960.rts2
2970 RTS
2980
2990\ text "UUDecoding " has been reversed for efficiency
3000.messtext
3010 EQUS " gnidoceDUU"
3020
3030]NEXT
3040a$="save UUDecod "+STR$~p%+" "+STR$~P%
3050PRINT"*"a$:OSCLIa$
3060END