10 REM >HADFS0 v5.78
   20 REM Source for HADFS ROM
   30 REM v5.60 Pre-release of version 6.00
   40 REM v5.61 *Rename works in BigDirs, bugfix missing TYA in OSGBPB
   50 REM       Deleting extended dirs, delete (notfound) works, OSGBPB PTR>16M
   60 REM v5.62 Modification time, OSFILE &FC
   70 REM v5.63 Channel buffers can be in Hazel workspace
   80 REM       Workspace compacted and tidied up into consistant blocks
   90 REM       GetDir copies header into absolute workspace for later access
  100 REM v5.64 Updated vramSelect code
  110 REM v5.65 Rearranging dirInit/dirNext/dirSize code, Serv7 returns correct value
  120 REM       Final version that has optional code for _NotHazel%, _IDE16%, OldVRAM%
  130 REM v5.66 Removed all optional code for _NotHazel%, _IDE16%, OldVRAM%, WS=&1000
  140 REM       ReadInfo($), CDIR, Rename, Install uses offset to DIR
  150 REM v5.67 Directory buffer relocatable
  160 REM v5.68 Consistant 4-byte sector addresses in directories, CMOS byte holds DRVINT
  170 REM v5.69 Tidied up disk access, 8x4G IDE drives accessible, *opt4,8+n, bugfix reading
  180 REM       PRIV in GBPB
  190 REM v5.70 DoIOwn checks aux account, *Account sets aux account, System !Boot does Electron ROMs
  200 REM       For Electron, DrvIDE checks &FC for absence, DrvFlop check returned result for absence
  210 REM       OSFILE &FC calls GetSectAddr to ensure correct directory loaded
  220 REM       *Rename samename samename doesn't give 'File exists' error
  230 REM       Need to do: better MOS 3.50/DFS 2.4x interaction, tweek Electron System !Boot
  240 REM v5.71 *HADFS checks for Master 3.50 DFS, DrvFloppy enables Master 3.50 DFS when calling
  250 REM       Optimised some disk access code, tweeked IDE error translation, System !Boot works on
  260 REM       Electron
  270 REM v5.72 H-Break clears keypress, shadow select works on BBC again
  280 REM v5.73 GoMMC driver disabled if DFS 0.90 to avoid DFS 0.90 OSWORD bug
  290 REM v5.74 IDE driver copes with device missing on Compact where empty I/O gives random values
  300 REM       OPTFLG set with DFS 2.45 on any Master series
  310 REM v5.75 Workaround for MOS5+NetFS RTC bug - just drops out with an error
  320 REM v5.76 FindFreeSpace prioritises finding exact match so to shrink FSM
  330 REM v5.77 MOS5+NetFS RTC bug bypassed by reading SoftRTC if on MOS5
  340 REM v5.78 Extending zero-length files works, :name -> $.name
  350 REM v6.00 Release version
  360 :
  370 ver$="5.60":date$=" (31 Dec 2011)"
  380 ver$="5.61":date$=" (12 Jan 2012)"
  390 ver$="5.62":date$=" (17 Feb 2012)"
  400 ver$="5.63":date$=" (10 Mar 2012)"
  410 ver$="5.64":date$=" (17 Mar 2012)"
  420 ver$="5.65":date$=" (18 Mar 2012)"
  430 ver$="5.66":date$=" (20 Mar 2012)"
  440 ver$="5.67":date$=" (22 Mar 2012)"
  450 ver$="5.68":date$=" (23 Mar 2012)"
  460 ver$="5.69":date$=" (24 Mar 2012)"
  470 ver$="5.70":date$=" (24 Mar 2012)"
  480 ver$="5.71":date$=" (03 Apr 2012)"
  490 ver$="5.72":date$=" (08 Apr 2012)"
  500 ver$="5.73":date$=" (11 Apr 2012)"
  510 ver$="5.74":date$=" (14 Apr 2012)"
  520 ver$="5.75":date$=" (15 Apr 2012)"
  530 ver$="5.76":date$=" (25 Jan 2016)"
  540 ver$="5.77":date$=" (22 Nov 2016)"
  550 ver$="5.78":date$=" (16 Oct 2018)"
  560 ver$="5.79":date$=" (22 Oct 2018)"
  570 base$=ver$
  580 ver$="6.00":date$=" (20 Apr 2012)"
  590 ver$="6.10":date$=" (16 Oct 2018)"
  600 :
  610 IF?&20F<&80 AND ?&20F>&D PRINT"VDU redirected!!":CLOSE#0:END
  620 :
  630 REM OS Entries
  640  oscli=&FFF7:OSBYTE=&FFF4:OSWORD=&FFF1
  650 OSWRCH=&FFEE:OSNEWL=&FFE7:OSASCI=&FFE3
  660 OSRDCH=&FFE0:OSFILE=&FFDD:OSFIND=&FFCE
  670 OSARGS=&FFDA:GSINIT=&FFC2:GSREAD=&FFC5
  680 OSRDRM=&FFB9:WHATOS=OSFILE+2
  690 :
  700 REM OS Vectors
  710 FILEV=&212:XFILEV=&DBA:FSCV=&21E
  720 :
  730 REM Initialise absent config variables:
  740 _NoInsHlp%=_NoInsHlp%:_NoFormat%=_NoFormat%
  750 _NoStatus%=_NoStatus%:_OmitCopy%=_OmitCopy%
  760 _NoMMCDrv%=_NoMMCDrv%:_NoIDEDrv%=_NoIDEDrv%
  770 _NoNullKB%=_NoNullKB%:_NoSftRTC%=_NoSftRTC%
  780 _NoGBAddr%=_NoGBAddr%:_NetRTCBug%=_NetRTCBug%
  790 _Debug%=_Debug%
  800 :
  810 IF _Debug%:_OmitCopy%=TRUE
  820 :
  830 REM Extended info offsets:
  840 md=&1A:mt=&1C:cd=&1E:us=&19
  850 :
  860 REM workspace variables base, moved to avoid clashing with OSWORD &7F:
  870 WS=&0E00
  880 :
  890 REM workspace variables, offset from WS, rearranged for 24-bit disks:
  900 DSKNAME=WS+0:DIRNAME=WS+&10:LIBNAME=WS+&1A:OBJECT=WS+&24
  910 CSD=WS+&70
  920 LIB=CSD+4:URD=LIB+4:USERNUM=URD+4
  930 OswB0=WS+&30
  940 Dosw90=OswB0+4:Daddr=OswB0+6
  950 Ddrv=Daddr-1:Dcmd=Daddr+5:Dtrk=Daddr+6
  960 Dsec=Daddr+7:Dnum=Daddr+8:Dres=Daddr+9
  970 :
  980 FSM=&0F00:DIR=&0000:HDR=WS+&50:REM DIR dynamically at &1100 or &C300
  990 OPTNUM=USERNUM+1:PRIV=OPTNUM:OPTFLG=OPTNUM+1
 1000 CURR=USERNUM+4:ENABLE=OPTFLG+1
 1010 CHNINFO=WS+&88:CHN26=WS+&D0:CHN25=WS+&E8
 1020 VFLG=CURR+4
 1030 DRVTMP=VFLG+1:DRVINT=VFLG+2:DRVEXT=DRVINT+1
 1040 Ctrl=OswB0+&12
 1050 myfs=2:auxfs=myfs+1:REM (ws) offsets, same as *opt number
 1060 d=3:REM d=offset to drive byte
 1070 :
 1080 REM Zero page variables:
 1090 zp0=&C0
 1100 blk=zp0+4:start=zp0+6:len=zp0+9:buf=zp0+12:cptr=zp0+14
 1110 :
 1120 zp1=&B0
 1130 addr=zp1+0:sect=zp1+4:drive=sect+3:num=zp1+8:action=zp1+9
 1140 shadow=zp1+10:catex=zp1+11:argnum=zp1+12:files=zp1+13:fptr=zp1+14
 1150 numflg=zp1+11:numsub=zp1+12:numstore=zp1+16:ptrstore=numstore
 1160 ret=numstore+0:index=numstore+1:fcnt=numstore+2:attrc=fcnt:attrs=numstore+3
 1170 pathflg=argnum:argchn=argnum:pathabs=len+0
 1180 ws=addr:tptr=ws:tmp=ws+2:argtmp=buf
 1190 :
 1200 REM Other variables:
 1210 progID=6:HADFSnum=16:able%=&6FF9:REM abilities
 1220 IF _OmitCopy%    :able%=able%ANDNOT&0001
 1230 REM IF _NoInstal%:able%=able%ANDNOT&0020
 1240 IF WS=&E00       :able%=able%ANDNOT&0200
 1250 IF CHNINFO>WS+&7F:able%=able%ANDNOT&0100
 1260 REM IF _SmallFSM%:able%=able%ANDNOT&2000
 1270 REM IF _SmallDIR%:able%=able%ANDNOT&2000
 1280 IF _NoIDEDrv%    :able%=able%ANDNOT&4000
 1290 :
 1300 REM Tweek this line if running out of memory for variables:
 1310 mcode%=TOP+&53FE+64*5:HIMEM=mcode%
 1320 Block%=&8000:VDU15
 1330 :
 1340 M%=&7C00:IFL%>&7BFF:VDU22,7,28,0,24,39,15:M%=&7E58:$(M%-40)=STRING$(40,"`"):CLS:PRINT"Writing over screen."
 1350 PRINT"mcode%=&";~HIMEM;" ";:IF HIMEM>&3C00:PRINT"Room for ";(&7F00-HIMEM);" bytes" ELSE PRINT
 1360 PRINT "Assembling S.HADFS0"
 1370 O%=mcode%:P%=Block%
 1380 [OPT0
 1390 \ ==========
 1400 \ ROM HEADER
 1410 \ ==========
 1420 RTS:EQUW DriveDispatch            :\ Pointer to drive dispatch table
 1430 \JMP Service                      :\ Service routine entry point
 1440 JMP Dummy1                        :\ Service routine entry point
 1450 EQUB &82:EQUB Copyright-&8000
 1460 EQUB VAL LEFT$(ver$,3)
 1470 EQUS "HADFS":BRK:EQUS ver$+date$
 1480 \BRK:\EQUW DummyHeader-2          :\ Point to dummy module headers
 1490 .Copyright
 1500 BRK:EQUS "(C)J.G.Harston":BRK     :\ Date is in date string
 1510 :
 1520 \ ================
 1530 \ SERVICE ROUTINES
 1540 \ ================
 1550 .Service
 1560 .z%
 1570 CMP #&01:BNE P%+5:JSR KeyboardChk :\ Check if keyboard absent
 1580 :]:IF _NoNullKB%:z%=P%-z%:P%=P%-z%:O%=O%-z%
 1590 CMP #&07:BEQ ServOk               :\ Bypass disable check for OSBYTE
 1600 PHA:LDA &DF0,X:BMI P%+4:EOR #&40  :\ %11*->%11*, %10*->%10*, %01*->%00*, %00*->%01*
 1610                                   :\   enabled    disabled    disabled    enabled
 1620 ASL A:BPL ServOff:PLA
 1630 .ServOk
 1640 \CMP #&02:\BNE P%+5:\JSR TimeRestr:\ Restoring TIME could be called here
 1650 CMP #&0F:BCS P%+5:JSR TimeSave    :\ Preserve TIME over Ctrl-Break
 1660 CMP #&12:BNE P%+5:JMP Serv12      :\ Select filing system
 1670 CMP #&0B:BCC ServCall
 1680 CMP #&21:BCC ServExit             :\ Master-specific calls &21-&29
 1690 CMP #&2A:BCS ServExit:SEC         :\ Reduce offset for Master calls
 1700 .ServCall
 1710 TAX:LDA ws:PHA:LDA ws+1:PHA:LDA tmp:PHA  :\ Preserve &B0/1/2
 1720 TXA:JSR ServJump                         :\ Call with A=service number, CS=Master call
 1730 TAX:PLA:STA tmp:PLA:STA ws+1:PLA:STA ws  :\ Restore &B0/1/2
 1740 TXA:PHA                                  :\ A=claimed/unclaimed, X is restored by MOS
 1750 .ServOff
 1760 PLA
 1770 .ServExit
 1780 \ ------------------------
 1790 \ SERVICE 0 - NULL SERVICE
 1800 \ ------------------------
 1810 .Serv0:.Serv23
 1820 RTS
 1830 :
 1840 .ServJump
 1850 PHA:BCC P%+4:SBC #&16             :\ Reduce offset for Master calls
 1860 ASL A:TAX                         :\ X=offset to entry
 1870 LDA ServTable+0,X:STA ws+0        :\ Get routine address
 1880 LDA ServTable+1,X:STA ws+1
 1890 LDX &F4:PLA                       :\ Restore ROM and call number
 1900 .JumpWS
 1910 JMP (ws)                          :\ Jump to routine
 1920 :
 1930 .ServTable
 1940 EQUW Serv0:EQUW Serv1:EQUW Serv2:EQUW Serv3
 1950 EQUW Serv4:EQUW Serv0:EQUW Serv0:EQUW Serv7
 1960 EQUW Serv8:EQUW Serv9:EQUW ServA
 1970 EQUW Serv21:EQUW Serv22:EQUW Serv23:EQUW Serv24
 1980 EQUW Serv25:EQUW Serv26:EQUW Serv27:EQUW Serv28
 1990 EQUW Serv29
 2000 :
 2010 \ ---------------------------------------------------
 2020 \ SERVICE &24 - State how much Hazel workspace needed
 2030 \ ---------------------------------------------------
 2040 .Serv24
 2050 DEY:RTS                           :\ Need one page of private workspace
 2060 :
 2070 \ --------------------------------------------
 2080 \ SERVICE &21 - Claim Hazel absolute workspace
 2090 \ --------------------------------------------
 2100 .Serv21
 2110 CPY #&C9:BCS P%+4:LDY #&C9:RTS    :\ Need at least nine pages of shared workspace
 2120 :
 2130 \ -------------------------------------------
 2140 \ SERVICE &22 - Claim Hazel private workspace
 2150 \ -------------------------------------------
 2160 .Serv22
 2170 CPY #&DC:BCC P%+4:LDY #&DC        :\ If run out of Hazel, point to top of Hazel
 2180 LDA #&20:JSR MskDF0               :\ Preserve ownership flag
 2190 TYA:JSR SetDF0                    :\ Note location of private workspace, preserving ownership flag
 2200 INY:LDA #&22:RTS                  :\ Claim one page of workspace
 2210 :
 2220 \ -----------------------------------------
 2230 \ SERVICE 1 - STATE ABSOLUTE WORKSPACE SIZE
 2240 \ -----------------------------------------
 2250 .Serv1
 2260 .z%
 2270 CPY #&14:BCS P%+4:LDY #&14        :\ Master needs six pages of shared low workspace
 2280 :]:IF DIR=0:z%=P%-z%:P%=P%-z%:O%=O%-z%
 2290 .z%
 2300 CPY #&10:BCS P%+4:LDY #&10        :\ Master needs two pages of shared low workspace
 2310 :]:IF DIR<>0:z%=P%-z%:P%=P%-z%:O%=O%-z%
 2320 .z%
 2330 JSR WhatMOS:BCC Serv1Exit
 2340 :]:IF VALbase$>=5.79:z%=P%-z%:P%=P%-z%:O%=O%-z%
 2350 .z%
 2360 BIT WHATOS:BMI Serv1Exit
 2370 :]:IF VALbase$<5.79:z%=P%-z%:P%=P%-z%:O%=O%-z%
 2380 CPY #&17:BCS P%+4:LDY #&17        :\ BBC needs nine pages of shared low workspace
 2390 .Serv1Exit
 2400 LDX &F4:LDA #1:RTS                :\ Restore X and A and exit
 2410 :
 2420 \ ------------------------------------
 2430 \ SERVICE 2 - CLAIM RELATIVE WORKSPACE
 2440 \ ------------------------------------
 2450 .Serv2
 2460 LDA &28D:BEQ Serv2a               :\ Restore TIME if not Soft-Break
 2470 PHP:SEI:LDX #3                    :\ Disable IRQs
 2480 .Serv2Lp1
 2490 LDA &3D9,X:STA &293,X:STA &298,X  :\ Restore TIME from backup
 2500 DEX:BNE Serv2Lp1:LDX &F4:PLP      :\ Restore IRQs
 2510 .Serv2a
 2520 .z%
 2530 JSR WhatMOS:BCS Serv2BBC          :\ Claim low workspace on BBC
 2540 :]:IF VALbase$>=5.79:z%=P%-z%:P%=P%-z%:O%=O%-z%
 2550 .z%
 2560 BIT WHATOS:BPL Serv2BBC           :\ Claim low workspace on BBC
 2570 :]:IF VALbase$<5.79:z%=P%-z%:P%=P%-z%:O%=O%-z%
 2580 LDA &DF0,X:AND #&DF               :\ Get ws pointer without ownership flag
 2590 CMP #&DC:BCC Serv2d               :\ If haven't run out of Hazel, use it
 2600 .Serv2BBC
 2610 LDA #&20:JSR MskDF0               :\ Preserve ownership flag
 2620 TYA:SEC:SBC #&0E                  :\ Convert to offset from page &0E
 2630 JSR SetDF0                        :\ Note location of private workspace, keeping ownership flag
 2640 INY                               :\ Use one page of low workspace
 2650 .Serv2d
 2660 TYA:PHA:JSR FindWS                :\ ws=>private workspace
 2670 LDA &28D:CMP #2:PHP:JSR ServAgo   :\ Copy info into private w/s if I own shared workspace
 2680 :
 2690 \\ This now moved to *HADFS
 2700 \\LDY #OPTFLG AND &FF
 2710 \\LDA (ws),Y:\AND #&6F            :\ Clear MOS 3.50 and NoDFS flags
 2720 \\JSR ChkMOS350:\BNE Serv2e       :\ Check for "MOS 3.50" string
 2730 \\ORA #&80                        :\ Set MOS 3.50 flag
 2740 \\.Serv2e
 2750 \\STA (ws),Y                      :\ Update OPTFLG
 2760 :
 2770 PLP:BCC Serv2Exit                 :\ Exit if not Ctrl-Break
 2780 LDA #0:LDY #CHNINFO AND 255       :\ Clear channel info if Ctrl-Break
 2790 .Serv2Lp2
 2800 STA (ws),Y:INY:BNE Serv2Lp2
 2810 JSR ReadCMOS:TYA                  :\ Get my CMOS byte, using Y=&00 as default
 2820 LDY #DRVINT AND 255:STA (ws),Y    :\ Store as default DRVINT
 2830 .Serv2Exit
 2840 JSR ClrOwnWS                      :\ I don't own workspace
 2850 PLA:TAY:LDA #2:RTS                :\ Restore and exit
 2860 :
 2870 .GetOwnWS:JSR GetDF0_F4:AND #&20:RTS :\ Get ownership flag
 2880 .SetOwnWS:LDA #&20:BNE SetDF0_F4     :\ Set ownership flag
 2890 .ClrOwnWS:LDA #&DF                   :\ Clear ownership flag
 2900 :
 2910 .MskDF0_F4:LDX &F4
 2920 .MskDF0   :AND &DF0,X:JMP PutDF0
 2930 .GetDF0_F4:LDA #0
 2940 .SetDF0_F4:LDX &F4
 2950 .SetDF0   :ORA &DF0,X
 2960 .PutDF0   :STA &DF0,X:RTS
 2970 :
 2980 \ Keep bits from OPTFLG in Y, merge in bits from A
 2990 \ ------------------------------------------------
 3000 .MaskIntoOPTFLG
 3010 PHA:TYA:JSR MaskOPTFLG:PLA
 3020 .IntoOPTFLG
 3030 ORA OPTFLG:STA OPTFLG:RTS
 3040 .MaskOPTFLG
 3050 AND OPTFLG:STA OPTFLG:RTS
 3060 :
 3070 \ ------------------------------
 3080 \ SERVICE 3 - BOOT FILING SYSTEM
 3090 \ ------------------------------
 3100 .Serv3
 3110 TYA:PHA:LDA #&7A:JSR OSBYTE       :\ Scan for keypress
 3120 TXA:BMI Serv3Init2                :\ No key pressed
 3130 CMP #&54:BNE Serv3Exit            :\ 'H' pressed, select HADFS
 3140 :
 3150 \ Allow Ctrl-Caps-H-Break to disable:
 3160 \\LDX #&BF:\CMP #&54:\BEQ Srv3Key     :\ 'H' pressed, X=check for CapsLock
 3170 \\LDX #&AB:\CMP #&40:\BNE Srv3Exit    :\ 'CapsLock' pressed, X=check for H
 3180 \\.Srv3Key
 3190 \\PHA:\LDA #&81:\LDY #&FF:\JSR OSBYTE :\ Check for other key pressed
 3200 \\PLA:\INX:\BEQ Srv3Disable           :\ 'H'+'CapsLock'
 3210 \\CMP #&54:\BEQ Srv3Init              :\ 'H-Break'
 3220 \\.Srv3Disable
 3230 \\LDA &28D:\BEQ Srv3Exit              :\ Not Ctrl-Break
 3240 \\.RomDisable
 3250 \\SEC:\JSR RomEnable
 3260 \\JSR PrText
 3270 \\EQUS "Press CTRL-BREAK":\BRK:\JMP P%
 3280 \\.Serv3Init1
 3290 \\TXA:\LDA #&78:\JSR OSBYTE           :\ Clear keypressed info
 3300 :
 3310 LDA #&78:JSR OSBYTE               :\ Clear keypressed info
 3320 PLA:.Serv3Setup:PHA               :\ Enter here from *FX90
 3330 .Serv3Init2
 3340 JSR PrTitle2:JSR fx143go
 3350 JSR CheckClock1:BEQ srv3clkOk
 3360 JSR PrText:EQUS " No date":BRK
 3370 .srv3clkOk
 3380 JSR Pr2Newl
 3390 PLA:BNE Serv3NoBoot
 3400 LDX #BootTab AND 255:LDY #BootTab DIV 256
 3410 JSR I_AmXY
 3420 .Serv3NoBoot
 3430 LDA #0:RTS
 3440 .Serv3Exit
 3450 PLA:TAY:LDA #3:RTS
 3460 .BootTab
 3470 EQUS "BOOT":EQUB 13
 3480 :
 3490 \ ----------------------
 3500 \ SERVICE 4 - * COMMANDS
 3510 \ ----------------------
 3520 .Serv4
 3530 LDX #OsTable1-CommTable
 3540 .Serv4Try
 3550 TXA:PHA:JSR SearchTable
 3560 BNE Srv4Go
 3570 PLA:TAX:LDA (&F2),Y:AND #&DF
 3580 CMP #ASC"H":BNE Srv4No
 3590 INY:JSR SearchTable
 3600 BNE Srv4Go2
 3610 DEY
 3620 .Srv4No
 3630 LDA #4:RTS
 3640 .Srv4Go
 3650 PLA
 3660 .Srv4Go2
 3670 JSR JumpWS:LDA #0:RTS
 3680 :
 3690 \ ------------------
 3700 \ SERVICE 7 - OSBYTE
 3710 \ ------------------
 3720 .Serv7
 3730 PHA:LDA &EF:CMP #90:BNE Srv7Off
 3740 LDA &F0:BEQ Srv7info
 3750 CMP #progID:BNE Srv7Off
 3760 \ *FX90,6,n
 3770 LDA &DF0,X:TAY             :\ Y=old DF0,X value
 3780 LDA &F1:BMI Srv7rd         :\ *FX90,6,128+ - read
 3790 CMP #&40:BCS Srv7Off       :\ *FX90,6,64+ - context calls
 3800 CMP #4:BCS Srv7rd          :\ *FX90,6,4+ - unused
 3810 CMP #1:BEQ Srv7off         :\ *FX90,6,1 - disable
 3820 CLC:JSR RomEnable          :\ CC, enable ROM
 3830 BEQ Srv7rd                 :\ *FX90,6,0 - enable
 3840 SBC #2:JSR Serv3Setup      :\ A is now 0
 3850 TAY:BEQ Srv7ok
 3860 .Srv7off
 3870 JSR RomEnable              :\ CS, disable ROM
 3880 .Srv7rd
 3890 TYA       :\ 00xx  01xx  10xx  11xx
 3900 EOR #&40  :\ 01xx  00xx  11xx  10xx
 3910 CMP #&40  :\  CS    CC    CS    CS
 3920 BCS P%+4  :\  vv          vv    vv
 3930 ADC #&C1  :\       11xx
 3940 SBC #&40  :\ 00xx  10xx  10xx  01xx
 3950 STA &F0
 3960 .Srv7ok
 3970 PLA:LDA #0:RTS
 3980 :
 3990 .Srv7info:\ *FX90 help routine
 4000 LDA &F1:BEQ Srv7hlp
 4010 CMP #1:BNE Srv7Off:JSR PrText
 4020 EQUS STR$ progID+": ":BRK
 4030 JSR PrTitle:JMP Srv7Off
 4040 .Srv7hlp
 4050 TAX:LDY #1:JSR Osbyte90:JMP Srv7ok
 4060 :
 4070 .Srv7Off:PLA:RTS
 4080 :
 4090 .RomEnable
 4100 \ CC=Enable ROM, CS=Disable ROM
 4110 LDX &F4
 4120 PHA:LDA &DF0,X:PHA:AND #&BF:STA &DF0,X
 4130 PLA:BCC P%+4:EOR #&80:LSR A:AND #&40
 4140 JSR SetDF0:PLA:RTS
 4150 :
 4160 \ ------------------
 4170 \ SERVICE 8 - OSWORD
 4180 \ ------------------
 4190 .Serv8
 4200 LDA &EF
 4210 CMP #14:BNE P%+5:JMP Osword14     :\ OSWORD 14 - Read RTC
 4220 \CMP #15:\BNE P%+5:\JMP Osword15  :\ OSWORD 15 - Write RTC
 4230 CMP #90:BNE P%+5:JMP Osword90     :\ OSWORD 90 - Read/Write sectors
 4240 LDA #8:RTS
 4250 :
 4260 \ ------------------------------
 4270 \ SERVICE 10 - Release workspace
 4280 \ ------------------------------
 4290 .ServA
 4300 CLC:.ServAgo
 4310 JSR GetOwnWS:BEQ SrvAExit         :\ I don't own, so ignore
 4320 BCS P%+5:JSR args0_FF             :\ Update buffers if not Ctrl-Break
 4330 \.SrvAgo2
 4340 JSR ClrOwnWS:JSR FindWS           :\ Clear ownership flag
 4350 LDY #CSD AND 255                  :\ Copy context and channel info to workspace
 4360 .SrvAlp
 4370 LDA WS,Y:STA (ws),Y:INY:BNE SrvAlp:\ Save workspace after fsnums
 4380 .SrvAExit
 4390 LDA #&A:RTS
 4400 :
 4410 \ ----------------------------------
 4420 \ SERVICE &12 - SELECT FILING SYSTEM
 4430 \ ----------------------------------
 4440 .Serv12
 4450 CPY #HADFSnum:BEQ Srv12Init
 4460 TYA:CMP #5:BCC Srv12not
 4470 JSR FindWS:LDY #myfs
 4480 CMP (ws),Y:BEQ Srv12Init
 4490 INY:CMP (ws),Y:BEQ Srv12Init
 4500 .Srv12not
 4510 TAY:LDA #&12:RTS
 4520 .Srv12Init
 4530 JMP HadfsOn:\ Returns with A=0
 4540 :
 4550 \ ---------------------------------------
 4560 \ SERVICE &25 - RETURN FILING SYSTEM INFO
 4570 \ ---------------------------------------
 4580 .Serv25
 4590 LDX #0:.Srv25lp
 4600 LDA Srv25tb,X:STA (&F2),Y
 4610 INX:INY:CPX #11:BNE Srv25lp
 4620 LDA #&25:RTS
 4630 .Srv25tb
 4640 EQUS "HADFS   ":EQUB 25:EQUB 29
 4650 EQUB HADFSnum
 4660 :
 4670 \ -------------------
 4680 \ SERVICE &26 - *SHUT
 4690 \ -------------------
 4700 .Serv26
 4710 JSR EnsureHADFS:PHA        :\ Select HADFS if not already
 4720 JSR Close                  :\ Close all files
 4730 PLA:JSR RestoreFS:LDA #&26 :\ Restore filing system
 4740 :
 4750 .Serv27:\ RESET
 4760 .Serv28:\ *CONFIGURE
 4770 RTS
 4780 :
 4790 \ ----------------------------
 4800 \ SERVICE &29 - DISPLAY STATUS
 4810 \ ----------------------------
 4820 \ Need to change status output, possible:
 4830 \ *Status HADFS        *Status HADFS                      *Status HADFS
 4840 \ Date     Unset       Date     Thu,28 Mar 2013.22-30-00  HADFS    02 86 Thu,28 Mar....
 4850 \ Channels 5           Channels 4
 4860 \ Drives   IIEEEIIE    Drives   IIIIIIII
 4870 \
 4880 .Serv29
 4890 TAX:TYA:PHA                        :\ Save command offset
 4900 JSR GetChar:BEQ Srv29a             :\ <cr> - display status
 4910 CMP #ASC".":BEQ Srv29a             :\ '.' - display status
 4920 AND #&DF:CMP #ASC"H":BNE Serv29Exit:\ Not 'H', exit
 4930 LDX #0                             :\ Claim *STATUS call
 4940 .Srv29a                            :\ Should really check for 'HADFS'
 4950 TXA:PHA:LDX #0                     :\ Save claimed/unclaimed
 4960 .Srv29b
 4970 LDA Srv25tb,X:JSR OSWRCH:INX       :\ Print "HADFS    "
 4980 CPX #8:BNE Srv29b:JSR OSWRCH
 4990 LDA OPTFLG:PHA:LDA DRVINT:PHA      :\ Get flags
 5000 JSR GetOwnWS:BNE Srv29c            :\ I own WS, so use stacked values
 5010 PLA:PLA:JSR FindWS                 :\ Look for my workspace
 5020 LDY #OPTFLG AND 255:LDA (ws),Y:PHA :\ Get flags from workspace
 5030 LDY #DRVINT AND 255:LDA (ws),Y:PHA :\ Get flags from workspace
 5040 .Srv29c
 5050 PLA:JSR PrHex:JSR PrSpace          :\ Print flags
 5060 PLA:JSR PrHex:JSR PrSpace          :\ Print flags
 5070 JSR Time:BNE Serv29Exit:JSR OSNEWL :\ Print RTC
 5080 .Serv29Exit
 5090 PLA:TAX:PLA:TAY:TXA                :\ Restore Y, claim or pass on
 5100 :]:IF _NoStatus%:z%=P%-Serv29:P%=P%-z%:O%=O%-z%
 5110 RTS
 5120 :
 5130 .PrTitle1
 5140 JSR OSNEWL
 5150 .PrTitle
 5160 JSR PrTitle2:JSR PrText
 5170 EQUS " "+ver$:EQUB 13:BRK
 5180 RTS
 5190 .PrTitle2
 5200 JSR PrText:EQUS "Harston ADFS":BRK
 5210 RTS
 5220 :
 5230 \ --------------------------
 5240 \ SERVICE &09 - DISPLAY HELP
 5250 \ --------------------------
 5260 .Serv9
 5270 TYA:PHA:LDX #HelpTable-CommTable
 5280 JSR GetChar:BNE Srv9b
 5290 LDY #NullText-TextTable
 5300 .Srv9a
 5310 JSR DispHelp2
 5320 .Srv9Exit
 5330 PLA:TAY:LDA #9
 5340 RTS
 5350 :
 5360 .Srv9b
 5370 JSR SearchTable:BEQ Srv9Exit
 5380 JSR DispHelp1
 5390 PLA:TAY:LDA (&F2),Y
 5400 CMP #ASC".":BNE Srv9claim
 5410 TYA:PHA
 5420 LDX #OsTable2-CommTable
 5430 LDY #OsText-TextTable
 5440 BNE Srv9a
 5450 .Srv9claim
 5460 LDA #9:RTS
 5470 :
 5480 .DispHelp1
 5490 LDX ws:LDY ws+1
 5500 .DispHelp2
 5510 JSR PrTitle1
 5520 :
 5530 \ X points to comm table
 5540 \ Y points to text table
 5550 .HelpLp1
 5560 JSR Pr2Space:JSR HelpLp2
 5570 INY:INX:INX
 5580 LDA CommTable,X:BNE HelpLp1
 5590 RTS
 5600 :
 5610 .HelpLp2
 5620 LDA CommTable,X:INX
 5630 CMP #ASC"`":BCS HelpWord
 5640 JSR OSWRCH:JMP HelpLp2
 5650 .HelpWord
 5660 AND #&DF:JSR OSWRCH
 5670 JSR PrSpace
 5680 .HelpLp3
 5690 LDA TextTable,Y:BMI HelpTextEnd
 5700 JSR OSWRCH:INY:BNE HelpLp3
 5710 .HelpTextEnd
 5720 AND #&7F:JSR OSWRCH:JMP OSNEWL
 5730 :
 5740 \ X points to table start
 5750 \ Y points to text string
 5760 .SearchTable
 5770 TYA:PHA
 5780 .TableLp
 5790 LDA (&F2),Y
 5800 CMP #ASC".":BEQ TableDot
 5810 CMP CommTable,X:BEQ TableChar
 5820 CMP #ASC"@":BCC TableNxt
 5830 EOR #32
 5840 CMP CommTable,X:BEQ TableChar
 5850 .TableNxt
 5860 JSR TableSkip
 5870 .TableNxt2
 5880 INX:INX:PLA:TAY
 5890 LDA CommTable,X:BNE SearchTable
 5900 \ end of table
 5910 \ Y=ok, A=0
 5920 RTS
 5930 :
 5940 .TableChar
 5950 INX:INY:LDA CommTable-1,X
 5960 CMP #ASC"`":BCC TableLp
 5970 LDA (&F2),Y:AND #&DF
 5980 CMP #ASC"Z"+1:BCS TableFound
 5990 CMP #ASC"A":BCS TableNxt2
 6000 BCC TableFound
 6010 .TableDot
 6020 JSR TableSkip:INY
 6030 .TableFound
 6040 LDA CommTable+0,X:STA ws+0
 6050 LDA CommTable+1,X:STA ws+1
 6060 PLA:JSR SkipSpc:LDA #&FF
 6070 RTS:\ found
 6080 :
 6090 .TableSkip
 6100 LDA CommTable,X:INX
 6110 CMP #ASC"`":BCC TableSkip
 6120 RTS
 6130 :
 6140 :
 6150 \                       Tables
 6160 .CommTable
 6170 .HelpTable
 6180 EQUS "HADFs":EQUB FileTable-CommTable:EQUB FileText-TextTable
 6190 EQUS "UTILs":EQUB OsTable2-CommTable:EQUB OsText-TextTable
 6200 BRK
 6210 :
 6220 .OsTable1
 6230 EQUS "STATUs":EQUW Status
 6240 EQUS "CONFIGURe":EQUW Config
 6250 :]:IF _NoStatus%:z%=P%-OsTable1:P%=P%-z%:O%=O%-z%
 6260 EQUS "SHUt":EQUW Shut
 6270 .OsTable2
 6280 EQUS "CLOSe":EQUW Close
 6290 .z%
 6300 EQUS "FORm":EQUW Form
 6310 :]:IF _NoFormat%:z%=P%-z%:P%=P%-z%:O%=O%-z%
 6320 EQUS "HADFs":EQUW Hadfs
 6330 EQUS "SETDATe":EQUW SetDate
 6340 \EQUS "SETTIMe":\EQUW SetTime
 6350 EQUS "TIMe":EQUW Time
 6360 BRK
 6370 :
 6380 .FileTable
 6390 EQUS "ACCESs":EQUW Access
 6400 EQUS "ACCOUNt":EQUW Account
 6410 EQUS "BYe":EQUW Bye
 6420 EQUS "CDIr":EQUW CDir
 6430 .z%
 6440 EQUS "COPy":EQUW Copy
 6450 :]:IF _OmitCopy%:z%=P%-z%:P%=P%-z%:O%=O%-z%
 6460 EQUS "DELETe":EQUW Delete
 6470 EQUS "DIr":EQUW Dir
 6480 EQUS "ENABLe":EQUW Enable
 6490 EQUS "Ex":EQUW Ex
 6500 EQUS "FREe":EQUW Free
 6510 EQUS "INFo":EQUW Info
 6520 .CommInstall
 6530 EQUS "INSTALl":EQUW Install
 6540 EQUS "I Am":EQUW I_Am
 6550 EQUS "LIb":EQUW Lib
 6560 EQUS "MAp":EQUW Map
 6570 EQUS "MOUNt":EQUW Mount
 6580 EQUS "RENAMe":EQUW Rename
 6590 EQUS "TITLe":EQUW Install
 6600 BRK
 6610 :
 6620 .TextTable
 6630 .NullText
 6640 .HelpText
 6650 EQUB &80:\ and the next one
 6660 .OsText:\ Mustn't be =TextTable
 6670 EQUB &80
 6680 .z%
 6690 EQUB 8:EQUS "nn <drv":EQUB ASC">"+128
 6700 :]:IF _NoFormat%:z%=P%-z%:P%=P%-z%:O%=O%-z%
 6710 EQUB &80
 6720 EQUS "(dd/mm/yy (d)":EQUB ASC")"+128
 6730 \EQUS "hh,mm,s":\EQUB "s"+128
 6740 EQUB &80
 6750 :
 6760 .FileText
 6770 EQUS "<fsp> <access":EQUB ASC">"+128
 6780 EQUS "<dir> <acc":EQUB ASC">"+128
 6790 EQUB &80
 6800 EQUS "<dir":EQUB ASC">"+128
 6810 .z%
 6820 EQUS "<src> <dest":EQUB ASC">"+128
 6830 :]:IF _OmitCopy%:z%=P%-z%:P%=P%-z%:O%=O%-z%
 6840 EQUS "<fsp":EQUB ASC">"+128
 6850 EQUS "(<dir>":EQUB ASC")"+128
 6860 EQUB &80
 6870 EQUS "(<dir>":EQUB ASC")"+128
 6880 EQUS "(<drv>":EQUB ASC")"+128
 6890 EQUS "<afsp":EQUB ASC">"+128
 6900 .HelpInstall
 6910 EQUS "(<drv> ($)) (<name>) (<size>":EQUB ASC")"+128
 6920 EQUS "<user":EQUB ASC">"+128:\ "(;/<pass>)"
 6930 EQUS "<dir":EQUB ASC">"+128
 6940 EQUS "(<drv>":EQUB ASC")"+128
 6950 EQUS "(<drv>":EQUB ASC")"+128
 6960 EQUS "<old fsp> <new fsp":EQUB ASC">"+128
 6970 EQUS "(<drv>) <name":EQUB ASC">"+128
 6980 :
 6990 :
 7000 ]
 7010 PRINT CHR$11;STRING$(20,CHR$9);O%-mcode%;" bytes"
 7020 >"S.HADFS1"