100 ; PROGRAM NAME IS 'DSTOSS' 24 JUN 87
110 ;
120 X=FRE(0):GOSUB LOADCODE
130 DIM SIZE$2,FILE$32,A$1,F$1,ADR$4,CAT$[125]32,FST$2,ATT$1,FST$2
140 CLS:DR 1:VTAB 2:MEMLEFT=X-131072:DISKSPACE=404480
150 PRINT "             DOUBLE SIDED TO SINGLE SIDED CONVERSION UTILITY"
160 PRINT:PRINT " THIS PROGRAM COPIES FILES FROM A DOUBLE SIDED-DISK TO A SINGLE-SIDED DISK."
170 PRINT:PRINT " ALL DATA ON THE DESTINATION DISK WILL BE ERASED!"
180 PRINT:PRINT " THE FILES WILL BE COPIED IN THE ORDER THAT THEY APPEAR IN THE CATALOG."
190 PRINT " FILES THAT ARE scratched WILL not BE copied."
200 VTAB 15:INPUT "INPUT THE SOURCE DRIVE # (1 OR 2) ",S_DR%
210 IF S_DR%<>1 THEN IF S_DR%<>2 GOTO 200
220 INPUT "INPUT THE DESTINATION DRIVE # (1 OR 2) ",D_DR%
230 IF D_DR%<>1 THEN IF D_DR%<>2 GOTO 220
240 PRINT " DO YOU WANT TO FORMAT THE DESTINATION DISK ";:EDIT F$
250 IF F$<>"Y" THEN IF F$<>"N" THEN IF F$<>"y" THEN IF F$<>"Y" GOTO 240
260 PRINT " PRESS RETURN WHEN READY:";:EDIT A$:VTAB 18:HTAB 25:PRINT " CHECKING
DISK TYPE."
270 DR S_DR%:CALL $00D80C:PEEKW $00D81C,S_SIDE%
280 IF S_SIDE%=2 GOTO 320
290 PRINT " THE DISK IN DRIVE ";S_DR%;" IS NOT DOUBLE-SIDED."
300 PRINT " PROGRAM ABORTED.":DR 1:STOP
310 ;
320 VTAB 18:HTAB 25:PEEKW $014008,SYS%:IF SYS%=9 THEN PRINT " THE DISK IS A DATA DISK.":D_NXST%=10:BUFF=135680:GOTO 350
330 PRINT " THE DISK IS A SYSTEM DISK.  READING THE SYSTEM TRACKS."
340 D_NXST%=75:BUFF=202240:MEMLEFT=MEMLEFT-65*1024:DISKSPACE=DISKSPACE-65*1024
350 DR%=S_DR%:NEW%=1:MEMLEFT=MEMLEFT-4608
360 DATABFR=131072:SECTOR%=0
370 CNT%=SYS%:GOSUB READDBASIC:POKE $020025,HEX(01):POKE $0201FF,HEX(76)
380 PEEKW $014006,NUMFILE%:DATABFR=BUFF:CLRLINE 18:CLRLINE 19:CLRLINE 20
390 VTAB 18:PRINT " READING FILES .... "
400 PRINT " FILE NAME       DISK SPACE LEFT       MEMORY LEFT  "
410 BUFFER1=DATABFR+2:CAT=81984:FOR I%=0 TO NUMFILE%-1
420 ADR=CAT+FLT(I%)*32:PEEK ADR,FILE$:SIZE$=MID$(FILE$,23,2)
430 POKEW $00FFF0,SIZE$:PEEKW $00FFF0,SIZE%
440 ATT$=MID$(FILE$,2,1):POKE $00FFF0,ATT$:PEEK $00FFF0,ATT%
450 IF ATT%>7 THEN ATT%=ATT%-8:GOTO 450
460 IF ATT%>3 THEN NEXT I%:GOTO WRITE_DISK
470 IF MEMLEFT<FLT(SIZE%)*1024 GOTO WRITE_DISK
480 IF DISKSPACE<FLT(SIZE%)*1024 GOTO WRITE_DISK
490 FST$=MID$(FILE$,21,2):POKEW $00FFF0,FST$:PEEKW $00FFF0,FSTSECT%
500 VTAB 20:PRINT " ";MID$(FILE$,4,17):GOSUB READ_FILE
510 NEXT I%
520 ;
530  "WRITE_DISK"
540 POKE $020240,CAT$[]:D_NXST%=D_NXST%-1
550 POKE $020200,HEX(0194):POKEW $020202,D_NXST%:POKEW $020204,HEX(007E)
560 POKEW $020206,FILE%:POKEW $020208,SYS%
570 IF S_DR%<>D_DR% GOTO 600
580 PRINT " REMOVE THE SOURCE DISK AND INSERT THE DESTINATION DISK."
590 PRINT " PRESS RETURN WHEN READY.";:EDIT A$
600 IF F$<>"Y" THEN IF F$<>"y" GOTO 640
610 CLRLINE 21:VTAB 22:CLRLINE:PRINT " FORMATTING DESTINAION DISK.  THIS WILL TAKE ABOUT 32 SECONDS."
620 DR D_DR%:POKEW $00D81C,HEX(0001):CALL $00D7F8
630 ;
640 POKE DRIVE,D_DR%:IF F$<>"N" THEN IF F$<>"n" GOTO 700
650 NEW%=1:CALL INITDBASIC
660 PEEKW SIDES,D_SIDE%:IF D_SIDE%=1 GOTO 700
670 PRINT " THE DESTINATION DISK IS NOT SINGLE-SIDED!"
680 PRINT " PROGRAM ABORTED!":DR 1:STOP
690 ;
700 DATABFR=131072:SECTOR%=0:CNT%=D_NXST%:NEW%=1:D_NXST=FLT(D_NXST%)/5
710 VTAB 22:CLRLINE:PRINT " WRITING DATA TO DISK.  THIS WILL TAKE ABOUT";D_NXST*.24;"SECONDS."
720 DR%=D_DR%:GOSUB WRITEDBASIC
730 PRINT " PROGRAM IS DONE":DR 1:END
740 ;
750  "READ_FILE":CNT%=1:NEW%=0
760 SECTOR%=FSTSECT%:GOSUB READDBASIC
770 MEMLEFT=MEMLEFT-1024:DISKSPACE=DISKSPACE-1024
780 T%=D_NXST%-1:POKEW $00FFF0,T%:PEEKW $00FFF0,FST$
790 CAT$[FILE%]=FILE$:MID$(CAT$[FILE%],21,2)=FST$:FILE%=FILE%+1
800 PEEKW BUFFER1,NXST%:POKEW BUFFER1,D_NXST%
810 IF NXST%=0 THEN POKEW BUFFER1,HEX(0000)
820 DATABFR=DATABFR+1024:BUFFER1=DATABFR+2:D_NXST%=D_NXST%+1
830 IF NXST%=0 GOTO END_OF_FILE
840 SECTOR%=NXST%:VTAB 20:HTAB 20:PRINT DISKSPACE,MEMLEFT
850 GOSUB READDBASIC:MEMLEFT=MEMLEFT-1024:DISKSPACE=DISKSPACE-1024:GOTO 800
860  "END_OF_FILE"
870 VTAB 20:HTAB 20:PRINT DISKSPACE,MEMLEFT
880 RETURN
890 ; PROGRAM NAME IS 'DISKPRIM' 19 JUN 87
900 ;
910 ; ********* LOAD THE UTILITY CODE & SET VARIABLES *********
920 ;
930  "LOADCODE"
940 HIMEM $020000:; WE CAN USE $40000 TO TOP OF MEM FOR SECTOR STORAGE
950 DIM CODE[300],ADR$4:; SAVES 2400 BYTES FOR THE CODE
960 TXLOC CODE[],ADR:; ADDRESS = START OF THE CODE AREA
970 BLOAD DPRIMO,ADR:; LOADS THE UTILITY CODE
980 ASSIGN ADR0=$1030 C000 0000 0000
990 ;
1000 ; ** CALL LOCATIONS **
1010 ;
1020 INITDBASIC=ADR:; CALL INITDBASIC DETERMINES THE TYPE OF DBASIC DISK
1030 RDDBASIC=ADR+4:; CALL RDDBASIC READS DBASIC SECTORS
1040 WRDBASIC=ADR+8:; CALL WRDBASIC WRITES DBASIC SECTORS
1050 INITTOS=ADR+12:; CALL INITTOS DETERMINES THE TYPE OF TOS DISK
1060 RDTOS=ADR+16:; CALL RDTOS READS TOS SECTORS
1070 WRTOS=ADR+20:; CALL WRTOS WRITES TOS SECTORS
1080 ;
1090 ; ** LOCATIONS TO SET UP BEFORE A CALL **
1100 ;
1110 BUFFER=ADR+24:; (LONG WORD VALUE) ADDRESS WHERE DATA TRANSFER IS TO OCCUR
1120 SECTOR=ADR+28:; (WORD VALUE) ABSOLUTE SECTOR # TO START READING OR WRITING
1130 COUNT=ADR+30:; (WORD VALUE) NUMBER OF SECTORS TO READ OR WRITE
1140 DRIVE=ADR+32:; (BYTE VALUE) NUMBER OF DRIVE TO SELECT
1150 ;
1160 ; ** LOCATION TO PEEK AT BUT DON'T TOUCH **
1170 ;
1180 SIDES=ADR+34:; (WORD VALUE) # OF SIDES OF THE DISK LAST INIT'ED
1190 RETURN
1200 ;
1210 ;
1220 ; ********* READ DBASIC SECTORS *********
1230 ;
1240 ;
1250 ; "INPUT PARAMETERS:    VARIABLE NAME      DESCRIPTION
1260 ; "                     DATABFR            ADDRESS OF MEMORY TO READ TO
1270 ; "                     SECTOR%            STARTING ABSOLUTE SECTOR #
1280 ; "                     CNT%               # OF SECTORS TO READ
1290 ; "                     DR%                # OF DRIVE TO READ TO
1300 ; "                     NEW%               IF 1 THEN INIT DISK ELSE NOT
1310 ;
1320  "READDBASIC"
1330 TEMP=ADR0+DATABFR:PEEK $0011C6,ADR$
1340 POKE BUFFER,ADR$
1350 POKEW SECTOR,SECTOR%
1360 POKEW COUNT,CNT%
1370 PEEK DRIVE,PREV_DR%
1380 POKE DRIVE,DR%
1390 IF PREV_DR%<>DR% THEN CALL INITDBASIC
1400 IF NEW%=1 THEN CALL INITDBASIC
1410 CALL RDDBASIC
1420 RETURN
1430 ;
1440 ; ********* WRITE DBASIC SECTORS *********
1450 ;
1460 ;
1470 ; "INPUT PARAMETERS:    VARIABLE NAME      DESCRIPTION
1480 ; "                     DATABFR            ADDRESS OF MEMORY TO WRITE FROM
1490 ; "                     SECTOR%            STARTING ABSOLUTE SECTOR #
1500 ; "                     CNT%               # OF SECTORS TO WRITE
1510 ; "                     DR%                # OF DRIVE TO WRITE TO
1520 ; "                     NEW%               IF 1 THEN INIT THE DISK ELSE NOT
1530 ;
1540  "WRITEDBASIC"
1550 TEMP=ADR0+DATABFR:PEEK $0011C6,ADR$
1560 POKE BUFFER,ADR$
1570 POKEW SECTOR,SECTOR%
1580 POKEW COUNT,CNT%
1590 PEEK DRIVE,PREV_DR%
1600 POKE DRIVE,DR%
1610 IF PREV_DR%<>DR% THEN CALL INITDBASIC
1620 IF NEW%=1 THEN CALL INITDBASIC
1630 CALL WRDBASIC
1640 RETURN
1650 ;
