1 REM LETTER-PERFECT FILE COPY UTIL
2 REM DAN FLEYSHER, JUNE 1984
3 REM 
4 REM THIS BASIC PROGRAM ACCESSES
5 REM LETTER-PERFECT DOCUMENTS (v. 1)
6 REM & COPIES THEM TO AN ATARI DOS
7 REM SINGLE DENSITY DISK.
8 GOTO 100
9 REM 
10 REM **SUBR. TO WRITE OUT BUFFER CONTENTS**
20 PRINT :PRINT "REMOVE LETTER-PERFECT DISK,"
30 PRINT " INSERT ATARI DOS DISK,"
40 PRINT "  & HIT RETURN":TRAP 50:INPUT DUMMY$
50 TRAP 40000:OPEN #2,8+APPEND,0,FILE$
55 PRINT :PRINT "WRITING ";FILE$;"...":TRAP 9100
60 FOR I=BUF TO BUF+BUFOFF:TEMP=PEEK(I)
70 IF TEMP=27 THEN POP :GOTO 90:REM END OF FILE
80 PUT #2,TEMP:NEXT I
90 CLOSE #2:BUFOFF=0:APPEND=1:TRAP 40000:RETURN 
99 REM 
100 REM **INITIALIZATION & STARTUP**
110 DIM DUMMY$(1),FILE$(14),SLOADER$(40),DIR$(128):DIR$(128)=" "
120 I=0:APPEND=0:DIRSECT=0:DIROFF=0:INSECT=0:TEMP=0
125 STAT=0:ENUMSUBR=0:SLOADER=ADR(SLOADER$):DIR=ADR(DIR$)
130 BUFSIZ=FRE(0)-100
135 REM USE REST OF RAM FOR DATA BUFFER (LEAVE 100 BYTES SPARE)
140 DIM BUF$(BUFSIZ):BUF=ADR(BUF$):BUF$(BUFSIZ)=" "
150 PRINT "}     LETTER-PERFECT COPY UTILITY":PRINT :PRINT 
160 PRINT "BEFORE PROCEEDING, INSERT DISK"
170 PRINT " CONTAINING LETTER-PERFECT FILES.":PRINT :PRINT 
199 REM 
200 REM **INSTALL MACHINE LANG. SECTOR READER**
210 RESTORE 
220 FOR I=SLOADER TO SLOADER+39
230 READ TEMP:POKE I,TEMP:NEXT I
299 REM 
300 REM **SET UP FILE ACCESSING CONTROL**
310 PRINT "TO READ LETTER-PERFECT DIRECTORY"
320 PRINT " ENTER 'C' (CURRENT FILES ONLY)"
330 PRINT "    OR 'A' (ALL - CURRENT + DELETED"
340 PRINT " AND HIT RETURN."
350 PRINT "NOTE: ATTEMPT TO SALVAGE DELETED FILE"
360 PRINT " MAY NOT BE 100% SUCCESSFUL.":PRINT 
370 TRAP 320:INPUT DUMMY$:TRAP 40000
380 IF DUMMY$<>"C" AND DUMMY$<>"A" THEN 320
390 PRINT :IF DUMMY$="A" THEN PRINT "  # INDICATES FILE IS
DELETED":PRINT 
399 REM 
400 REM **ENUMERATE LETTER-PERFECT DIRECTORY FILES**
410 ENUMSUBR=500:REM CALL STEP 500 FOR EACH FILE
420 GOSUB 1000:REM ENUMERATE!
430 GOTO 600
499 REM 
500 REM **LIST FILES ON SCREEN, 3 TO A LINE**
510 IF I<10 THEN PRINT " ";
520 PRINT I;
530 IF STAT<>76 AND STAT<>108 THEN PRINT "#";:GOTO 550
540 PRINT " ";
550 PRINT DIR$(DIROFF+6,DIROFF+13);
560 IF (I/3)=INT(I/3) THEN PRINT :GOTO 580
570 PRINT " |";
580 RETURN 
599 REM 
600 REM **HAVE USER SELECT FILE NO. & FIND IT IN DIRECTORY**
610 IF (I/3)<>INT(I/3) THEN PRINT 
620 TRAP 620:PRINT "COPY WHICH FILE NO.";:INPUT TEMP:TRAP 40000
630 IF TEMP<1 OR TEMP>I THEN PRINT "PICK A NUMBER FROM ABOVE LIST":GOTO
620
640 ENUMSUBR=700
650 GOSUB 1000:REM STEP THRU DIRECTORY UNTIL FILE FOUND
660 STOP :REM ERROR - GOSUB 1000 SHOULD NOT RETURN HERE
670 GOTO 800
699 REM 
700 REM **FOR DESIRED FILE NO. (STORED IN TEMP)**
701 REM ** STORE 1ST INDEX SECT.NO. IN DIRSECT **
710 IF I<>TEMP THEN RETURN 
720 POP :REM DON'T RETURN FROM GOSUB ENUMSUBR
730 POP :REM DON'T RETURN FROM GOSUB 1000
740 FILE$="D:"
750 FILE$(3)=DIR$(DIROFF+6,DIROFF+13)
760 PRINT :PRINT :PRINT "READING ";FILE$(3);"..."
770 DIRSECT=PEEK(DIR+DIROFF+3)+256*PEEK(DIR+DIROFF+4)
799 REM 
800 REM **LOAD EACH SECTOR REFERENCED BY**
801 REM **INDEX SECTOR INTO RAM BUFFER  **
810 IF DIRSECT=0 OR DIRSECT>720 THEN 1200
820 STAT=USR(SLOADER,DIRSECT,DIR)
830 IF STAT<>1 THEN GOSUB 9000
835 DIRSECT=PEEK(DIR+1)+256*PEEK(DIR+2)
840 FOR DIROFF=8 TO 127 STEP 2
850 INSECT=PEEK(DIR+DIROFF)+256*PEEK(DIR+DIROFF+1)
860 IF INSECT=0 OR INSECT>720 THEN 950
870 STAT=USR(SLOADER,INSECT,BUF+BUFOFF)
880 IF STAT<>1 THEN GOSUB 9000
890 BUFOFF=BUFOFF+128:IF BUFOFF<BUFSIZ-128 THEN 950
900 GOSUB 10:REM BUFFER IS FULL - WRITE IT OUT
910 IF TEMP=27 THEN POP :GOTO 1200
920 PRINT :PRINT "REMOVE ATARI DOS DISK,"
930 PRINT " RE-INSERT LETTER-PERFECT DISK,"
940 PRINT "  & HIT RETURN":TRAP 945:INPUT DUMMY$
945 TRAP 40000:PRINT :PRINT "READING ";FILE$(3);"..."
950 NEXT DIROFF
960 GOTO 800
999 REM 
1000 REM **READ LETTER-PERFECT DIRECTORY:**
1001 REM ** FOR EACH FILE, CALL ENUMSUBR **
1005 I=0:REM INIT COUNTER FOR FILES ENUMERATED
1010 FOR DIRSECT=363 TO 369:REM $16B TO $171
1020 STAT=USR(SLOADER,DIRSECT,DIR)
1030 IF STAT<>1 THEN GOSUB 9000
1040 FOR DIROFF=0 TO 127 STEP 16
1050 STAT=PEEK(DIR+DIROFF):REM UNLOCKED/LOCKED/DELETED = $4C/$6C/$CC
1060 IF STAT=0 THEN 1100
1070 IF DUMMY$="C" AND STAT<>76 AND STAT<>108 THEN 1100
1080 I=I+1:REM FILE NO. TO BE ENUMERATED
1090 GOSUB ENUMSUBR:REM DO ENUMSUBR FOR THIS ENTRY
1100 NEXT DIROFF
1110 NEXT DIRSECT
1120 RETURN 
1199 REM 
1200 REM **CLEAN UP AND END**
1210 IF BUFOFF>0 THEN GOSUB 10
1220 PRINT :PRINT :PRINT "FILE STORED ON ATARI DOS DISK"
1230 END 
1999 REM 
2000 REM **MACHINE LANGUAGE UTILITY TO LOAD   **
2001 REM **SINGLE-DENSITY DISK SECTOR INTO RAM**
2002 REM ** STAT=USR(SLOADER,SECTOR NO,BUF ADR)**
2010 DATA 104,104,141,11,3,104,141,10,3
2020 DATA 104,141,5,3,104,141,4,3
2030 DATA 169,82,141,2,3
2040 DATA 169,1,141,1,3
2050 DATA 32,83,228
2060 DATA 173,3,3,133,212,169,0,133,213,96
8999 REM 
9000 REM **SUBR. TO PRINT DISK SECTOR READ ERROR**
9010 PRINT "DISK SECTOR READ ERROR ";STAT
9020 PRINT " TYPE 'CONT' TO FORGE ON"
9030 STOP 
9040 RETURN 
9099 REM 
9100 REM **ERROR WRITING TO DOS DISK**
9110 PRINT "ERROR WRITING TO DOS DISK"
9120 STOP 
