10 REM " 4/3/87    6:57
   20 HIMEM=&7C00
   30 FOR P=0 TO 1
   40   P%=&A00
   50   [OPT P*2
   60   BCS go
   70   RTS
   80   .go
   90   LDA #&30:STA &F2
  100   LDA #&A:STA &F3:LDY #0:JSR &FFC2
  110   BEQ end
  120   .loop
  130   JSR &FFC5:BCS end:JSR &FFE3:JMP loop
  140   .end
  150   JSR &FFE7:JMP &FFE7
  160   ]
  170 NEXTP:*KEY 10O.|K|MG.190|K|M
  180 FOR MM=0 TO 2:PROC_DWIND(MM,0,FNheight,FNwidth,0):NEXTMM:GOTO240
  190 ON ERROR RUN
  200 Y%=VPOS:PRINTTAB(0,1);"Sigma Computer":PRINTTAB(0,Y%);"      ";TAB(0,Y%-2);"      ":IF ?&355<>7 THEN GOTO 220
  210 IF (?&28A AND 8)=0 THEN FOR Z=32200 TO HIMEM STEP -4:!Z=!(Z-3):NEXTZ
  220 PROC_STRIPES:PRINTTAB(0,Y%-2);
  230 IF ?&408>4 OR ?&409>4 OR ?&40A>4 OR ?&40B>4 THEN ?&408=0:?&409=1:?&40A=2:?&40B=3
  240 CLEAR
  250 DIM mcode% 50
  260 FOR P=0 TO 1
  270   P%=mcode%
  280   [OPT P*2
  290   LDA #help AND 255:STA &F2
  300   LDA #help DIV 256:STA &F3
  310   LDA #143:LDX #9:LDY #0
  320   JMP &FFF4
  330   .help
  340   EQUB 13
  350   ]
  360 NEXT P
  370 DIM COM$(21),BCOM$(7),str$(15),err% 40:str$(0)="S":str$(1)="S":str$(2)="P":str$(3)="R":printer=0:?err%=0:VER$="OS 1.3"
  380 FOR L=1 TO 21:READ COM$(L):NEXT L
  390 DATA CAT,EXEC,ENTER,EXAMINE,FX,HELP,INFO,KEY,LOAD,MESSAGE
  400 DATA OPT,OS,ROMS,RUN,SAVE,SPOOL,TAPE,*,*,HARSTON,MASTER
  410 FOR L=1 TO 7:READ BCOM$(L):NEXT L
  420 DATA AUTO,BASIC,EDIT,ERASE,RENUMBER,TRACE,*
  430 ON ERROR GOTO 530
  440 PRINTFN_STREAM(1);:IF R%=1 THEN GOTO 3020
  450 PRINT"Operating System"'
  460 $err%=CHR$0+CHR$128+"OS (C)Harston Computing Ltd."+CHR$0:CALL err%
  470 line=480
  480 R%=0:PRINTFN_STREAM(0);:VDU42
  490 A$=FN_EDIT
  500 rline=480
  510 PROC_OSC(A$)
  520 GOTO rline
  530 IF ERR=128 THEN ?(err%+1)=0:GOTO ERL+10
  540 IFERR=127THENGOTO1000
  550 VDU6:IF (?&28A AND 2)=0 THEN VDU7
  560 IF ERR=251 OR ERR=250 THEN *K.10O.|KMG.180|K|M
  570 PRINTFN_STREAM(0);:REPORT:IF ERR<>17 THEN GOTO 590
  580 IF INKEY(-57)=0THEN GOTO 600
  590 IF ERR<128 THEN PRINT" at line ";ERL;FN_STREAM(0);:OSCLI"FX4":OSCLI"FX121":END
  600 PRINTFN_STREAM(0):GOTO line
  610 DEFFN_TBVAR(X,Y)
  620 IF X=0 THEN =COM$(Y)
  630 IF X=1 THEN =BCOM$(Y)
  640 REMIF X=2 THEN =UCOM$(Y)
  650 IF X>15 THEN READ Z$:=Z$
  660 ="/"
  670 DEFFN_TLK2(TB,STRT,MAX)
  680 HL2=HL:C=STRT:GOTO 720
  690 DEFFN_TLOOK(TB,MAX)
  700 HL2=HL
  710 C=1
  720 L=1:CC$=FN_TBVAR(TB,C)
  730 IF MID$(A$,HL,1)=MID$(CC$,L,1) THEN GOTO 790
  740 IF MID$(A$,HL,1)<"a" THEN GOTO 760
  750 IF (ASCMID$(A$,HL,1))-32=ASCMID$(CC$,L,1) THEN GOTO 790
  760 IF MID$(A$,HL,1)="." THEN =C
  770 C=C+1:HL=HL2:IF C>MAX THEN=-1
  780 GOTO 720
  790 L=L+1:HL=HL+1:IF L>LEN CC$ THEN HL=HL-1:=C
  800 GOTO 730
  810 DEFPROC_STRIPES:IF?&355<>7 OR (?&28A AND 8)<>0 THENFOR MM=0 TO 2:PROC_DWIND(MM,0,FNheight,FNwidth,0):NEXTMM:VDU26:?&408=0:?&409=0:?&40A=0:?&40B=0:ENDPROC
  820 VDU26:PROC_DWIND(0,3,24,37,15):PROC_DWIND(1,3,14,39,0):PROC_DWIND(2,3,14,39,0):PROC_DWIND(3,0,24,39,0):FORZ=0TO14:PRINTTAB(0,Z);"";CHR$157;"":NEXTZ:FORZ=15TO23:PRINT"";CHR$157;"":NEXTZ
  830 PRINT"";CHR$157;"";
  840 ENDPROC
  850 DEFPROC_OSC(A$)
  860 HL=0
  870 IF A$="" THEN ENDPROC
  880 IF A$=CHR$13THENENDPROC
  890 IF FN_Nxtchar="*" THEN GOTO 880
  900 IF MID$(A$,HL,1)="/"THEN GOTO 1080
  910 NUM=FN_TLOOK(0,20)
  920 IF NUM<>-1 THEN GOTO 970
  930 PROC_BROM(1):IF found=1 THEN ENDPROC
  940 PROC_UROM(1):IF found=1 THEN ENDPROC
  950 REMPRINT"Looking elsewhere.."
  960 OSCLI A$:ENDPROC
  970 ON NUM GOTO 2000,2060,1630,1790,2070,2200,2360,2370,2440,1460,2520,1030,2580,2610,2650,2780,3300,1040,1050,980
  980 MM=FN_GETDEC MOD 8:A%=133:X%=MM:U%=(USR&FFF4)AND&FFFF00:IF U% DIV 256<(TOP+2000) THEN $(err%+1)="Bad mode"+CHR$0:CALL err%
  990 ?(err%+1)=127:CALLerr%
 1000 MODEMM:PROC_STRIPES
 1010 GOTOline
 1020 ENDPROC
 1030 R%=0:GOTO 240
 1040 FL$=FN_GSTR:CHAINFL$
 1050 FL$=FN_GSTR:VDU21:OSCLI"INFO "+FL$
 1060 FL$="LOAD"""+FL$+""""+CHR$6+CHR$13:FORL=1 TO LEN FL$:OSCLI"FX 138,0,"+STR$(ASCMID$(FL$,L,1)):NEXT L
 1070 VDU6,11,21:END
 1080 A$=MID$(A$,HL+1):GOTO950
 1090 DEFFN_Nxtchar
 1100 HL=HL+1:IF HL>LEN A$THEN =CHR$13
 1110 IF MID$(A$,HL,1)=CHR$13THEN=CHR$13
 1120 IF MID$(A$,HL,1)<"!"THEN GOTO 1100
 1130 =MID$(A$,HL,1)
 1140 DEFFN_GetChar
 1150 IF HL>LEN A$ THEN=13 ELSE=ASCMID$(A$,HL,1)
 1160 DEFFN_GETDEC
 1170  LOCAL V:V=0
 1180  AA$=FN_Nxtchar:IF AA$<"0" OR AA$>"9" THEN =-1
 1190 GOTO 1210
 1200 AA$=FN_Nxtchar:IF AA$<"0" OR AA$>"9" THEN =V
 1210 V=V*10+ASC AA$-48
 1220 GOTO 1200
 1230 DEFFN_GHEX
 1240 AA$=FN_Nxtchar:IF AA$>"`" THEN AA$=CHR$(ASC AA$-32)
 1250 HX=ASC AA$-48:IF HX>9 THEN HX=HX-7
 1260 ZZ=ASCFN_Nxtchar+FN_SEPAR:=HX
 1270 $err%=CHR$0+"Bad hex"+CHR$0:CALL err%
 1280 =0
 1290 DEFFN_SEPAR
 1300 IF HL>LEN A$ OR MID$(A$,HL,1)=CHR$13 THEN =0
 1310 IF MID$(A$,HL,1)="," OR MID$(A$,HL,1)=";" THEN =1
 1320 GOTO 2080
 1330 DEFPROC_STREM(ST):GOTO1370
 1340 DEFPROC_STRM
 1350 LOCAL ST:AA$=FN_Nxtchar:IF AA$<>"#"THEN HL=HL-1:ST=1:GOTO1370
 1360 ST=FN_GHEX:ZZ=FN_SEPAR
 1370 ST=ST AND15:IF str$(ST)="" $(err%+1)="Stream closed"+CHR$0:CALLerr%
 1380 stflg=INSTR("SPR",str$(ST)):IF stflg=0 $(err%+1)="Invalid I/O device"+CHR$0:CALLerr%
 1390 ON stflg GOTO 1400,1410,1430
 1400 OSCLI"FX3,68":IF ST=0 PRINTFN_WIND(?&408);:ENDPROC ELSE PRINTFN_WIND(?&409);:ENDPROC
 1410 IF NOT printer $(err%+1)="Printer not selected"+CHR$0:CALLerr%
 1420 OSCLI"FX3,10":ENDPROC
 1430 OSCLI"FX3,7":ENDPROC
 1440 PRINTFN_STREAM(ST);
 1450 ENDPROC
 1460 NUM=FN_GETDEC:IF NUM=-1 THEN GOTO 2080
 1470 IF NUM<>?&AFF THEN GOTO 1610
 1480 IF FN_SEPAR=0 THEN GOTO 2080
 1490 NUM=FN_GETDEC:IF NUM=-1 THEN GOTO 2080
 1500 HL1=HL:IF FN_Nxtchar=CHR$13 THEN GOTO 1560
 1510 IF MID$(A$,HL)=""""""+CHR$13 THEN OSCLI"FX 247":GOTO1590
 1520 HL=HL1:ZZ=FN_SEPAR
 1530 OSCLI"KEY 10,"+MID$(A$,HL+1):*KEY 10O.|K|MG.180|K|M
 1540 IF LEN A$>200 THEN GOTO 1600
 1550 $&A30=MID$(A$,HL+1):?&A2F=LEN A$-1
 1560 *FX249,10
 1570 *FX248
 1580 *FX247,76
 1590 ?&AFF=NUM:ENDPROC
 1600 $(err%+1)=CHR$&FD+"Bad string"+CHR$0:CALL err%
 1610 $(err%+1)="Bad number"+CHR$0:CALL err%
 1620 ENDPROC
 1630 AA$=FN_Nxtchar:VV=FN_GET2HEX:PRINTFN_STREAM(0);
 1640 PRINTFN_HEX(VV);" ";:CHK=0
 1650 AA$=FN_EDIT
 1660 IF LEN AA$<>19 THEN PRINT"Wrong length":GOTO 1640
 1670 AA$=LEFT$(AA$,18)
 1680 FOR LOOP1=VV TO VV+7
 1690   V1=FN_GHEX1(MID$(AA$,1,2)):CHK=CHK+V1:?LOOP1=V1:AA$=MID$(AA$,3)
 1700 NEXT LOOP1:CHK=CHK AND 255:IF CHK<>FN_GHEX1(AA$) THEN PRINT"Checksum error":GOTO 1640
 1710 VV=VV+8:IF VV<65536 THEN GOTO 1640
 1720 ENDPROC
 1730 DEFFN_GHEX1(A$)
 1740 IF LEN A$<>2 THEN =0
 1750 V4=ASCMID$(A$,1,1)-48:IF V4>9 THEN V4=V4-7
 1760 V5=ASCMID$(A$,2,1)-48:IF V5>9 THEN V5=V5-7
 1770 =V4*16+V5
 1780 ENDPROC
 1790 PROC_STRM:AA$=FN_Nxtchar:VV=FN_GET2HEX
 1800 PRINTFN_HEX(VV);" ";:CHK=0:FOR LOOP1=VV TO VV+7
 1810 PRINTFN_HEX1(?(LOOP1));" ";:CHK=CHK+?(LOOP1):NEXTLOOP1
 1820 PRINT" =";:CHK=CHK AND 255:PRINTFN_HEX1(CHK)
 1830 VV=VV+8:IF VV>65535 THEN ENDPROC ELSE GOTO 1800
 1840 DEFFN_HEX1(Z)
 1850 IF Z<15 THEN ="0"+STR$~(Z) ELSE =STR$~(Z)
 1860 DEFFN_HEX(Z)
 1870 =FN_HEX1(Z DIV 256)+FN_HEX1(Z AND 255)
 1880 DEFFN_GET2HEX
 1890  LOCAL VV,AA$,FL:VV=0:FL=0
 1900 AA$=MID$(A$,HL,1):IF AA$>"`" THEN AA$=CHR$(ASC AA$-32)
 1910 IF AA$<"0" OR AA$>"F" OR (AA$>"9" AND AA$<"A"THEN GOTO 1940
 1920 FL=1:VV=VV*16+ASC AA$-48:IF AA$>"9" THEN VV=VV-7
 1930 HL=HL+1:GOTO 1900
 1940 IF FL=1 THEN =VV ELSE GOTO 1610
 1950 DEFPROC_SPC
 1960 IF HL>LEN A$THEN ENDPROC
 1970 IF MID$(A$,HL,1)=" "THEN HL=HL+1:GOTO 1960
 1980 IF MID$(A$,HL,1)=CHR$13 THEN ENDPROC
 1990 ENDPROC
 2000 FF$="."
 2010 PROC_STRM
 2020 IF ASC(FN_Nxtchar)=-1 THEN FL$="":GOTO 2040
 2030 FL$=FF$+MID$(A$,HL)
 2040 OSCLI FL$
 2050 ENDPROC
 2060 FF$="EXEC ":GOTO 2010
 2070 VL=FN_GETDEC:IF VL<>-1 THEN GOTO 2090
 2080 $err%=CHR$0+CHR$254+"Bad command"+CHR$0:CALL err%
 2090 VB=0:VC=0:IF FN_SEPAR=3 THEN GOTO 2080
 2100 VB=FN_GETDEC:IF VB=-1 THEN VB=0:GOTO 2130
 2110 ZZ=FN_SEPAR
 2120 VC=FN_GETDEC:IF VC=-1 THEN VC=0
 2130 AA$="FX "+STR$(VL)+","+STR$(VB)+","+STR$(VC)
 2140 IFVL=101 THEN REPORT:PRINT" (";ERR;")":ENDPROC
 2150 IFVL=13 AND VB<4 AND VC<8 THEN ?(&408+VB)=VC:ENDPROC
 2160 IFVL=13 AND VB=255 THEN ?&408=0:?&409=1:?&40A=2:?&40B=3:ENDPROC
 2170 IFVL=0 AND VB=0 THEN $(err%+1)=CHR$247+VER$+CHR$0:CALLerr%
 2180 IFVL=0 THEN ENDPROC
 2190 OSCLIAA$:ENDPROC
 2200 PROC_STRM
 2210 AA$=FN_Nxtchar:AL$=MID$(A$,HL)
 2220 IF AA$=CHR$13 THEN PRINT'VER$:GOTO2330
 2230 HL1=HL:NUM1=FN_TLK2(0,12,14):HL=HL1:IF NUM1<>12 THEN GOTO 2330
 2240 PRINT'VER$:MAX=17:RESTORE 2290:PROC_HLP(0):GOTO2330
 2250 DEFPROC_HLP(X)
 2260 FOR L=1 TO MAX
 2270   PRINT "  ";FN_TBVAR(X,L);" ";:READ Z$:PRINT Z$
 2280 NEXT L
 2290 DATA (#<strm>) (<pointer>),(#<strm>) <afsp>,<start>,(#<strm>) <start>,<fx> <1st par> <2nd par>,(#<strm>) <name>,(#<strm>) <afsp>,<key> <text>
 2300 DATA <afsp> <start>,<oldpass> <newpass> <message>,<opt> <par>,,(#<strm>),(#<strm>) <afsp>,<afsp> <start> (<end>/+<length>) <exec> <reload>,(#<strm>) <afsp>
 2310 DATA <baud>
 2320 AA$="":ENDPROC
 2330 PROC_BROM(2):PROC_UROM(2)
 2340 $help=LEFT$(AL$,10):CALL mcode%
 2350 ENDPROC
 2360 FF$="INFO ":GOTO 2010
 2370 KY=FN_GETDEC
 2380 IF KY=-1 OR KY>25THEN ELSE GOTO 2400
 2390 $err%=CHR$0+CHR$251+"Bad key"+CHR$0:CALLerr%
 2400 ZZ=FN_SEPAR
 2410 IF KY=10 THEN AA$="O.|K|MG.180|K|M" ELSE AA$=""
 2420 OSCLI "KEY"+STR$(KY)+AA$+MID$(A$,HL+1)
 2430 ENDPROC
 2440 AA$=FN_Nxtchar:HL2=HL:GOTO2460
 2450 AA$=FN_Nxtchar
 2460 IF AA$<>"," AND AA$<>";" AND AA$<>CHR$13 THEN GOTO 2450
 2470 FL$=MID$(A$,HL2,HL-HL2)
 2480 ADD$=MID$(A$,HL+1)
 2490 FL$="LOAD "+FL$+" "+ADD$
 2500 OSCLI FL$
 2510 ENDPROC
 2520 VL=FN_GETDEC:IF VL=-1 THEN GOTO 2560
 2530 ZZ=FN_SEPAR
 2540 OSCLI A$
 2550 ENDPROC
 2560 $err%=CHR$0+CHR$203+"Bad option"+CHR$0:CALLerr%
 2570 ENDPROC
 2580 PROC_STRM
 2590 PRINT"15 OS"TAB(20)"( / / /S)"'"14 BASIC"TAB(20)"(F/R/L/S)"'"13 Extra Utilities"TAB(20)"( / / /S)"
 2600 ENDPROC
 2610 PROC_STRM
 2620 AA$="RUN "+MID$(A$,HL+1)
 2630 OSCLI AA$
 2640 ENDPROC
 2650 FL$="SAVE "+FN_GSTR:IF FN_SEPAR=0 THEN GOTO 2720
 2660 FL$=FL$+" "+FN_GSTR:IF MID$(A$,HL,1)<>"," AND MID$(A$,HL,1)<>";" AND MID$(A$,HL,1)<>"+" THEN GOTO 2720
 2670 IF MID$(A$,HL,1)<>"+" THEN FL$=FL$+" " ELSE FL$=FL$+"+"
 2680 FL$=FL$+FN_GSTR:IF FN_SEPAR=0 THEN GOTO 2710
 2690 FL$=FL$+" "+FN_GSTR:IF FN_SEPAR=0 THEN GOTO 2710
 2700 FL$=FL$+" "+FN_GSTR:IF FN_SEPAR=0 THEN GOTO 2710 ELSE GOTO 2720
 2710 OSCLI FL$:ENDPROC
 2720 $(err%+1)=CHR$252+"Bad address"+CHR$0:CALLerr%
 2730 DEFFN_GSTR
 2740 AA$=FN_Nxtchar:HL2=HL:GOTO2760
 2750 AA$=FN_Nxtchar
 2760 IF AA$<>";" AND AA$<>"," AND AA$<>"+" AND AA$<>CHR$13 THEN GOTO 2750
 2770 =MID$(A$,HL2,HL-HL2)
 2780 FF$="SPOOL ":GOTO 2010
 2790 ENDPROC
 2800 REM This is the BASIC 'ROM' from here onwards...
 2810 DEFPROC_BROM(X)
 2820 found=0
 2830 IF X>2 THEN ENDPROC
 2840 IF X=2 THEN GOTO 2890
 2850 NUM=FN_TLOOK(1,6):IF NUM=-1 THEN ENDPROC
 2860 found=1:IF NUM=2 OR NUM=6 THEN GOTO 2880
 2870 IF R%<>1 found=0:ENDPROC
 2880 ON NUM GOTO 2950,3040,3220,3170,3240,3280
 2890 IF FN_GetChar=13THEN PRINT'"BASIC 1.00":ENDPROC
 2900 HL1=HL:IF FN_TLK2(1,2,2)<>2 THEN HL=HL1:ENDPROC
 2910 HL=HL1:PRINT'"BASIC 1.00"
 2920 RESTORE 2940
 2930 MAX=6:PROC_HLP(1):ENDPROC
 2940 DATA <start> <step>,,<line>,<start> <end>,<start> <step>,<1/0>
 2950 VL=FN_GETDEC:IF VL=-1 THEN VL=10:ST=10:GOTO2980
 2960 ZZ=FN_SEPAR
 2970 ST=FN_GETDEC:IF ST=-1 THEN ST=10
 2980 FOR LO=VL TO 65000 STEP ST
 2990   PROC_PR(LO):A$=FN_EDIT
 3000 NEXT LO
 3010 ENDPROC
 3020 PROC_SB:GOTO 3050
 3030 DEFPROC_SB
 3040 line=2060:R%=1:PRINT"BASIC"':rline=2060:ENDPROC
 3050 $err%=CHR$0+"(C)1986 Harston Computing"+CHR$0:CALLerr%
 3060 PRINTFN_STREAM(0);">";:A$=FN_EDIT:IF A$="CALL !-4"+CHR$13 THEN CALL!-4
 3070 HL=0:IF FN_Nxtchar<>"*" THEN GOTO 3060
 3080 PROC_OSC(MID$(A$,HL+1))
 3090 GOTO 3060
 3100 DEFPROC_PR(LO)
 3110 IF LO>9999 GOTO 3160
 3120 IF LO>999 PRINT" ";:GOTO 3160
 3130 IF LO>99 PRINT"  ";:GOTO 3160
 3140 IF LO>9 PRINT"   ";:GOTO 3160
 3150 PRINT"    ";
 3160 PRINT;LO;" ";:ENDPROC
 3170 VL=FN_GETDEC:IF VL=-1 THEN GOTO 2080
 3180 IF FN_SEPAR<>1 THEN GOTO 2080
 3190 VL2=FN_GETDEC:IF VL=-1 THEN GOTO 2080
 3200 PRINT"Lines deleted from ";VL;" to ";VL2
 3210 ENDPROC
 3220 VL=FN_GETDEC:IF VL=-1 THEN GOTO 2080
 3230 PRINT"Editing line ";VL:ENDPROC
 3240 VL=FN_GETDEC:IF VL=-1 VL=10:ST=10:GOTO 3270
 3250 ZZ=FN_SEPAR
 3260 ST=FN_GETDEC:IF ST=-1 THEN ST=10
 3270 PRINT"Lines renumbered, starting at ";VL;","'"going up by ";ST:ENDPROC
 3280 VL=ABS FN_GETDEC
 3290 VL=VL AND 1:PRINT"Trace is o";:VDU (110*VL)+(102*(1-VL)),(102*(1-VL)):PRINT".":ENDPROC
 3300 baud=FN_GETDEC:IF baud=-1 THEN baud=300
 3310 PRINT"Tape baud ";baud
 3320 IF baud=300 THEN OSCLI"TAPE3" ELSE *TAPE12
 3330 ENDPROC
 3340 REM Editing routine:
 3350 DEFPROC_restofline
 3360 PRINTLEFT$(Y$,LENY$-1);B$;:IF B$<>"" THEN VDU8:B$=""
 3370 ENDPROC
 3380 DEFPROC_doline
 3390 PROC_restofline
 3400 PRINTSTRING$(LEN Y$-1,CHR$(8));
 3410 ENDPROC
 3420 DEFPROC_INIT
 3430 X$="":Y$=" ":edflag=0:keylen=0:edflg=0
 3440 VDU 23,1,0;0;0;0;
 3450 REM
 3460 ENDPROC
 3470 A2=255:keylen=-1:=CHR$(27)
 3480 DEFPROC_EEXIT
 3490 *FX225,1
 3500 *FX225,128
 3510 *FX225,144
 3520 ENDPROC
 3530 DEFFN_GETKEY
 3540 IF keylen=-1 THEN keylen=0:=A2
 3550 A$=FN_KEY:A=ASC A$
 3560 IF A=?&26C THEN GOTO 3470
 3570 IF A=27 THEN A2=27:keylen=-1:=CHR$A
 3580 IF A<128 THEN =A$
 3590 IF A<138 THEN GOTO 3650
 3600 IF (A AND 15)<11 THEN =CHR$(ASCA$-16)
 3610 IF (?&28A AND 1)=0 THEN GOTO 3630
 3620 IF (A AND 48)<20 THEN A=(A EOR 16):REM 'AMSTRAD'
 3630 IF (A AND 48)=0 OR (A AND 15)=11 THEN GOTO 3660
 3640 A2=((A-11)AND 7):A=(A AND 48)/2:A2=A2+A:keylen=-1:=CHR$(27)
 3650 OSCLI"FX138,0,"+STR$(A+64):GOTO3550
 3660 A=A AND 15:ON A-10 GOTO 3670,3720,3680,3710,3730
 3670 A=FN_SCRN:GOSUB 3690:IF A<>0 THEN =CHR$(A) ELSE VDU 7:GOTO 3550
 3680 GOSUB 3690:edflag=1:GOTO 3550
 3690 edx=edx+1:IF edx<FNwidth THEN RETURN ELSE edx=0
 3700 edy=edy+1:IF edy<FNheight THEN RETURN ELSE edy=0:RETURN
 3710 GOSUB 3700:edflag=1:GOTO 3550
 3720 edx=edx-1:edflag=1:IF edx>-1 THEN GOTO 3550 ELSE edx=FNwidth-1
 3730 edy=edy-1:edflag=1:IF edy>-1 THEN GOTO 3550 ELSE edy=FNheight-1:GOTO 3550
 3740 DEFFNheight=?&309-?&30B+1
 3750 DEFFNwidth=?&30A-?&308+1
 3760 DEFFN_SCRN
 3770 PROC_DECURSOR
 3780 X1=POS:Y1=VPOS:PRINTTAB(edx,edy);
 3790 A%=135:U%=USR &FFF4:PRINTTAB(X1,Y1);:=((U% AND &FF00)/256)
 3800 DEFFN_KEY
 3810 IF edflag=0 THEN edx=POS:edy=VPOS:GOTO 3830
 3820 VDU23,1,1;0;0;0;:PRINTTAB(edx,edy);
 3830 =GET$
 3840 DEFPROC_CURSOR
 3850 IF ?&355=7 THEN PRINTCHR$(255);CHR$(8);:ENDPROC
 3860 ?&D3=255-?&D3:PRINTLEFT$(Y$,1);:VDU8:?&D3=255-?&D3
 3870 xp=POS:yp=VPOS:IF edflag=0 THEN ENDPROC ELSE PRINTTAB(edx,edy);:ENDPROC
 3880 DEFPROC_DECURSOR
 3890 IF ?&355=7 THEN ENDPROC
 3900 IF ?&355=7 THEN PRINTTAB(xp,yp);" ";CHR$(8);:ENDPROC
 3910 PRINTTAB(xp,yp);LEFT$(Y$,1);:VDU8:ENDPROC
 3920 DEFFN_EDIT
 3930 LOCAL A$,B$,A,B,X$,Y$,edflag,edx,edy,xp,yp:xp=POS:yp=VPOS
 3940 REM
 3950 PROC_INIT
 3960 escflag=?&275:*FX 229,1
 3970 *FX 225,128
 3980 *FX 226,144
 3990 *FX 227,160
 4000 *FX 228,176
 4010 *FX221,1
 4020 *FX4,2
 4030 IF Y$="" THEN Y$=" ":X$=LEFT$(X$,LEN X$-1)
 4040 PROC_CURSOR:IF edflag=1 THEN VDU 23,1,1;0;0;0;
 4050 REMloop
 4060 IF ?&355<>7 THEN GOTO 4090
 4070 VDU255:PROC_doline:VDU8
 4080 IF X$<>"" THEN VDU 8:PRINTRIGHT$(X$,1);
 4090 lxp=POS:lyp=VPOS:A$=FN_GETKEY
 4100 PRINTTAB(lxp,lyp);
 4110 PROC_DECURSOR
 4120 A=ASC A$
 4130 IF A=27 THEN GOTO 4290
 4140 IF A=127 THEN PROC_DEL:GOTO4030
 4150 IF A<32 THEN GOTO 4240
 4160 IF LEN X$+LEN Y$>250 THEN VDU7:GOTO 4030
 4170 IF (LEN X$+LEN Y$)>=(FNwidth*FNheight)-2 THEN ?&275=escflag:PROC_restofline:VDU32,8:PRINT:PROC_EEXIT:$(err%+1)="No room for line"+CHR$0:CALL err%
 4180 X$=X$+A$:PRINTA$;:PROC_doline
 4190 GOTO 4030
 4200 DEFPROC_DEL
 4210 IF X$="" THEN PROC_BEEP:ENDPROC
 4220 VDU 32,8,127:X$=LEFT$(X$,LEN X$-1)
 4230 B$="  "+CHR$(8):PROC_doline:ENDPROC
 4240 IF A=13 THEN ?&275=escflag:PROC_restofline:VDU32,8:PRINT:PROC_EEXIT:=X$+LEFT$(Y$,LEN Y$-1)+CHR$(13)
 4250 REM Decode control keys
 4260 IFA<>21 THENVDUA:OSCLI"FX218":GOTO4030 ELSE IF X$="" THEN GOTO 4030 ELSE FOR L1=1 TO LEN X$:PROC_DEL:NEXT:GOTO4030
 4270 IF (escflag AND 1)=0 THEN ?&275=escflag:PROC_restofline:VDU32,8:PRINT:PROC_EEXIT:*FX125
 4280 GOTO 4050
 4290 REM esc codes
 4300 A=FN_GETKEY:IF A=27 THEN GOTO 4050
 4310 IF A=255 THEN GOTO 4270
 4320 A2=A DIV 8:A=A AND 7
 4330 ON A2 GOTO 4370,4490,4610
 4340 PROC_BEEP:GOTO4030
 4350 DEFPROC_BEEP:IF (?&28A AND 4)=0 THEN VDU7
 4360 ENDPROC
 4370 IF A>2 THEN PROC_doline
 4380 ON A+1 GOTO 4390,4410,4430,4450,4470
 4390 IF Y$=" " THEN GOTO 4340
 4400 Y$=MID$(Y$,2):B$=" ":PROC_doline:GOTO 4030
 4410 IF X$="" THEN GOTO 4340
 4420 Y$=RIGHT$(X$,1)+Y$:X$=LEFT$(X$,LEN X$-1):VDU 8:GOTO 4030
 4430 IF Y$=" " THEN GOTO 4340
 4440 X$=X$+LEFT$(Y$,1):Y$=MID$(Y$,2):VDU 9:GOTO 4030
 4450 IF LEN Y$-1<FNwidth THEN GOTO 4340
 4460 X$=X$+LEFT$(Y$,FNwidth):Y$=MID$(Y$,FNwidth+1):VDU 10:GOTO 4030
 4470 IF LEN X$<FNwidth THEN GOTO 4340
 4480 Y$=RIGHT$(X$,FNwidth)+Y$:X$=LEFT$(X$,LEN X$-FNwidth):VDU 11:GOTO 4030
 4490 IF A=1 OR A=2 THEN PROC_doline
 4500 ON A+1 GOTO 4340,4550,4580,4530,4510
 4510 IF X$="" THEN GOTO 4030
 4520 PRINTSTRING$(LEN X$,CHR$(8));:Y$=X$+Y$:X$="":GOTO 4030
 4530 IF Y$=" " THEN GOTO 4030
 4540 PROC_restofline:X$=X$+LEFT$(Y$,LEN Y$-1):Y$=" ":GOTO 4030
 4550 x1=POS:IF x1=0 THEN GOTO 4340
 4560 IF LEN X$<FNwidth THEN x1=LEN X$
 4570 PRINTSTRING$(x1,CHR$(8));:Y$=RIGHT$(X$,x1)+Y$:X$=LEFT$(X$,LEN X$-x1):GOTO 4030
 4580 x1=POS:IF x1=FNwidth-1 THEN GOTO 4340
 4590 IF FNwidth-x1>LEN Y$-1 THEN PRINTSTRING$(LEN Y$-1,CHR$9);:X$=X$+LEFT$(Y$,LEN Y$-1):Y$=" ":GOTO 4030
 4600 PRINTSTRING$(FNwidth-x1-1,CHR$(9));:X$=X$+LEFT$(Y$,FNwidth-x1-1):Y$=MID$(Y$,FNwidth-x1):GOTO 4030
 4610 IF A=0 THEN GOTO 4340
 4620 VDUA+7:GOTO 4030
 4630 DEFPROC_DWIND(wind%,a%,b%,c%,d%)
 4640 LOCAL BA%
 4650 IF wind%>7 OR wind%<0 THEN ENDPROC
 4660 BA%=wind%*9+&411
 4670 ?BA%=0:?(BA%+1)=0
 4680 ?(BA%+2)=a%:?(BA%+3)=b%:?(BA%+4)=c%:?(BA%+5)=d%
 4690 ?(BA%+6)=?&D2:?(BA%+7)=?&D3:?(BA%+8)=?&358
 4700 ENDPROC
 4710 DEFFN_WIND(w%)
 4720 IF w%<0 OR w%>7 THEN =""
 4730 LOCAL BA%
 4740 BA%=(7 AND (?&410))*9+&411
 4750 ?BA%=POS:BA%?1=VPOS:?(BA%+6)=?&D2:?(BA%+7)=?&D3:?(BA%+8)=?&358
 4760 BA%=w%*9+&411
 4770 VDU 28,?(BA%+2),?(BA%+3),?(BA%+4),?(BA%+5)
 4780 VDU31,?BA%,?(BA%+1)
 4790 ?&410=w%:?&D2=?(BA%+6):?&D3=?(BA%+7):?&358=?(BA%+8)
 4800 =""
 4810 DEFFN_STREAM(w%)
 4820 PROC_STREM(w%):=""
 4830 DEFPROC_UROM(X)
 4840 IF X>2 THEN ENDPROC
 4850 IF X=2 THEN GOTO 5000
 4860 RESTORE 4940:NUM=FN_TLOOK(16,17):IF NUM=-1 OR (NUM AND 1)=0 THEN ENDPROC
 4870 found=1:ON (NUM+1)/2 GOTO 1040,4950,980,1050,4880,4890,4910,4970,4900
 4880 VDU2:printer=-1:ENDPROC
 4890 VDU3:printer=0:ENDPROC
 4900 PRINTFN_STREAM(0);:FOR L=0TO15:PRINT;~L;CHR$8;CHR$10;str$(L);CHR$9;CHR$11;:NEXT:PRINT'':ENDPROC
 4910 PROC_STRM
 4920 VL=FN_GETDEC:IF VL=-1 THEN ENDPROC
 4930 VDUVL:GOTO4920
 4940 DATA CHAIN,<afsp>,DEFWINDOW,<window> <left> <bottom> <right> <top>,MODE,<mode>,PLOAD,<afsp>,PRINTON,,PRINTOFF,,VDU,(#<strm>) <ascii> ...,TIME,(<time>),STREAMS,
 4950 NM1=FN_GETDEC:NM2=FN_GETDEC:NM3=FN_GETDEC:NM4=FN_GETDEC:NM5=FN_GETDEC:IF (NM1 OR NM2 OR NM3 OR NM4 OR NM5)<0 THEN GOTO 2080
 4960 PROC_DWIND(NM1,NM2,NM3,NM4,NM5):ENDPROC
 4970 VL=FN_GETDEC:VL1=FN_GETDEC:IF (VL OR VL1)<0 THEN GOTO4990
 4980 TIME=360000*VL+6000*VL1
 4990 PRINTFN_STREAM(0);"The time is ";TIME DIV 360000;":";TIME DIV 6000 MOD 60:ENDPROC
 5000 RESTORE 5030:HL1=HL:VL=FN_TLK2(16,1,1):HL=HL1:IF FN_GetChar=13OR VL>-1 THEN PRINT'"Extra Utilities 1.00"
 5010 IF VL=-1 THEN GOTO5040
 5020 RESTORE 4940:MAX=9:PROC_HLP(16):HL=HL1
 5030 DATA EXTRA
 5040 IF FN_GetChar=13 THENGOTO5050
 5050 IFMID$(A$,HL,1)="."THENENDPROC
 5060 RESTORE 5080:HL1=HL:VL=FN_TLK2(16,1,1):HL=HL1:IF VL=-1THENGOTO5100
 5070 PRINT'"*FX calls:":MAX=8:PROC_HLP(16)
 5080 DATA FX,*FX0,Returns OS version,*FX13,Set windows for streams 0-2,*FX101,Reports last error
 5090 DATA *FX250,Sets control bits as follows:,"  1",BBC/Amstrad cursor key operation,"  2",No BEEP on errors,"  4",No BEEP on editing errors,"  8",QL-type/Ordinary screen in mode 7
 5100 RESTORE5130:HL1=HL:VL=FN_TLK2(16,1,1):HL=HL1:IF VL=-1THEN ENDPROC
 5110 PRINT'"Acknowledgements to:":MAX=4:PROC_HLP(16)
 5120 ENDPROC
 5130 DATA ACKNOW,Greg,Heslington,Chris,Gooch,Jonathan,Murphy,Steve,Oxley