10 REM > CustomDNFS 1.40
   20 REM (C)1997-98 J.G.Harston
   30 REM Allows customising of NFS3.60 and DFS1.20 in
   40 REM DNFS3.00 ROM or 8K NFS3.60 ROM
   50 REM 25-Jul-1998 v1.20 - Added NotReady patch to DFS
   60 REM 23-Aug-1998 v1.30 - Read image direct from ROM
   70 REM 22-Nov-2015 v1.40 - Optimise UTILS, *EX bugfix
   80 :
   90 MODE&87:PRINTSPC4"Customise DNFS for BBC B/B+"'SPC4;STRING$(27,"=")
  100 VDU 28,0,24,39,2:DIMmem%&3FFF:mem%!&2000=0:mem%!&3A2C=0:PROCLoadROM
  110 CLS:VDU26:PROCupdate:psn%=0:REPEATUNTILFNchange:VDU11
  120 save$=" "+STR$~mem%+"+":IFmem%!9=&2C534644:save$=save$+"4000" ELSE save$=save$+"2000"
  130 IFRIGHT$(file$,1)>="0" OR RIGHT$(file$,1)<="2":file$=LEFT$(file$,LENfile$-1)
  140 IFmem%?&213=&32:file$=file$+"2" ELSE file$=file$+"1"
  150 PRINT"Enter name to save by: '"file$"'":REPEATINPUT":"A$:IFLEFT$(A$,1)="*":OSCLIA$
  160 UNTILLEFT$(A$,1)<>"*":IFA$<>"":file$=A$
  170 save$="*Save "+file$+save$+" 0 FFFBBC00":PRINTsave$;:OSCLIsave$:PRINT
  180 END
  190 :
  200 DEFPROCLoadROM:file$="DNFS300":REM %.^.ROMImages
  210 PRINT'"Read image from active ROM? ";:INPUT""A$:IFLEFT$(A$,1)="Y"ORLEFT$(A$,1)="y":PROCReadFromROM:ENDPROC
  220 PRINT'"File to load: '"file$"'":REPEATINPUT":"A$:IFLEFT$(A$,1)="*":OSCLIA$
  230 UNTILLEFT$(A$,1)<>"*":IFA$<>"":file$=A$
  240 IFfile$<>"":PRINT"Loading...";:OSCLI"LOAD "+file$+" "+STR$~mem%
  250 IFmem%!13<>&54454E:PRINT'"File '"file$"' is not a DNFS image.":END
  260 ENDPROC
  270 :
  280 DEFFNd0(A%,N%)=RIGHT$("00000000"+STR$A%,N%)
  290 DEFFNh0(A%,N%)=RIGHT$("00000000"+STR$~A%,N%)
  300 DEFFNstn(A%):=FNd0(A%DIV256,3)+"."+FNd0(A%AND&FF,3)
  310 DEFFNdot(A$):A%=INSTR(A$,"."):IFA%=0:=VALA$ ELSE =256*VALLEFT$(A$,A%-1)+VALMID$(A$,A%+1)
  320 :
  330 DEFFNtype(A%):LOCALA$:IFA%=0:="* Reserved *"
  340 IF(A%AND&FF00)=&FF00:A$="SJ " ELSE IF(A%AND&FF00)=&0100:A$="Torch " ELSE IF(A%AND&FF00)=&0200:A$="Reuters " ELSE IF(A%AND&FF00)=&1000:A$="JGH " ELSE IFA%<256:A$="Acorn "
  350 IFA%=1:=A$+"BBC"
  360 IFA%=2:=A$+"Atom"
  370 IFA%=3:=A$+"System 3/4"
  380 IFA%=4:=A$+"System 5"
  390 IFA%=5:=A$+"Master 128"
  400 IFA%=6:=A$+"Electron"
  410 IFA%=7:=A$+"Archimedes"
  420 IFA%=8:=A$+"*Reserved*"
  430 IFA%=9:=A$+"Communic'r"
  440 IFA%=10:=A$+"Master ET"
  450 IFA%=11:=A$+"Filestore"
  460 IFA%=12:=A$+"M-Compact"
  470 IFA%=13:=A$+"PC Ecolink"
  480 IFA%=14:=A$+"RISCiX"
  490 IFA%=15:=A$+"Risc PC"
  500 IFA%=16:=A$+"Iyonix"
  510 IFA%=17:=A$+"A9"
  520 IFA%=&1040:=A$+"ZX Spectrum"
  530 IFA%=&1041:=A$+"Amstrad CPC"
  540 IFA%=&FFF8:=A$+"GP Server"
  550 IFA%=&FFF9:=A$+"80386 UNIX"
  560 IFA%=&FFFA:=A$+"SCSI Card"
  570 IFA%=&FFFB:=A$+"IBM Interface"
  580 IFA%=&FFFC:=A$+"Nascom 2"
  590 IFA%=&FFFD:=A$+"RM 480Z"
  600 IFA%=&FFFE:=A$+"File Server"
  610 IFA%=&FFFF:=A$+"Z80 CP/M"
  620 =A$+"?"
  630 :
  640 DEFPROCupdate:PRINTTAB(0,3);
  650 PRINT"Machine type:  &";FNh0(mem%!&21,4);" - ";FNtype(mem%!&21 AND &FFFF);SPC(39-POS)''
  660 PRINT"NFS version:    ";~mem%?&24;".";~mem%?&23''
  670 PRINT"File server:    ";FNstn(256*mem%?&2EE+mem%?&2E7)''
  680 PRINT"Printer server: ";FNstn(256*mem%?&2EE+mem%?&304)''
  690 PRINT"DFS version:    ";:IFmem%!9=&2C534644:PRINT$(mem%+&3A2C)'' ELSE PRINT"****"''
  700 PRINT"NFS *EX bugfix: ";:IFmem%?&C57=&8C:PRINT"No " ELSE PRINT"Yes"
  710 ENDPROC
  720 :
  730 DEFFNchange:psn%=psn%+1:PRINTTAB(0,psn%*3+1+3*(psn%>5));
  740 IFpsn%=8:PRINT"Ok? ";:INPUT""A$:VDU11:PRINTSPC39:psn%=0:=LEFT$(A$,1)="Y" OR LEFT$(A$,1)="y"
  750 PRINT"Change to: ";
  760 IFpsn%=5:VDU8,8:PRINT" fix timeouts? ";
  770 IFpsn%=6:VDU8,8:PRINT" optimise UTILS? ";
  780 IFpsn%=7:VDU8,8:PRINT" add *EX bugfix? ";
  790 INPUT""A$:VDU11:PRINTSPC39:IFA$="":=0
  800 IFpsn%=1:A%=EVAL("&"+A$):mem%?&21=A%:mem%?&22=A%DIV256
  810 IFpsn%=2:A%=FNdot(A$):mem%?&23=EVAL("&"+STR$(A%AND&FF)):mem%?&24=A%DIV256:mem%?&210=(mem%?&24)+48:mem%?&212= ((mem%?&23)AND&F0)DIV16+48:mem%?&213=((mem%?&23)AND&F)+48
  820 IFpsn%=3:A%=FNdot(A$):mem%?&2E7=A%:mem%?&2EE=A%DIV256
  830 IFpsn%=4:A%=FNdot(A$):mem%?&304=A%:mem%?&2EE=A%DIV256
  840 IFpsn%=5:IFLEFT$(A$,1)="Y"ORLEFT$(A$,1)="y":PROCFixDFS
  850 IFpsn%=6:IFLEFT$(A$,1)="Y"ORLEFT$(A$,1)="y":PROCFixUTILS
  860 IFpsn%=7:IFLEFT$(A$,1)="Y"ORLEFT$(A$,1)="y":PROCFixEX
  870 PROCupdate:=0
  880 :
  890 DEFPROCFixDFS:IF$(mem%+&3A2C)<>"DFS 1.20":ENDPROC
  900 mem%?&250C=&20:REM new address of *COMPACT
  910 mem%!&2A4C=&7730A2C6:mem%!&2A50=&C9BB1520
  920 mem%?&2A54=&00:REM save catalogue resets 'Not Ready'
  930 mem%?&2C12=&1A:REM branch to earlier 'Not Ready' check
  940 mem%?&2C2B=&B0:REM branch earlier in addr=addr+num
  950 mem%!&2C2D=&F0BB0D20
  960 mem%?&2C31=&07:REM call 'Not Ready' reset code
  970 $(mem%+&3ADD)="src> <dst>"+CHR$&BC+"old> <new>"+CHR$&A8+"<dir>)"+CHR$&A8+"<drv>)"+CHR$&BC+"title>"+CHR$&BC+"drv>"+CHR$255:REM Shortened help text
  980 mem%!&3B0D=&AA842048:mem%!&3B11=&6010C968
  990 mem%!&3B15=&A4202BA0:mem%!&3B19=&BB0D20AC
 1000 mem%!&3B1D=&EA60F6F0:REM Check for and clear 'Not Ready'
 1010 mem%!&3B22=&F720A9CE:mem%!&3B26=&6D6F439F
 1020 mem%!&3B2A=&74636170:REM Short 'Compacting'
 1030 $(mem%+&3A2C)="DFS 1.21":ENDPROC
 1040 :
 1050 DEFPROCFixUTILS:IFLEFT$($(mem%+&3A2C),7)<>"DFS 1.2":ENDPROC
 1060 RESTORE:READ A$
 1070 REPEAT:A%=EVAL("&"+MID$(A$,4,4))-&8000:A$=MID$(A$,10,LENA$-11)
 1080   REPEAT:mem%?A%=EVAL("&"+LEFT$(A$,2)):A%=A%+1:A$=MID$(A$,3):UNTILA$=""
 1090 READ A$:UNTIL LEFT$(A$,3)=":00"
 1100 ENDPROC
 1110 DATA :01A56C0044AA
 1120 DATA :02A57200BF9593
 1130 DATA :01A57A00D20E
 1140 DATA :01A581009940
 1150 DATA :02A58E00BF9577
 1160 DATA :05B49500C904208EBF78
 1170 DATA :01B4E800EA79
 1180 DATA :01BA330032E0
 1190 DATA :20BE8A00B1BEC921B0034C618C4CC180A900F002A9FF85AB2080BFA90DD01820D7FFB01C94
 1200 DATA :20BEAA00C90AF0F728D0054820A1BF6820E3FF24FF3019AA25ABC90D084CA5BE28E00DF017
 1210 DATA :20BECA000320E7FFA9004CCEFF2080BF24FF30651820E4BF20A9BFBA8AE907AA9AA9088565
 1220 DATA :09BEEA00AC20D7FFB0109D01014E
 1230 DATA :1BBEF60020A9BFE8C6ACD0EDF016A92A20EEFF20EEFF20A9BFA9009D0101E8E7
 1240 DATA :11BF1300D0EB386A85ABA2088A1865A885A89002E692
 1250 DATA :20BF250068C97FB004C920B002A92E20EEFFCAD0EF20E7FFA5AB3091109720CEBE4C76ABB9
 1260 DATA :20BF450020B8BFA98020CEFF85AA20A1BFA92085AEBA8AE94085ADA0FF84AFC884ABC884D0
 1270 DATA :20BF6500AC8898A2AB20F1FFB0D0A200A4AABD000120D4FFE8C90DD0F5F0CF20B2BFA940B6
 1280 DATA :14BF850020CEFFA8D0264C8CA1F005AD80FE2903602090BF89
 1290 DATA :0CBF9A00FA4CC1B3FFFFFF20DCBFB00376
 1300 DATA :01BFAD00EEA5
 1310 DATA :01BFB6000981
 1320 DATA :01BFFC00EE56
 1330 DATA :0000000000
 1340 :
 1350 DEFPROCFixEX
 1360 IF$(mem%+&3A2C)="DFS 1.22":mem%?&C57=&BE:mem%?&C58=&89:mem%?&23=&62:mem%?&213=&32:ENDPROC
 1370 IFLEFT$($(mem%+&3A2C),7)="DFS 1.2" OR mem%!12<>&54454E20 OR mem%?&C57<>&8C:ENDPROC
 1380 A%=&2000:REPEAT:A%=A%-1:UNTILmem%?A%<>&FF:IFA%>&3FF4:ENDPROC
 1390 mem%!(A%+1)=&21C9BEB1:mem%!(A%+5)=&614C03B0:mem%!(A%+9)=&80C14C8C
 1400 mem%?&C57=A%DIV256+&80:mem%?&C58=A%:mem%?&23=&62:mem%?&213=&32
 1410 ENDPROC
 1420 :
 1430 DEFPROCReadFromROM:file$="DNFS300"
 1440 DIM mc% 79:FOR P=0 TO 1:P%=mc%:[OPT P*2
 1450   LDA #&80:STA &73:LDA #0:STA &72   :\ Source address
 1460   TAY:JSR &FFDA:PHA                 :\ Read current FS
 1470   LDA #143:LDX #18:LDY #4:JSR &FFF4 :\ Select DFS
 1480   LDA &F4:PHA                       :\ Save this ROM
 1490   LDA &DBC:STA &F4:STA &FE30:LDY #0 :\ Select DFS ROM
 1500   .lp
 1510   LDA (&72),Y:STA (&70),Y:INY:BNE lp      :\ Copy a page
 1520   INC &73:INC &71:LDA &73:CMP #&C0:BNE lp :\ Copy whole ROM
 1530   PLA:STA &F4:STA &FE30              :\ Restore ROM
 1540   PLA:TAY:LDX #18:LDA #143:JMP &FFF4 :\ Restore FS
 1550 ]NEXT:!&70=mem%:CALLmc%:ENDPROC