home *** CD-ROM | disk | FTP | other *** search
/ ftp.uni-stuttgart.de/pub/systems/acorn/ / Acorn.tar / Acorn / 6502 / beginner / uudecode.bas < prev    next >
BASIC Source File  |  1992-05-25  |  9KB  |  307 lines

  1.    10REM DecoSrc - Source for UUDecod
  2.    20REM Create the specified file, decoding as you go - used with UUEncode
  3.    30REM
  4.    40REM Written by Mark Horton, ported by Gerben Vos - Public Domain
  5.    50REM Machine code version for BBC Microcomputer, Acorn Electron and Master
  6.    60REM Creates a file which can be *Run, with load & exec addresses of &880
  7.    70REM
  8.    80REM Usage: *UUDecode <Inputfile>
  9.    90REM
  10.   100REM Notes/bugs:
  11.   110REM + occupies the printer, speech and serial buffer and envelope storage
  12.   120REM + uses BASIC string buffer at &600
  13.   130REM + doesn't complain when newlines are missing in the translation table
  14.   140REM + the code is sometimes too overloaded, cryptic and brittle
  15.   150 
  16.   160osfind=&FFCE:osbput=&FFD4:osbget=&FFD7:osargs=&FFDA:osasci=&FFE3
  17.   170in=&70:out=&71:num=&72:bytesleft=&73:temp=&74
  18.   180nfil=&75:seq=&76:useseq=&77:quad=&78:text=&7C
  19.   190 
  20.   200name =&100:REM output file name buffer
  21.   210table=&600:REM character table, 256 bytes
  22.   220 
  23.   230p%=&880
  24.   240FORQ=0TO3STEP2
  25.   250P%=p%
  26.   260[OPT Q
  27.   270 
  28.   280.decode
  29.   290 
  30.   300\ get address of command args
  31.   310 LDA #1:LDX #text:LDY #0:STY nfil:STY useseq:JSR osargs
  32.   320 
  33.   330\ set up default character table
  34.   340 JSR cleartable
  35.   350 LDY #64
  36.   360.loop
  37.   370 TYA:AND #63:STA table+32,Y:DEY:BPL loop
  38.   380 
  39.   390\ skip leading spaces; Y=255 after loop
  40.   400.skipspaces2
  41.   410 INY:LDA (text),Y:CMP #32:BEQ skipspaces2
  42.   420 CMP #13:BNE no_usage
  43.   430 BRK
  44.   440 EQUB &71 \hopefully unused error number
  45.   450 EQUS "Usage: UUDecode <Inputfile>"
  46.   460 
  47.   470.inexistsnot
  48.   480 BRK
  49.   490 EQUB &D6
  50.   500 EQUS "Not found"
  51.   510 BRK
  52.   520 
  53.   530\ open given file for input
  54.   540.no_usage
  55.   550 TYA:CLC:ADC text:TAX:LDA text+1:ADC #0:TAY \address of name now in YX
  56.   560 LDA #&40:JSR osfind:STA in
  57.   570 TAX:BEQ inexistsnot \TAX influences Z(ero) flag
  58.   580 
  59.   590\ scan file for occurence of "begin" or "table"
  60.   600.searchbeginline
  61.   610 LDX #0 \for checkbeginline and checktableline
  62.   620 JSR byte_in_or_endoffile
  63.   630 CMP begintext:BEQ checkbeginline
  64.   640 CMP tabletext:BEQ checktableline
  65.   650.searchnewline \this is garbage, skip the line
  66.   660 JSR is_eol:BEQ searchbeginline \new line found, check again
  67.   670 JSR byte_in_or_endoffile:BCC searchnewline\JMP
  68.   680 
  69.   690\ look for "begin "
  70.   700.checkbeginline
  71.   710 JSR byte_in_or_endoffile:INX:CMP begintext,X:BNE searchnewline
  72.   720 CPX #5:BNE checkbeginline
  73.   730 BEQ beginfound\JMP
  74.   740 
  75.   750\ look for "table"
  76.   760.checktableline
  77.   770 JSR byte_in_or_endoffile:INX:CMP tabletext,X:BNE searchnewline
  78.   780 CPX #4:BNE checktableline
  79.   790 
  80.   800\ read translation table
  81.   810.tablefound
  82.   820 JSR cleartable
  83.   830 LDA #0:STA temp
  84.   840.loop
  85.   850 JSR byte_in_or_endoffile:JSR is_eol:BEQ table_newline
  86.   860 TAX:LDA table,X:BPL badtable \entry is already in use
  87.   870 LDA temp:STA table,X
  88.   880 INC temp:BPL loop \if char count>127, fall thru to error routine
  89.   890 
  90.   900\ if newline, char count must be 0, 32 or 64
  91.   910.table_newline
  92.   920 LDA temp:TAY:AND #31:BNE badtable
  93.   930 CPY #64:BCC loop \not at end of table
  94.   940 BEQ searchbeginline \table is finished, go looking for begin lines again
  95.   950\char count>64, so table was too big; fall thru to error message
  96.   960 
  97.   970.badtable
  98.   980 JSR close_in
  99.   990 BRK
  100.  1000 EQUB &77
  101.  1010 EQUS "Bad "
  102.  1020.tabletext
  103.  1030 EQUS "table"
  104.  1040 BRK
  105.  1050 
  106.  1060\ skip file mode
  107.  1070.beginfound
  108.  1080 JSR byte_in_or_endoffile:CMP #32:BNE beginfound
  109.  1090 
  110.  1100\ get output file name and store it temporarily
  111.  1110 LDX #255
  112.  1120.getname
  113.  1130 JSR byte_in_or_endoffile:INX:STA name,X
  114.  1140 JSR is_eol:BNE getname
  115.  1150 
  116.  1160\ delimit file name with cr
  117.  1170.endname
  118.  1180 LDA #13:STA name,X \delimit file name with cr
  119.  1190 
  120.  1200\ print message
  121.  1210 LDY #11
  122.  1220.printmess
  123.  1230 LDA messtext-1,Y:JSR osasci
  124.  1240 DEY:BNE printmess
  125.  1250 
  126.  1260\ print output file name; Y=0 at start
  127.  1270.printname \Y=0 at start
  128.  1280 LDA name,Y:INY:JSR osasci
  129.  1290 CMP #13:BNE printname
  130.  1300 
  131.  1310\ open for input to check for existence
  132.  1320 LDX #name MOD256:LDY #name DIV256
  133.  1330 LDA #&40:JSR osfind:STA out
  134.  1340 CMP #0:BEQ outexistsnot
  135.  1350 JSR close_out_in \output file exists, won't overwrite
  136.  1360 BRK
  137.  1370 EQUB &C4
  138.  1380 EQUS "Already exists"
  139.  1390 BRK
  140.  1400 
  141.  1410\ prepare for the real work
  142.  1420.outexistsnot
  143.  1430 LDA #ASC"z":STA seq
  144.  1440 INC nfil \note that decoding has been attempted
  145.  1450 LDA #&80:JSR osfind:STA out \open for output, X and Y are still OK
  146.  1460 
  147.  1470\ main decoding loop
  148.  1480.nextline
  149.  1490 JSR skipcrlfs \A=first char now
  150.  1500 JSR dec_byte:STA num:STA bytesleft
  151.  1510 
  152.  1520\ read a group of four chars
  153.  1530.nextquad
  154.  1540 DEC bytesleft:BMI linedecoded
  155.  1550 LDX #3
  156.  1560.readquad
  157.  1570 JSR dec_in:STA quad,X
  158.  1580 DEX:BPL readquad
  159.  1590 
  160.  1600\ now decode the group of four bytes into three
  161.  1610 LDA quad+3:ASL A:ASL A:STA temp
  162.  1620 LDA quad+2:LSR A:LSR A:LSR A:LSR A:ORA temp:JSR byte_out
  163.  1630 DEC bytesleft:BMI linedecoded
  164.  1640 LDA quad+2:ASL A:ASL A:ASL A:ASL A:STA temp
  165.  1650 LDA quad+1:LSR A:LSR A:ORA temp:JSR byte_out
  166.  1660 DEC bytesleft:BMI linedecoded
  167.  1670 LDA quad+1:ASL A:ASL A:ASL A:ASL A:ASL A:ASL A
  168.  1680 ORA quad:JSR byte_out
  169.  1690 JMP nextquad
  170.  1700 
  171.  1710\ check if there is a sequence letter
  172.  1720.linedecoded
  173.  1730 JSR byte_in_or_fileerror:JSR is_eol:BNE checkseq
  174.  1740 LDA useseq:BEQ seq_ok \check if sequence letter has been used before
  175.  1750\ sequence letter omitted, fall thru to badseq since previous seq<>seq
  176.  1760 
  177.  1770\ check if sequence letter is right
  178.  1780.checkseq
  179.  1790 STA useseq \note that sequence letters are in use by making useseq<>0
  180.  1800 CMP seq:BNE badseq
  181.  1810 
  182.  1820\ skip rest of line
  183.  1830.skipgarbage
  184.  1840 JSR byte_in_or_fileerror:JSR is_eol:BNE skipgarbage
  185.  1850 
  186.  1860\ finished one line
  187.  1870.seq_ok
  188.  1880 LDA seq:DEC seq:CMP #ASC"a":BNE noseqwrap:LDA #ASC"z":STA seq
  189.  1890.noseqwrap
  190.  1900 LDA num:BNE nextline \num<>0, so more lines follow
  191.  1910 
  192.  1920\ ready with output file, check for end line
  193.  1930.fileend \ready with output file, check for end line
  194.  1940 JSR skipcrlfs
  195.  1950 LDX #253 \X becomes 0 when 3 characters further
  196.  1960.checkend
  197.  1970 CMP endtext-253,X:BNE noend
  198.  1980 JSR byte_in:BCS noend
  199.  1990 INX:BNE checkend
  200.  2000 JSR is_eol:BNE noend
  201.  2010 JSR close_out
  202.  2020 JMP searchbeginline
  203.  2030 
  204.  2040.badseq
  205.  2050 JSR close_out_in
  206.  2060 BRK
  207.  2070 EQUB &75
  208.  2080 EQUS "Sequence"
  209.  2090 BRK
  210.  2100 
  211.  2110.noend
  212.  2120 JSR close_out_in
  213.  2130 BRK
  214.  2140 EQUB &74
  215.  2150 EQUS "No "
  216.  2160.endtext
  217.  2170 EQUS "end"
  218.  2180 EQUS " line"
  219.  2190 BRK
  220.  2200 
  221.  2210\ miscellaneous routines
  222.  2220 
  223.  2230\ close input and/or output files
  224.  2240.close_out_in
  225.  2250 JSR close_out
  226.  2260.close_in
  227.  2270 LDA #0:LDY in:JMP osfind
  228.  2280 
  229.  2290.close_out
  230.  2300 LDA #0:LDY out:JMP osfind
  231.  2310 
  232.  2320\ clear the translation table
  233.  2330.cleartable
  234.  2340 LDA #255:LDY #0
  235.  2350.loop
  236.  2360 STA table,Y:INY:BNE loop
  237.  2370\ RTS is not needed, since next routine is harmless
  238.  2380 
  239.  2390\ check if A is a return or linefeed
  240.  2400.is_eol
  241.  2410 CMP #13:BEQ rts
  242.  2420 CMP #10
  243.  2430.rts
  244.  2440 RTS
  245.  2450 
  246.  2460\ write A to output file
  247.  2470.byte_out
  248.  2480 LDY out:JMP osbput
  249.  2490 
  250.  2500\ read from input file into A
  251.  2510.byte_in
  252.  2520 LDY in:JMP osbget
  253.  2530 
  254.  2540\ read a byte and decode it
  255.  2550.dec_in
  256.  2560 JSR byte_in_or_fileerror
  257.  2570 
  258.  2580\ decode A
  259.  2590.dec_byte
  260.  2600 TAY:LDA table,Y:BPL rts
  261.  2610 JSR close_out_in
  262.  2620 BRK
  263.  2630 EQUB &76
  264.  2640 EQUS "Bad char"
  265.  2650 BRK
  266.  2660 
  267.  2670\ read a byte; at EOF, only close input file, then check if any files have
  268.  2680\ been decoded; if so, return
  269.  2690\ don't call this routine from within another subroutine!!
  270.  2700.byte_in_or_endoffile
  271.  2710 JSR byte_in:BCC rts
  272.  2720 JSR close_in
  273.  2730 PLA:PLA \remove return address
  274.  2740 LDA nfil:BNE rts
  275.  2750 BRK
  276.  2760 EQUB &72
  277.  2770 EQUS "No "
  278.  2780.begintext
  279.  2790 EQUS "begin "
  280.  2800 EQUS "line"
  281.  2810 BRK
  282.  2820 
  283.  2830\ read a byte; at EOF, complain and close both output and input files
  284.  2840.byte_in_or_fileerror
  285.  2850 JSR byte_in:BCC rts2
  286.  2860 JSR close_out_in
  287.  2870 BRK
  288.  2880 EQUB &73
  289.  2890 EQUS "Premature EOF"
  290.  2900 BRK
  291.  2910 
  292.  2920\ skip extra cr's and lf's in e.g. MesSy-LOSS text file format
  293.  2930.skipcrlfs
  294.  2940 JSR byte_in_or_fileerror:JSR is_eol:BEQ skipcrlfs
  295.  2950\ return with A=first character of line
  296.  2960.rts2
  297.  2970 RTS
  298.  2980 
  299.  2990\ text "UUDecoding " has been reversed for efficiency
  300.  3000.messtext
  301.  3010 EQUS " gnidoceDUU"
  302.  3020 
  303.  3030]NEXT
  304.  3040a$="save UUDecod "+STR$~p%+" "+STR$~P%
  305.  3050PRINT"*"a$:OSCLIa$
  306.  3060END
  307.