10 REM > HexDiff
   20 DIM ctrl% 31,name% 127,mem1% 255,mem2% 255
   30 ON ERROR REPORT:PROCCloseAll:PRINT:PROCexit(ERR):END
   40 A$=FNOS_GetEnv:in1%=0:in2%=0:out%=0:X%=ctrl%:Y%=X%DIV256
   50 eol$=CHR$13:IFos%>5:eol$=CHR$10 ELSE IFos%=32:eol$=CHR$13+CHR$10:PROCWin_TextIO
   60 in1$=FNcl("",1):in2$=FNcl("",1):out$=FNcl("",1):base$=FNcl("",1)
   70 IFin1$="-?":PRINT"Usage: HexDiff <file1> (<file2>) <outfile> (<addr>)":PROCexit(0):END
   80 IFout$="":out$=in2$:in2$=""
   90 IFASCin2$=34:in2$=""
  100 IFin1$="":INPUT"Base file: "in1$:INPUT"Diff file: "in2$:INPUT"Output: "out$:INPUT"Base address: &"base$
  110 X%!2=0:IFFNfile(in1$,5)<>1:PRINT"File1 '"in1$"' not found":PROCexit(214):END
  120 load1%=X%!2:IFbase$<>"":load1%=EVAL("&"+base$)
  130 X%!2=0:IFin2$<>"":IFFNfile(in2$,5)<>1:PRINT"File2 '"in2$"' not found":PROCexit(214):END
  140 load2%=X%!2:IFbase$<>"":load2%=EVAL("&"+base$)
  150 in1%=OPENIN(in1$):IFin2$<>"":in2%=OPENIN(in2$)
  160 IFout$<>"":out%=OPENOUT(out$)
  170 ext1%=EXT#in1%:ext2%=ext1%:IFin2%:ext2%=EXT#in2%
  180 line$="":base%=0:REPEAT
  190   IFNOTEOF#in1%:PROCgbpb(4,in1%,mem1%,256,0)
  200   IFin2%:IFNOTEOF#in2%:PROCgbpb(4,in2%,mem2%,256,0)
  210   max%=ext2%-base%-1:IFmax%>255:max%=255
  220   FOR byte%=0 TO max%:IFLENline$>31:PROCEmit
  230     IFin2%=0:line$=line$+CHR$mem1%?byte%
  240     IFin2%:IFmem1%?byte%=mem2%?byte%:IFline$<>"":PROCEmit
  250     IFin2%:IFmem1%?byte%<>mem2%?byte% OR base%+byte%>ext1%:line$=line$+CHR$mem2%?byte%
  260   NEXT:base%=base%+256:eof%=EOF#in1%:IFin2%:eof%=eof%OREOF#in2%
  270 UNTILeof%:IFline$<>"":base%=base%-256:PROCEmit
  280 PROCOut(":0000000000"+eol$):PROCCloseAll:ON ERROR PROCexit(0):END
  290 IFout$<>"":IFos%<32:OSCLI"SetType "+out$+" FFF":OSCLI"Stamp "+out$
  300 PROCexit(0):END
  310 DEFPROCCloseAll
  320 in1%=in1%:IFin1%:A%=in1%:in1%=0:CLOSE#A%
  330 in2%=in2%:IFin2%:A%=in2%:in2%=0:CLOSE#A%
  340 out%=out%:IFout%:A%=out%:out%=0:CLOSE#A%
  350 ENDPROC
  360 DEFPROCEmit
  370 addr%=load1%+base%+byte%-LENline$
  380 PROCOut(":"+FNh0(LENline$,2)+FNh0(addr%,4)+"00")
  390 FOR lp%=1 TO LENline$:PROCOut(FNh0(ASCMID$(line$,lp%,1),2)):NEXT
  400 sum%=LENline$+(addr%DIV256)+(addr%AND255)
  410 FOR lp%=1 TO LENline$:sum%=sum%+ASCMID$(line$,lp%,1):NEXT
  420 PROCOut(FNh0(256-(sum%AND255),2)+eol$):line$="":ENDPROC
  430 DEFPROCOut(A$):IFout%:PROCwr(out%,A$):ENDPROC ELSE ENDPROC
  440 DEFFNOS_GetEnv:LOCALA$,A%,X%,Y%:X%=1:os%=((USR&FFF4)AND&FF00)DIV256:DIMX%-1
  450 IFos%=32:IFPAGE>&FFFF:SYS"GetModuleFileName",0,X%,255:A$=$$X%:run$=A$:=@cmd$
  460 IFos%=32:A$=$&100
  470 IFLENA$=0:IFPAGE>&7FFF:run$=$&8100:SYS"OS_GetEnv"TOA$,,A%:SYS"OS_WriteEnv","",A%:A$=MID$(A$,1+INSTR(A$+" "," ",1+INSTR(A$," "))):IFLENA$=0:A$=run$
  480 IFLENA$=0:IF?(TOP-3):A$=$&600 ELSE IFLENA$=0:A$=$(PAGE-&300)
  490 A%=INSTR(A$+" "," "):run$=LEFT$(A$,A%-1):IFrun$<>"":=MID$(A$,A%+1)
  500 Y%=X%DIV256:A%=9:?X%=0:X%!1=X%+16:X%!16=0:CALL&FFD1:A%=X%+16:IF!A%AND?A%+A%?2<>8:A%?(A%+1)=13:=$(A%+1)
  510 =""
  520 DEFPROCos(A$):IFASCA$=42:OSCLIA$ ELSE IFA$<>"":CHAINA$
  530 ENDPROC
  540 DEFPROCexit(A%):OSCLI"FX1,"+STR$A%:quit$=quit$:A$=quit$:quit$="":PROCos(A$)
  550 IFos%=32:QUIT A%
  560 IFos%<6:END ELSE *Quit
  570 ENDPROC
  580 DEFFNcl(l$,n%):IFl$="":A$=FNs(A$):IFASCA$=34:A%=INSTR(A$+""" ",""" ",2):l$=MID$(A$,2,A%-3):A$=FNs(MID$(A$,A%+1)):=l$
  590 IFl$="":A%=INSTR(A$+" "," "):l$=LEFT$(A$,A%-1):A$=FNs(MID$(A$,A%+1)):=l$
  600 IFn%=0:IFl$<>"":A%=INSTR(A$,l$):IFA%:A$=FNs(LEFT$(A$,A%-1)+MID$(A$,INSTR(A$," ",A%)+1)):=TRUE
  610 IFn%=0:IFl$<>"":=FALSE
  620 A%=INSTR(LEFT$(" ",ASCl$=32)+A$,l$):IFA%=0:=""
  630 A$=LEFT$(A$,A%-1)+FNs(MID$(A$,INSTR(A$," ",A%)+1))
  640 IFASCl$=32:l$=MID$(A$,A%):A$=LEFT$(A$,A%-1):=MID$(l$,1-(ASCl$=34),LENl$+2*(ASCl$=34))
  650 IFASCMID$(A$,A%,1)<>34:l$=MID$(A$,A%,INSTR(A$+" "," ",A%)-A%):A$=LEFT$(A$,A%-1)+MID$(A$,A%+LENl$+1):=l$
  660 l$=MID$(A$,A%+1,INSTR(A$+""" ",""" ",A%+1)-A%-1):A$=LEFT$(A$,A%-1)+MID$(A$,A%+LENl$+3):=l$
  670 DEFFNs(A$):IFLEFT$(A$,1)=" ":REPEATA$=MID$(A$,2):UNTILLEFT$(A$,1)<>" "
  680 IFRIGHT$(A$,1)=" ":REPEATA$=LEFT$(A$,LENA$-1):UNTILRIGHT$(A$,1)<>" "
  690 =A$
  700 DEFFNh0(A%,N%)=RIGHT$("0000000"+STR$~A%,N%)
  710 DEFFNfile(A$,A%):IFos%<32:$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF
  720 IFINSTR(A$,".")=0:A$=A$+"."
  730 IFA%=255 OR A%=5:X%!14=OPENIN(A$):IFX%!14:X%!10=EXT#X%!14:CLOSE#X%!14
  740 IFA%=255:IFX%?6=0:OSCLI"LOAD """+A$+""" "+STR$~X%!2:=1
  750 IFA%=5:IFX%!14:=1 ELSE IF A%=5:=0
  760 IFA%=0:OSCLI"SAVE """+A$+""" "+STR$~X%!10+" "+STR$~X%!14:X%!10=X%!14-X%!10:=1
  770 IFA%=7:OSCLI"SAVE """+A$+""" "+STR$~PAGE+"+"+STR$~X%!10:X%!10=X%!14-X%!10:=1
  780 IFA%=8 THEN
  790   LOCAL ERROR:ON ERROR LOCAL:=2
  800   OSCLI"MKDIR "+A$:=2
  810 ENDIF
  820 =0
  830 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%)
  840 ?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:IFos%<32:CALL &FFD1:ENDPROC
  850 IFA%=1ORA%=3:PTR#?X%=X%!9
  860 REPEAT:IFA%=1ORA%=2:BPUT#?X%,?X%!1 ELSE IFA%=3ORA%=4:?X%!1=BGET#?X%
  870 X%!1=X%!1+1:X%!5=X%!5-1:UNTIL(EOF#?X% AND A%>2)OR X%!5<1:ENDPROC
  880 DEFPROCwr(o%,A$):IFA$="":ENDPROC
  890 FORA%=1TOLENA$:BPUT#o%,ASCMID$(A$,A%,1):NEXT:ENDPROC
  900 DEFPROCWin_TextIO
  910 SYS "GetStdHandle",-10 TO @hfile%(1):*INPUT 1
  920 SYS "GetStdHandle",-11 TO @hfile%(2):*OUTPUT 2
  930 SYS "SetConsoleMode",@hfile%(1),0:ENDPROC