>HADFS0 v5.78  Source for HADFS ROM ' v5.60 Pre-release of version 6.00 (B v5.61 *Rename works in BigDirs, bugfix missing TYA in OSGBPB 2K Deleting extended dirs, delete (notfound) works, OSGBPB PTR>16M <) v5.62 Modification time, OSFILE &FC F5 v5.63 Channel buffers can be in Hazel workspace PD Workspace compacted and tidied up into consistant blocks ZI GetDir copies header into absolute workspace for later access d# v5.64 Updated vramSelect code nQ v5.65 Rearranging dirInit/dirNext/dirSize code, Serv7 returns correct value xR Final version that has optional code for _NotHazel%, _IDE16%, OldVRAM% Q v5.66 Removed all optional code for _NotHazel%, _IDE16%, OldVRAM%, WS=&1000 A ReadInfo($), CDIR, Rename, Install uses offset to DIR ( v5.67 Directory buffer relocatable U v5.68 Consistant 4-byte sector addresses in directories, CMOS byte holds DRVINT X v5.69 Tidied up disk access, 8x4G IDE drives accessible, *opt4,8+n, bugfix reading  PRIV in GBPB a v5.70 DoIOwn checks aux account, *Account sets aux account, System !Boot does Electron ROMs b For Electron, DrvIDE checks &FC for absence, DrvFlop check returned result for absence K OSFILE &FC calls GetSectAddr to ensure correct directory loaded F *Rename samename samename doesn't give 'File exists' error Y Need to do: better MOS 3.50/DFS 2.4x interaction, tweek Electron System !Boot ] v5.71 *HADFS checks for Master 3.50 DFS, DrvFloppy enables Master 3.50 DFS when calling a Optimised some disk access code, tweeked IDE error translation, System !Boot works on  Electron E v5.72 H-Break clears keypress, shadow select works on BBC again J v5.73 GoMMC driver disabled if DFS 0.90 to avoid DFS 0.90 OSWORD bug "_ v5.74 IDE driver copes with device missing on Compact where empty I/O gives random values ,9 OPTFLG set with DFS 2.45 on any Master series 6L v5.75 Workaround for MOS5+NetFS RTC bug - just drops out with an error @J v5.76 FindFreeSpace prioritises finding exact match so to shrink FSM JE v5.77 MOS5+NetFS RTC bug bypassed by reading SoftRTC if on MOS5 T> v5.78 Extending zero-length files works, :name -> $.name ^ v6.00 Release version h: r&ver$="5.60":date$=" (31 Dec 2011)" |&ver$="5.61":date$=" (12 Jan 2012)" &ver$="5.62":date$=" (17 Feb 2012)" &ver$="5.63":date$=" (10 Mar 2012)" &ver$="5.64":date$=" (17 Mar 2012)" &ver$="5.65":date$=" (18 Mar 2012)" &ver$="5.66":date$=" (20 Mar 2012)" &ver$="5.67":date$=" (22 Mar 2012)" &ver$="5.68":date$=" (23 Mar 2012)" &ver$="5.69":date$=" (24 Mar 2012)" &ver$="5.70":date$=" (24 Mar 2012)" &ver$="5.71":date$=" (03 Apr 2012)" &ver$="5.72":date$=" (08 Apr 2012)" &ver$="5.73":date$=" (11 Apr 2012)" &ver$="5.74":date$=" (14 Apr 2012)" &ver$="5.75":date$=" (15 Apr 2012)" &ver$="5.76":date$=" (25 Jan 2016)" &ver$="5.77":date$=" (22 Nov 2016)" &&ver$="5.78":date$=" (16 Oct 2018)" 0&ver$="5.79":date$=" (22 Oct 2018)" :base$=ver$ D&ver$="6.00":date$=" (20 Apr 2012)" N&ver$="6.10":date$=" (16 Oct 2018)" X: b3?&20F<&80 ?&20F>&D "VDU redirected!!":#0: l: v OS Entries * oscli=&FFF7:OSBYTE=&FFF4:OSWORD=&FFF1 *OSWRCH=&FFEE:OSNEWL=&FFE7:OSASCI=&FFE3 *OSRDCH=&FFE0:OSFILE=&FFDD:OSFIND=&FFCE *OSARGS=&FFDA:GSINIT=&FFC2:GSREAD=&FFC5  OSRDRM=&FFB9:WHATOS=OSFILE+2 :  OS Vectors $FILEV=&212:XFILEV=&DBA:FSCV=&21E : ) Initialise absent config variables: /_NoInsHlp%=_NoInsHlp%:_NoFormat%=_NoFormat% /_NoStatus%=_NoStatus%:_OmitCopy%=_OmitCopy% /_NoMMCDrv%=_NoMMCDrv%:_NoIDEDrv%=_NoIDEDrv% /_NoNullKB%=_NoNullKB%:_NoSftRTC%=_NoSftRTC%  1_NoGBAddr%=_NoGBAddr%:_NetRTCBug%=_NetRTCBug% _Debug%=_Debug%  : * _Debug%:_OmitCopy%= 4: > Extended info offsets: Hmd=&1A:mt=&1C:cd=&1E:us=&19 R: \H workspace variables base, moved to avoid clashing with OSWORD &7F: f WS=&0E00 p: zG workspace variables, offset from WS, rearranged for 24-bit disks: WS+&7F:able%=able%&0100 * IF _SmallFSM%:able%=able%ANDNOT&2000 * IF _SmallDIR%:able%=able%ANDNOT&2000 ' _NoIDEDrv% :able%=able%&4000  : = Tweek this line if running out of memory for variables: !mcode%=P+&53FE+64*5:=mcode% (Block%=&8000:15 2: <_M%=&7C00:L%>&7BFF:22,7,28,0,24,39,15:M%=&7E58:$(M%-40)=40,"`")::"Writing over screen." FE"mcode%=&";~;" ";: >&3C00:"Room for ";(&7F00-);" bytes" P "Assembling S.HADFS0" ZO%=mcode%:P%=Block% d [OPT0 n\ ========== x\ ROM HEADER \ ========== HRTS:EQUW DriveDispatch :\ Pointer to drive dispatch table D\JMP Service :\ Service routine entry point DJMP Dummy1 :\ Service routine entry point !EQUB &82:EQUB Copyright-&8000 EQUB ver$,3) $EQUS "HADFS":BRK:EQUS ver$+date$ F\BRK:\EQUW DummyHeader-2 :\ Point to dummy module headers .Copyright ?BRK:EQUS "(C)J.G.Harston":BRK :\ Date is in date string : \ ================ \ SERVICE ROUTINES \ ================  .Service .z% "ACMP #&01:BNE P%+5:JSR KeyboardChk :\ Check if keyboard absent ,.:]: _NoNullKB%:z%=P%-z%:P%=P%-z%:O%=O%-z% 6HCMP #&07:BEQ ServOk :\ Bypass disable check for OSBYTE @UPHA:LDA &DF0,X:BMI P%+4: #&40 :\ %11*->%11*, %10*->%10*, %01*->%00*, %00*->%01* JU :\ enabled disabled disabled enabled TASL A:BPL ServOff:PLA ^ .ServOk hI\CMP #&02:\BNE P%+5:\JSR TimeRestr:\ Restoring could be called here rCCMP #&0F:BCS P%+5:JSR TimeSave :\ Preserve over Ctrl-Break |=CMP #&12:BNE P%+5:JMP Serv12 :\ Select filing system CMP #&0B:BCC ServCall FCMP #&21:BCC ServExit :\ Master-specific calls &21-&29 GCMP #&2A:BCS ServExit:SEC :\ Reduce offset for Master calls  .ServCall @TAX:LDA ws:PHA:LDA ws+1:PHA:LDA tmp:PHA :\ Preserve &B0/1/2 ZTXA:JSR ServJump :\ Call with A=service number, CS=Master call ?TAX:PLA:STA tmp:PLA:STA ws+1:PLA:STA ws :\ Restore &B0/1/2 YTXA:PHA :\ A=claimed/unclaimed, X is restored by MOS  .ServOff PLA  .ServExit \ ------------------------ \ SERVICE 0 - NULL SERVICE \ ------------------------ .Serv0:.Serv23 RTS &: 0 .ServJump :GPHA:BCC P%+4:SBC #&16 :\ Reduce offset for Master calls D:ASL A:TAX :\ X=offset to entry NUCPY #&C9:BCS P%+4:LDY #&C9:RTS :\ Need at least nine pages of shared workspace H: R1\ ------------------------------------------- \1\ SERVICE &22 - Claim Hazel private workspace f1\ ------------------------------------------- p .Serv22 zSCPY #&DC:BCC P%+4:LDY #&DC :\ If run out of Hazel, point to top of Hazel @LDA #&20:JSR MskDF0 :\ Preserve ownership flag fTYA:JSR SetDF0 :\ Note location of private workspace, preserving ownership flag DINY:LDA #&22:RTS :\ Claim one page of workspace : /\ ----------------------------------------- -\ SERVICE 1 - STATE OLUTE WORKSPACE SIZE /\ -----------------------------------------  .Serv1 .z% WCPY #&14:BCS P%+4:LDY #&14 :\ Master needs six pages of shared low workspace ):]: DIR=0:z%=P%-z%:P%=P%-z%:O%=O%-z% .z% WCPY #&10:BCS P%+4:LDY #&10 :\ Master needs two pages of shared low workspace *:]: DIR<>0:z%=P%-z%:P%=P%-z%:O%=O%-z% .z% JSR WhatMOS:BCC Serv1Exit $0:]: base$>=5.79:z%=P%-z%:P%=P%-z%:O%=O%-z% ..z% 8BIT WHATOS:BMI Serv1Exit B/:]: base$<5.79:z%=P%-z%:P%=P%-z%:O%=O%-z% LUCPY #&17:BCS P%+4:LDY #&17 :\ BBC needs nine pages of shared low workspace V.Serv1Exit `ALDX &F4:LDA #1:RTS :\ Restore X and A and exit j: t*\ ------------------------------------ ~*\ SERVICE 2 - CLAIM RELATIVE WORKSPACE *\ ------------------------------------ .Serv2 DLDA &28D:BEQ Serv2a :\ Restore if not Soft-Break 5PHP:SEI:LDX #3 :\ Disable IRQs .Serv2Lp1 >LDA &3D9,X:STA &293,X:STA &298,X :\ Restore from backup 5DEX:BNE Serv2Lp1:LDX &F4:PLP :\ Restore IRQs .Serv2a .z% CJSR WhatMOS:BCS Serv2BBC :\ Claim low workspace on BBC 0:]: base$>=5.79:z%=P%-z%:P%=P%-z%:O%=O%-z% .z% CBIT WHATOS:BPL Serv2BBC :\ Claim low workspace on BBC /:]: base$<5.79:z%=P%-z%:P%=P%-z%:O%=O%-z% LLDA &DF0,X: #&DF :\ Get ws pointer without ownership flag LCMP #&DC:BCC Serv2d :\ If haven't run out of Hazel, use it ( .Serv2BBC 2@LDA #&20:JSR MskDF0 :\ Preserve ownership flag TYA:PHA:JSR FindWS :\ ws=>private workspace n]LDA &28D:CMP #2:PHP:JSR ServAgo :\ Copy info into private w/s if I own shared workspace x: \\ This now moved to *HADFS \\LDY #OPTFLG &FF E\\LDA (ws),Y:\ #&6F :\ Clear MOS 3.50 and NoDFS flags D\\JSR ChkMOS350:\BNE Serv2e :\ Check for "MOS 3.50" string 9\\A #&80 :\ Set MOS 3.50 flag \\.Serv2e 6\\STA (ws),Y :\ Update OPTFLG : ?PLP:BCC Serv2Exit :\ Exit if not Ctrl-Break GLDA #0:LDY #CHNINFO 255 :\ Clear channel info if Ctrl-Break .Serv2Lp2 STA (ws),Y:INY:BNE Serv2Lp2 QJSR ReadCMOS:TYA :\ Get my CMOS byte, using Y=&00 as default >LDY #DRVINT 255:STA (ws),Y :\ Store as default DRVINT .Serv2Exit >JSR ClrOwnWS :\ I don't own workspace "9PLA:TAY:LDA #2:RTS :\ Restore and exit ,: 6<.GetOwnWS:JSR GetDF0_F4: #&20:RTS :\ Get ownership flag @>.SetOwnWS:LDA #&20:BNE SetDF0_F4 :\ Set ownership flag J@.ClrOwnWS:LDA #&DF :\ Clear ownership flag T: ^.MskDF0_F4:LDX &F4 h".MskDF0 : &DF0,X:JMP PutDF0 r.GetDF0_F4:LDA #0 |.SetDF0_F4:LDX &F4 .SetDF0 :A &DF0,X .PutDF0 :STA &DF0,X:RTS : 6\ Keep bits from OPTFLG in Y, merge in bits from A 6\ ------------------------------------------------ .MaskIntoOPTFLG PHA:TYA:JSR MaskOPTFLG:PLA .IntoOPTFLG A OPTFLG:STA OPTFLG:RTS .MaskOPTFLG  OPTFLG:STA OPTFLG:RTS : $\ ------------------------------ #\ SERVICE 3 - BOOT FILING șTEM $\ ------------------------------  .Serv3 &:TYA:PHA:LDA #&7A:JSR OSBYTE :\ Scan for keypress 07TXA:BMI Serv3Init2 :\ No key pressed :BCMP #&54:BNE Serv3Exit :\ 'H' pressed, select HADFS D: N)\ Allow Ctrl-Caps-H-Break to disable: XN\\LDX #&BF:\CMP #&54:\BEQ Srv3Key :\ 'H' pressed, X=check for CapsLock bN\\LDX #&AB:\CMP #&40:\BNE Srv3Exit :\ 'CapsLock' pressed, X=check for H l\\.Srv3Key vH\\PHA:\LDA #&81:\LDY #&FF:\JSR OSBYTE :\ Check for other key pressed ;\\PLA:\INX:\BEQ Srv3Disable :\ 'H'+'CapsLock' 6\\CMP #&54:\BEQ Srv3Init :\ 'H-Break' \\.Srv3Disable ;\\LDA &28D:\BEQ Srv3Exit :\ Not Ctrl-Break \\.RomDisable \\SEC:\JSR RomEnable \\JSR PrText *\\EQUS "Press CTRL-BREAK":\BRK:\JMP P% \\.Serv3Init1 B\\TXA:\LDA #&78:\JSR OSBYTE :\ Clear keypressed info : >LDA #&78:JSR OSBYTE :\ Clear keypressed info >PLA:.Serv3Setup:PHA :\ Enter here from *FX90 .Serv3Init2 JSR PrTitle2:JSR fx143go !JSR CheckClock1:BEQ srv3clkOk "JSR PrText:EQUS " No date":BRK *.srv3clkOk 4JSR Pr2Newl >PLA:BNE Serv3NoBoot H)LDX #BootTab 255:LDY #BootTab 256 RJSR I_AmXY \.Serv3NoBoot fLDA #0:RTS p.Serv3Exit zPLA:TAY:LDA #3:RTS .BootTab EQUS "BOOT":EQUB 13 : \ ---------------------- \ SERVICE 4 - * COMMANDS \ ---------------------- .Serv4 LDX #OsTable1-CommTable .Serv4Try TXA:PHA:JSR SearchTable BNE Srv4Go PLA:TAX:LDA (&F2),Y: #&DF CMP #"H":BNE Srv4No INY:JSR SearchTable BNE Srv4Go2 DEY $ .Srv4No .LDA #4:RTS 8 .Srv4Go BPLA L .Srv4Go2 VJSR JumpWS:LDA #0:RTS `: j\ ------------------ t\ SERVICE 7 - OSBYTE ~\ ------------------  .Serv7 #PHA:LDA &EF:CMP #90:BNE Srv7Off LDA &F0:BEQ Srv7info CMP #progID:BNE Srv7Off \ *FX90,6,n 3LDA &DF0,X:TAY :\ Y=old DF0,X value 5LDA &F1:BMI Srv7rd :\ *FX90,6,128+ - read =CMP #&40:BCS Srv7Off :\ *FX90,6,64+ - context calls 5CMP #4:BCS Srv7rd :\ *FX90,6,4+ - unused 5CMP #1:BEQ Srv7off :\ *FX90,6,1 - disable 0CLC:JSR RomEnable :\ CC, enable ROM 4BEQ Srv7rd :\ *FX90,6,0 - enable ,SBC #2:JSR Serv3Setup :\ A is now 0  TAY:BEQ Srv7ok  .Srv7off 1JSR RomEnable :\ CS, disable ROM ( .Srv7rd 2'TYA :\ 00xx 01xx 10xx 11xx <% #&40 :\ 01xx 00xx 11xx 10xx F&CMP #&40 :\ CS CC CS CS P&BCS P%+4 :\ vv vv vv ZADC #&C1 :\ 11xx d'SBC #&40 :\ 00xx 10xx 10xx 01xx n STA &F0 x .Srv7ok PLA:LDA #0:RTS : ".Srv7info:\ *FX90 help routine LDA &F1:BEQ Srv7hlp !CMP #1:BNE Srv7Off:JSR PrText EQUS progID+": ":BRK JSR PrTitle:JMP Srv7Off  .Srv7hlp &TAX:LDY #1:JSR Osbyte90:JMP Srv7ok : .Srv7Off:PLA:RTS : .RomEnable #\ CC=Enable ROM, CS=Disable ROM  LDX &F4 (PHA:LDA &DF0,X:PHA: #&BF:STA &DF0,X "$PLA:BCC P%+4: #&80:LSR A: #&40 ,JSR SetDF0:PLA:RTS 6: @\ ------------------ J\ SERVICE 8 - OSWORD T\ ------------------ ^ .Serv8 h LDA &EF r=CMP #14:BNE P%+5:JMP Osword14 :\ OSWORD 14 - Read RTC |>\CMP #15:\BNE P%+5:\JMP Osword15 :\ OSWORD 15 - Write RTC GCMP #90:BNE P%+5:JMP Osword90 :\ OSWORD 90 - Read/Write sectors LDA #8:RTS : $\ ------------------------------ $\ SERVICE 10 - Release workspace $\ ------------------------------  .ServA CLC:.ServAgo ?JSR GetOwnWS:BEQ SrvAExit :\ I don't own, so ignore IBCS P%+5:JSR args0_FF :\ Update buffers if not Ctrl-Break  \.SrvAgo2 =JSR ClrOwnWS:JSR FindWS :\ Clear ownership flag QLDY #CSD 255 :\ Copy context and channel info to workspace  .SrvAlp DLDA WS,Y:STA (ws),Y:INY:BNE SrvAlp:\ Save workspace after fsnums  .SrvAExit &LDA #&A:RTS 0: :(\ ---------------------------------- D'\ SERVICE &12 - SELECT FILING șTEM N(\ ---------------------------------- X .Serv12 bCPY #HADFSnum:BEQ Srv12Init lTYA:CMP #5:BCC Srv12not vJSR FindWS:LDY #myfs CMP (ws),Y:BEQ Srv12Init  INY:CMP (ws),Y:BEQ Srv12Init  .Srv12not TAY:LDA #&12:RTS .Srv12Init "JMP HadfsOn:\ Returns with A=0 : -\ --------------------------------------- '\ SERVICE &25 - FILING șTEM INFO -\ ---------------------------------------  .Serv25 LDX #0:.Srv25lp LDA Srv25tb,X:STA (&F2),Y INX:INY:CPX #11:BNE Srv25lp  LDA #&25:RTS  .Srv25tb  #EQUS "HADFS ":EQUB 25:EQUB 29 *EQUB HADFSnum 4: >\ ------------------- H\ SERVICE &26 - *SHUT R\ ------------------- \ .Serv26 f=JSR EnsureHADFS:PHA :\ Select HADFS if not already p1JSR Close :\ Close all files z7PLA:JSR RestoreFS:LDA #&26 :\ Restore filing system : .Serv27:\ RESET .Serv28:\ *CONFIGURE RTS : "\ ---------------------------- "\ SERVICE &29 - DISPLAY STATUS "\ ---------------------------- -\ Need to change status output, possible: K\ *Status HADFS *Status HADFS *Status HADFS [\ Date Unset Date Thu,28 Mar 2013.22-30-00 HADFS 02 86 Thu,28 Mar.... %\ Channels 5 Channels 4 ,\ Drives IIEEEIIE Drives IIIIIIII \  .Serv29 =TAX:TYA:PHA :\ Save command offset $?JSR GetChar:BEQ Srv29a :\ - display status .INX:INY:LDA CommTable-1,X HCMP #"`":BCC TableLp RLDA (&F2),Y: #&DF \CMP #"Z"+1:BCS TableFound fCMP #"A":BCS TableNxt2 pBCC TableFound z .TableDot JSR TableSkip:INY .TableFound LDA CommTable+0,X:STA ws+0 LDA CommTable+1,X:STA ws+1 PLA:JSR SkipSpc:LDA #&FF RTS:\ found : .TableSkip LDA CommTable,X:INX CMP #"`":BCC TableSkip RTS : : "\ Tables .CommTable .HelpTable $AEQUS "HADFs":EQUB FileTable-CommTable:EQUB FileText-TextTable .>EQUS "UTILs":EQUB OsTable2-CommTable:EQUB OsText-TextTable 8BRK B: L .OsTable1 VEQUS "STATUs":EQUW Status ` EQUS "CONFIGURe":EQUW Config j4:]: _NoStatus%:z%=P%-OsTable1:P%=P%-z%:O%=O%-z% tEQUS "SHUt":EQUW Shut ~ .OsTable2 EQUS "CLOSe":EQUW Close .z% EQUS "FORm":EQUW Form .:]: _NoFormat%:z%=P%-z%:P%=P%-z%:O%=O%-z% EQUS "HADFs":EQUW Hadfs EQUS "SETDATe":EQUW SetDate !\EQUS "SETTIMe":\EQUW SetTime EQUS "TIMe":EQUW Time BRK : .FileTable EQUS "ACCESs":EQUW Access EQUS "ACCOUNt":EQUW Account  EQUS "BYe":EQUW Bye EQUS "CDIr":EQUW CDir .z% (EQUS "COPy":EQUW Copy 2.:]: _OmitCopy%:z%=P%-z%:P%=P%-z%:O%=O%-z% <EQUS "DELETe":EQUW Delete FEQUS "DIr":EQUW Dir PEQUS "ENABLe":EQUW Enable ZEQUS "Ex":EQUW Ex dEQUS "FREe":EQUW Free nEQUS "INFo":EQUW Info x.CommInstall EQUS "INSTALl":EQUW Install EQUS "I Am":EQUW I_Am EQUS "LIb":EQUW Lib EQUS "MAp":EQUW Map EQUS "MOUNt":EQUW Mount EQUS "RENAMe":EQUW Rename EQUS "TITLe":EQUW Install BRK : .TextTable  .NullText  .HelpText EQUB &80:\ and the next one #.OsText:\ Mustn't be =TextTable  EQUB &80 .z% "'EQUB 8:EQUS "nn "+128 ,.:]: _NoFormat%:z%=P%-z%:P%=P%-z%:O%=O%-z% 6 EQUB &80 @&EQUS "(dd/mm/yy (d)":EQUB ")"+128 J!\EQUS "hh,mm,s":\EQUB "s"+128 T EQUB &80 ^: h .FileText r&EQUS " "+128 |#EQUS " "+128  EQUB &80 EQUS ""+128 .z% $EQUS " "+128 .:]: _OmitCopy%:z%=P%-z%:P%=P%-z%:O%=O%-z% EQUS ""+128 EQUS "(":EQUB ")"+128  EQUB &80 EQUS "(":EQUB ")"+128 EQUS "(":EQUB ")"+128 EQUS ""+128 .HelpInstall 5EQUS "( ($)) () (":EQUB ")"+128 -EQUS ""+128:\ "(;/)" EQUS ""+128 EQUS "(":EQUB ")"+128 &EQUS "(":EQUB ")"+128 0+EQUS " "+128 :&EQUS "() "+128 D: N: X] b$ 11;20,9);O%-mcode%;" bytes" l>"S.HADFS1"