10
20
30
40
50
60
70
80
90
100
110
120
130
140 :
150 OS_CLI=&FFF7:OSBYTE=&FFF4:OSWORD=&FFF1:OSWRCH=&FFEE
160 OSASCI=&FFE3:OSGBPB=&FFD1:OSNEWL=&FFE7:OSFILE=&FFDD
170 :
180 DIM mcode% &B00, L% -1
190 FOR P=0TO1
200 P%=&8000:O%=mcode%
210 [OPT P*3+4
220 .ROMStart
230 EQUS "MRB" :\ No language entry
240 JMP Service :\ Service entry
250 EQUB &82:EQUB ROMCopyright-ROMStart
260 .ROMVersion
270 EQUB &05
280 .ROMTitle
290 EQUS "Virtual DFS":EQUB 0:EQUS "0.05 (01 Oct 2016)"
300 .ROMCopyright
310 EQUB 0:EQUS "(C)1995 MRB, 2004,2016 JGH":EQUB 0
320 :
330 .Service
340 PHA:TYA:PHA :\ Save registers
350 TSX:LDA &0102,X :\ Get service number
360 CMP #&03:BNE P%+5:JMP ServFSStart :\ FS startup
370 CMP #&04:BNE P%+5:JMP ServCommand :\ *command
380 CMP #&08:BNE P%+5:JMP ServOsword :\ OSWORD
390 CMP #&09:BNE P%+5:JMP ServHelp :\ *Help
400 CMP #&12:BNE P%+5:JMP ServFSSelect:\ Select a filing system
410 CMP #&25:BNE P%+5:JMP ServFSInfo :\ Request FS info
420 .ServExit
430 PLA:TAY :\ Restore Y
440 .ServExitY
450 PLA:RTS :\ Restore service number and return
460 .ServClaim
470 PLA:PLA :\ Drop stacked registers
480 LDA #0:RTS :\ Exit with A=0 to claim call
490 :
500 \ ===========================
510 \ ROM Administration Routines
520 \ ===========================
530 .PrROMTitleNL :\ Print NL, ROM title
540 JSR OSNEWL
550 .PrROMTitle :\ Print ROM title
560 LDX #0
570 .PrRTLp
580 LDA ROMTitle,X:BEQ PrRTDone
590 JSR OSWRCH:INX:BNE PrRTLp
600 .PrRTDone
610 RTS
620 .PrROMVersion
630 JSR PrSpace:INX
640 .PrRVLp
650 LDA ROMTitle,X:CMP #ASC"!":BCC PrRVDone
660 JSR OSWRCH:INX:BNE PrRVLp
670 .PrRVDone
680 JMP OSNEWL
690 :
700 \ ------------
710 \ ROM Commands
720 \ ------------
730 .ServCommand
740 PLA:TAY:PLA:LDX #&00 :\ X=>ROM command table
750 :
760 \ ---------------
770 \ *command lookup
780 \ ---------------
790 .CmdSearch
800 PHA:TYA:PHA :\ Save A and text offset
810 .CmdLookNext
820 PLA:PHA:TAY :\ Get text offset back
830 .CmdLookLp
840 LDA (&F2),Y:CMP #&2E:BEQ CmdMatchDot
850 AND #&DF:CMP CommandBase,X:BNE CmdNoMatch
860 INX:INY:LDA CommandBase,X
870 CMP #&0D:BNE CmdLookLp :\ Not a full command
880 LDA (&F2),Y :\ Get following character
890 CMP #ASC"A":BCS CmdCheckNext:\ Ensure command ends with non-alpha
900 DEY :\ Prepare to skip spaces
910 .CmdFoundSpc
920 INY:LDA (&F2),Y :\ Move past any spaces
930 CMP #ASC" ":BEQ CmdFoundSpc
940 LDA CommandBase+1,X:STA &B0 :\ Get command address
950 LDA CommandBase+2,X:STA &B1
960 JSR JumpB0 :\ Call command routine
970 PLA:PLA:LDA #0:RTS :\ Drop saved A,Y, return claimed
980 .CmdMatchDot
990 INX:LDA CommandBase,X
1000 CMP #&0D:BNE CmdMatchDot :\ Find end of table entry
1010 BEQ CmdFoundSpc :\ Jump to enter command
1020 .CmdNoMatch
1030 LDA CommandBase,X:INX
1040 CMP #&0D:BNE CmdNoMatch :\ Find end of table entry
1050 .CmdCheckNext
1060 INX:INX:LDA CommandBase,X
1070 BNE CmdLookNext :\ Loop until terminator found
1080 .CmdQuit
1090 PLA:TAY:PLA:RTS :\ Restore A,Y, exit unclaimed
1100 :
1110 \ -----------------
1120 \ ROM Command Table
1130 \ -----------------
1140 .CommandBase
1150 .ROMCommands
1160 \ Filing system selection
1170 EQUS "DISC" :EQUB 13:EQUW disc
1180 EQUS "DISK" :EQUB 13:EQUW disk
1190 EQUS "ADFS" :EQUB 13:EQUW adfs
1200 EQUS "FADFS" :EQUB 13:EQUW fadfs
1210 EQUS "VDFS" :EQUB 13:EQUW vdfs
1220 EQUS "FSCLAIM":EQUB 13:EQUW fsclaim
1230 :
1240 \ Utility commands
1250 EQUS "OSW"+CHR$(ASC"7"AND&DF)+"F":EQUB 13:EQUW fdc
1260 \EQUS "PAGE" :\EQUB 13:\EQUW page
1270 EQUS "QUIT" :EQUB 13:EQUW quit
1280 EQUS "DESKTOP":EQUB 13:EQUW quit
1290 \EQUS "SHADOW":\EQUB 13:\EQUW shadow
1300 :
1310 \ SRAM commands
1320 EQUS "SRLOAD" :EQUB 13:EQUW srload
1330 EQUS "SRWRITE":EQUB 13:EQUW srwrite
1340 EQUB 0
1350 :
1360 \ ---------------------------
1370 \ Filing System Command Table
1380 \ ---------------------------
1390 .FSCommands
1400 EQUS "ACCESS" :EQUB 13:EQUW access
1410 EQUS "BACK" :EQUB 13:EQUW back
1420 EQUS "BACKUP" :EQUB 13:EQUW backup
1430 EQUS "COMPACT":EQUB 13:EQUW compact
1440 EQUS "COPY" :EQUB 13:EQUW copy
1450 EQUS "DELETE" :EQUB 13:EQUW delete
1460 EQUS "DESTROY":EQUB 13:EQUW destroy
1470 EQUS "DRIVE" :EQUB 13:EQUW drive
1480 EQUS "ENABLE" :EQUB 13:EQUW enable
1490 EQUS "EX" :EQUB 13:EQUW ex
1500 EQUS "FORM" :EQUB 13:EQUW form
1510 EQUS "FREE" :EQUB 13:EQUW free
1520 EQUS "INFO" :EQUB 13:EQUW info
1530 EQUS "MAP" :EQUB 13:EQUW free
1540 EQUS "MOUNT" :EQUB 13:EQUW mount
1550 EQUS "RENAME" :EQUB 13:EQUW rename
1560 EQUS "TITLE" :EQUB 13:EQUW title
1570 EQUS "VERIFY" :EQUB 13:EQUW verify
1580 EQUS "WIPE" :EQUB 13:EQUW wipe
1590 EQUB 0
1600 :
1610 ]:IF P%-CommandBase>255:PRINT"Command table too big":END
1620 [OPT P*3+4
1630 \ ----------------------------------
1640 \ Detailed help routine
1650 \ Based on Sprow's code in VDFS 0.02
1660 \ ----------------------------------
1670 .ServHelp
1680 LDA (&F2),Y
1690 CMP #&0D:BEQ HelpTitle :\ No subject, just print ROM title
1700 CMP #&2E:BEQ L8514 :\ '.', print full info
1710 AND #&DF:CMP #&56:BNE L8538:\ Doesn't start with 'V', check for "DFS"
1720 INY:\JMP L8538 :\ Move past 'V', check for "DFS"
1730 :
1740 .L8538
1750 DEY:LDX #&FF
1760 .L853B
1770 INX:INY :\ Point to next characters
1780 LDA (&F2),Y:AND #&DF
1790 CMP L854C,X:BEQ L853B :\ If matches "DFS", loop to next char
1800 LDA L854C,X:BEQ L8514 :\ If at end, jump to print full info
1810 JMP ServExit
1820 :
1830 .L8514
1840 JSR PrROMTitleNL :\ Print ROM title
1850 JSR PrROMVersion
1860 LDX #ROMCommandHelp AND 255
1870 LDY #ROMCommandHelp DIV 256:\ Point to help text
1880 JSR PrintText:JMP ServExit
1890 .HelpTitle
1900 JSR PrROMTitleNL :\ Just print ROM title
1910 JSR PrROMVersion
1920 JMP ServExit
1930 :
1940 .PrintText
1950 STX &F6:STY &F7 :\ Store text pointer in ROMFS text pointer
1960 LDY #&00:BEQ L8525 :\ Jump into loop
1970 .L8522
1980 CMP #10:BNE HelpChar :\ LF is soft CR
1990 LDA &30A:SBC &308 :\ Get window width
2000 CMP #70:BCC HelpNarrow :\ <80 columns
2010 LDA #ASC" ":BNE HelpChar :\ 80-column mode, print space
2020 .HelpNarrow
2030 JSR OSNEWL:JSR PrSpace :\ <80-column mode, print newline+2spaces
2040 .HelpChar
2050 JSR OSASCI
2060 .L8525
2070 LDA (&F6),Y:BEQ L8530 :\ If &00 terminator, end
2080 INY:BNE L8522 :\ Loop to print character
2090 INC &F7:BMI L8522 :\ Increment high byte and loop back
2100 .L8530
2110 RTS
2120 :
2130 .L854C
2140 EQUS "DFS":EQUB 0 :\ *Help match string
2150 :
2160 .ROMCommandHelp
2170 EQUS "Filing system selection:":EQUB 13
2180 EQUS " DISK, DISC, ADFS, FADFS :":EQUB 10
2190 EQUS "Select VDFS if claimed":EQUB 13
2200 EQUS " VDFS : Select VDFS":EQUB 13
2210 EQUS " FSCLAIM ON : Claim DISC, ADFS":EQUB 13
2220 EQUS " FSCLAIM OFF : Release DISC, ADFS":EQUB 13
2230 EQUS " OSW7F (NONE)(<ver>) :":EQUB 10
2240 EQUS "Emulate Osword &7F memory corruption":EQUB 13
2250 EQUB 13
2260 EQUS "Utility commands:":EQUB 13
2270 EQUS " QUIT or DESKTOP : return to RISC OS":EQUB 13
2280 \EQUS " PAGE :\ force PAGE location":\EQUB 13
2290 \EQUS " SHADOW :\ dummy command":\EQUB 13
2300 EQUS " SRLOAD <name> <address> <rom>":EQUB 13
2310 EQUS " SRWRITE <start> <end> <dest> <rom>":EQUB 13
2320 EQUB 13
2330 EQUS "VDFS commands:":EQUB 13
2340 EQUS " BACK : return to root directory":EQUB 13
2350 EQUS " DRIVE : change current drive":EQUB 13
2360 EQUS " MOUNT : mount drive":EQUB 13
2370 EQUS " DIR : change current directory":EQUB 13
2380 EQUS " LIB : change current library":EQUB 13
2390 EQUS " INFO : show info on single file":EQUB 13
2400 EQUS " EX : show info on all files in CSD":EQUB 13
2410 EQUS " ACCESS, BACKUP, COMPACT, COPY,":EQUB 10
2420 EQUS "DESTROY, ENABLE, FORM, FREE, MAP,":EQUB 13
2430 EQUS " RENAME, TITLE, VERIFY, WIPE :":EQUB 10
2440 EQUS "trapped and ignored":EQUB 13
2450 EQUB 0
2460 :
2470 \ --------------------
2480 \ ROM Command routines
2490 \ --------------------
2500 .quit
2510 EQUB &03:EQUB &FF :\ Return to host
2520 :
2530 .page:.shadow
2540 \LDA #&00:\RTS :\ Ignore command
2550 :
2560 .srload :EQUB &03:EQUB &D0 :\ Pass to host and return
2570 .srwrite:EQUB &03:EQUB &D1 :\ Pass to host and return
2580 :
2590 \ ROM Support Workspace
2600 \ ---------------------
2610 .PageOffset:EQUB &00 :\ Amount to raise PAGE by
2620 :
2630 \ ======================
2640 \ Filing System Routines
2650 \ ======================
2660 \ Filing System Workspace
2670 \ -----------------------
2680 .ClaimFS:EQUB &00 :\ *FSCLAIM On/Off flag
2690 .FSFlag :EQUB &11 :\ FS id when claimed
2700 :
2710 \ --------------------------------
2720 \ Filing system selection commands
2730 \ --------------------------------
2740 .disc:.disk:.adfs
2750 .fadfs:.vdfs :\ On entry, X=4,11,18,26,33
2760 TXA:LSR A:LSR A:LSR A:TAX :\ X=0,1,2,3,4
2770 LDA FSValues,X:TAY :\ Get filing system number
2780 CPY #9:BCS SelectFS :\ Always select VDFS
2790 BIT ClaimFS:BMI SelectFS :\ If claimed, select VDFS
2800 PLA:PLA:PLA:TAY:PLA:RTS :\ Drop return, restore and return
2810 .SelectFS
2820 LDX #&12:LDA #&8F:JMP OSBYTE:\ Select filing system
2830 .FSValues
2840 EQUB 4:EQUB 4:EQUB 8 :\ DISC, DISK, ADFS
2850 EQUB 8:EQUB 17 :\ FADFS, VDFS
2860 :
2870 .fsclaim
2880 LDA (&F2),Y:AND #&DF
2890 CMP #ASC"O":BNE fsclaimStatus
2900 INY:LDA (&F2),Y:AND #&DF
2910 CMP #ASC"N":LDA #0:SBC #0
2920 EOR #&FF:STA ClaimFS:RTS
2930 .fsclaimStatus
2940 LDA #ASC"O":JSR OSWRCH
2950 LDA ClaimFS:AND #8:PHP:ORA #ASC"F"
2960 JSR OSWRCH:PLP:BNE P%+5:JSR OSWRCH
2970 JMP OSNEWL
2980 :
2990 \ --------------------------
3000 \ Filing System Service Code
3010 \ --------------------------
3020 .ServFSSelect
3030 CPY #&11:BEQ FSSelect :\ VDFS
3040 BIT ClaimFS:BPL FSSelectNone:\ If not claimed, don't check for DFS or ADFS
3050 CPY #&04:BEQ FSSelect :\ Select DFS
3060 CPY #&08:BEQ FSSelect :\ Select ADFS
3070 .FSSelectNone
3080 JMP ServExit :\ Exit unclaimed
3090 .FSSelect
3100 TYA:PHA :\ Save FS id
3110 LDA #&06:JSR FSCCallHost :\ Check host exists
3120 JSR CallFSCV :\ Inform current FS new FS taking over
3130 LDX #0:LDY #&1B :\ Set up new vectors
3140 .ClaimVecLp
3150 TYA:STA &212,X
3160 LDA #&FF:STA &213,X :\ vector=&FFxx
3170 LDA VectorTable+0,X:STA &D9F+0,Y
3180 LDA VectorTable+1,X:STA &D9F+1,Y
3190 LDA &F4:STA &D9F+2,Y :\ exvec=&RRxxyy
3200 INY:INY:INY:INX:INX
3210 CPX #&0E:BNE ClaimVecLp
3220 LDA #&8F:LDX #&0F:JSR OSBYTE:\ Notify that vectors have changed
3230 PLA:STA FSFlag :\ Store FS id
3240 JMP ServClaim
3250 .CallFSCV
3260 JMP (&021E)
3270 .VectorTable
3280 EQUW File:EQUW Args:EQUW BGet:EQUW BPut
3290 EQUW GBPB:EQUW Find:EQUW FSC
3300 :
3310 \ ---------------------------------
3320 \ Select FS on BREAK and maybe boot
3330 \ ---------------------------------
3340 .ServFSStart
3350 TYA:PHA
3360 LDA #&7A:JSR OSBYTE :\ Check what keys are pressed
3370 CPX #&FF:BEQ FSStartGo2 :\ No keys pressed, select me
3380 CPX #&51:BEQ FSStartGo1 :\ 'S' pressed, select me
3390 PLA:JMP ServExit :\ Exit
3400 .FSStartGo1
3410 LDA #&78:JSR OSBYTE :\ Clear keypressed info
3420 .FSStartGo2
3430 JSR PrROMTitle :\ Print filing system name
3440 JSR OSNEWL:JSR OSNEWL
3450 LDY FSFlag:JSR SelectFS :\ Select filing system
3460 PLA:BNE P%+5:JSR HostBoot :\ If booting, get !Boot from host
3470 JMP ServClaim :\ Exit, claimed
3480 .HostBoot
3490 EQUB &03:EQUB &D3 :\ Do !Boot
3500 :
3510 .ServFSInfo
3520 LDX #&00
3530 .FSInfoLp
3540 LDA L81FB,X:STA (&F2),Y
3550 INY:INX:CPX #44:BNE FSInfoLp:\ Copy filing system name
3560 PLA:JMP ServExitY :\ Drop saved Y and exit
3570 .L81FB
3580 EQUS "DISK ":EQUB &11:EQUB &15:EQUB &04
3590 EQUS "DISC ":EQUB &11:EQUB &15:EQUB &04
3600 EQUS "ADFS ":EQUB &30:EQUB &3A:EQUB &08
3610 EQUS "VDFS ":EQUB &C0:EQUB &FF:EQUB &11
3620 :
3630 \ -------------------------------------------
3640 \ Pass filing system calls to host and return
3650 \ -------------------------------------------
3660 .File :EQUB &03:EQUB &06
3670 .Args :EQUB &03:EQUB &05
3680 .BGet :EQUB &03:EQUB &04
3690 .BPut :EQUB &03:EQUB &03
3700 .GBPB :EQUB &03:EQUB &02
3710 .Find :EQUB &03:EQUB &01
3720 :
3730 \ -------------------
3740 \ File System Control
3750 \ -------------------
3760 .FSC
3770 CMP #&08:BEQ FSCDone :\ Jump if *command warning
3780 CMP #&0A:BNE P%+5:JMP Info :\ Info on a file
3790 CMP #&09:BNE P%+5:JMP Ex :\ Examine directory
3800 CMP #&05:BNE P%+5:JMP Cat :\ Catalogue directory
3810 CMP #&04:BEQ FSCmdRun :\ *RUN filename
3820 CMP #&03:BEQ FSCommandLookup:\ Filing system commands
3830 CMP #&02:BEQ FSCmdRun :\ */filename
3840 .FSCCallHost
3850 EQUB &03:EQUB &00 :\ Pass to emulator and return
3860 LDX #msgNoHost-msgNotFound :\ If we fall through to here, there's no
3870 JMP error :\ host and we've done ASL-ORA (&00,X)
3880 :
3890 \ ----------------------
3900 \ Filing System Commands
3910 \ ----------------------
3920 .FSCommandLookup
3930 PHA:TXA:PHA:TYA:PHA
3940 STX &F2:STY &F3:LDY #0
3950 LDX #FSCommands-CommandBase
3960 LDA #3:JSR CmdSearch:CMP #1:\ Cy=done/not done
3970 .FSCmdRetry
3980 PLA:TAY:PLA:TAX:PLA :\ Restore registers
3990 BCC FSCDone
4000 .FSCmdRun
4010 JSR FSCCallHost :\ Pass FSC to host to try
4020 \ On return, A=action, XY=address
4030 \ A=%1xxxxxxx - enter CoPro address, A=ID
4040 \ A=%01xxxxxx - enter I/O address
4050 \ A=%001xxxxx - print text
4060 \ A=%0001xxxx - reserved
4070 \ A=%0000xxxx - all done (usually A preserved)
4080 \
4090 AND #&FF:BMI FSCTube :\ Execute CoPro code
4100 ASL A:BMI FSCJump :\ Execute I/O code
4110 ASL A:BPL FSCDone
4120 JMP PrintText :\ Print text
4130 .FSCTube
4140 JSR &406:BCC FSCTube :\ Claim Tube with ID in A
4150 LDA #4:JMP &406 :\ Execute code at address at XY
4160 .FSCJump
4170 STX &B0:STY &B1
4180 .JumpB0
4190 JMP (&B0)
4200 :
4210 \ ------------------------------
4220 \ Filing System Command Routines
4230 \ ------------------------------
4240 .F2toXY
4250 TYA:CLC:ADC &F2:TAX:LDA &F3:ADC #0:TAY
4260 .FSCDone
4270 RTS
4280 :
4290 .drive :EQUB &03:EQUB &D2:\ Pass to host and return
4300 .back :EQUB &03:EQUB &D5:\ Pass to host and return
4310 .mount :EQUB &03:EQUB &D6:\ Pass to host and return
4320 .ex :JSR F2toXY:LDA #&09:JMP CallFSCV
4330 .info :JSR F2toXY:LDA #&0A:JMP CallFSCV
4340 .rename :JSR F2toXY:LDA #&0C:JMP CallFSCV
4350 :
4360 .access
4370 .backup
4380 .compact
4390 .copy
4400 .delete
4410 .destroy
4420 .enable
4430 .form
4440 .free
4450 .wipe
4460 .title
4470 .verify
4480 LDA #8:JSR FSCCallHost :\ Probe emulator
4490 CMP #3:BNE FSCDone :\ If doesn't return A=3, ignore
4500 PLA:PLA:PLA:PLA:PLA:PLA :\ Drop data from stack
4510 SEC:BCS FSCmdRetry :\ Pass command to emulator
4520 :
4530 \ ---------------------------
4540 \ Functions performed locally
4550 \ ---------------------------
4560 .Info
4570 STX &C0:STY &C1 :\ Perm FS workspace
4580 LDA #&80:BNE CatExInfo
4590 :
4600 .Ex
4610 LDA #&40:BNE CatExInfo
4620 :
4630 .Cat
4640 LDA #&00
4650 .CatExInfo :\ PL=multiple files, NE=full info
4660 \ &D01 = GBPB block
4670 \ NOTE, WSS OSGBPB 9 uses control block differently:
4680 \ &D01 = count
4690 \ &D02 = address
4700 \ &D06 = filename buffer size
4710 \ &D0A = offset
4720 \ &D0E = FILE block
4730 \ &D20 = pathname
4740 \
4750 PHA
4760 LDY #255:JSR ClaimNMI:STY &A0:\ Claim NMI workspace
4770 LDA #&40:STA &0D00:LDY #0 :\ Null RTI routine
4780 .InfoLp
4790 LDA (&C0),Y:STA &0D20,Y:INY :\ Copy filename to buffer
4800 CPY #&D60-&D20:BCC InfoLp
4810 LDA #&00:LDX #&06
4820 .CatInit
4830 STA &0D07,X:DEX:BPL CatInit :\ Start with first item
4840 .CatLoop
4850 LDX #&20:STX &0D02:STX &0D0E :\ =>Filename buffer
4860 LDX #&0D:STX &0D03:STX &0D0F
4870 PLA:PHA:BMI CatSingleFile
4880 LDX #&FF:STX &0D04:STX &0D05
4890 LDX #&01:STX &0D01 :\ Fetch one item
4900 LDX #&D60-&D20:STX &0D06 :\ Filename buffer size
4910 LDX #&01:LDY #&0D
4920 LDA #&09:JSR OSGBPB :\ Read catalogue entry
4930 LDA &0D01:BEQ CatDone :\ If no more, exit
4940 LDX #&D5F-&D20
4950 .CatLoopCR1
4960 LDA &D20,X:BNE CatLoopCR2 :\ Check for &00 terminator
4970 LDA #13:STA &D20,X :\ Change it to a <cr>
4980 .CatLoopCR2
4990 DEX:BPL CatLoopCR1
5000 .CatSingleFile
5010 LDX #&0E:LDY #&0D
5020 LDA #&05:JSR OSFILE :\ Read info on this entry
5030 TAY:BNE CatFound :\ Y=object type
5040 PLA:PHA:BMI errNotFound :\ Error if *INFO not found
5050 .CatFound
5060 JSR CatPrint :\ Print object name
5070 PLA:PHA:BEQ CatNoInfo
5080 TYA:PHA:LDY #3:LDX #5
5090 .CatAddrLp1
5100 TYA:PHA:LDY #4
5110 .CatAddrLp2
5120 LDA &0D0E,X:JSR PrHex
5130 DEX:DEY:BNE CatAddrLp2
5140 JSR PrSpace
5150 TXA:CLC:ADC #8:TAX
5160 PLA:TAY:DEY:BNE CatAddrLp1
5170 PLA:TAY :\ Get object type back
5180 .CatNoInfo
5190 TYA:JSR CatAttrs
5200 PLA:TAY:BEQ CatNext :\ *CAT, no more info
5210 JSR CatDate:JSR OSNEWL :\ *EX/*INFO, print date, newline
5220 .CatNext
5230 TYA:BMI CatExit :\ *INFO, finish
5240 PHA:JMP CatLoop :\ Loop back with *CAT/*EX
5250 :
5260 .CatDone
5270 PLA:BNE CatExit :\ *EX, no newline needed
5280 LDA #&86:JSR OSBYTE :\ Get POS,VPOS
5290 TXA:BEQ CatExit :\ No newline needed
5300 JSR OSNEWL
5310 .CatExit
5320 LDY &A0 :\ Relinquish NMI workspace
5330 .ClaimNMI
5340 LDX #11:LDA #143:JMP OSBYTE
5350 :
5360 .errNotFound
5370 JSR CatExit:LDX #0
5380 .error
5390 LDY #0
5400 .errLp
5410 INX:INY:LDA msgNotFound-1,X:STA &100,Y
5420 BNE errLp
5430 STA &100:JMP &100
5440 .msgNotFound:EQUB 214:EQUS "Not found":EQUB 0
5450 .msgNoHost :EQUB 248:EQUS "No host":EQUB 0
5460 :
5470 .CatPrint
5480 TYA:PHA:LDA #0:TAX:TAY:PHA :\ Print leafname
5490 .CatPrtLp1
5500 LDA &D20,Y:INY:CMP #ASC".":BNE CatPrtLp2
5510 PLA:TYA:PHA:LDA #ASC"."
5520 .CatPrtLp2
5530 CMP #ASC"!":BCS CatPrtLp1:PLA:TAY
5540 .CatPrtLp3
5550 LDA &0D20,Y:CMP #ASC" ":BCC CatPrPop
5560 JSR OSWRCH:INY:INX:CPX #12:BNE CatPrtLp3
5570 .CatPrPop
5580 PLA:TAY
5590 .CatPrSpc
5600 LDA #ASC" "
5610 .CatPrLp4
5620 JSR OSWRCH:INX
5630 CPX #13:BCC CatPrLp4 :\ Print spaces until column 13
5640 .CatCharNone
5650 RTS
5660 :
5670 .CatAttrs
5680 LDX #7:LDY #8
5690 AND #2:BEQ P%+5:JSR CatCharD:\ 'D'
5700 LDY #3:LDA #&08:JSR CatChar :\ 'L'
5710 LDY #1:LDA #&02:JSR CatChar :\ 'W'
5720 LDY #0:LDA #&01:JSR CatChar :\ 'R'
5730 BNE CatAttrs2
5740 LDY #2:LDA #&04:JSR CatChar :\ 'E'
5750 .CatAttrs2:JSR PrSlash :\ '\'
5760 LDY #5:LDA #&20:JSR CatChar :\ 'w'
5770 LDY #4:LDA #&10:JSR CatChar :\ 'r'
5780 BNE CatAttrs3
5790 LDY #6:LDA #&40:JSR CatChar :\ 'e'
5800 .CatAttrs3:JMP CatPrSpc
5810 :
5820 .CatChar
5830 BIT &0D1C:BEQ CatCharNone
5840 .CatCharD
5850 LDA CatAttrChars,Y:INX:JMP OSWRCH
5860 .CatAttrChars
5870 EQUS "RWELrwePD"
5880 :
5890 .CatDate
5900 LDA &D1D:BEQ CatCharNone :\ No date
5910 PHA:LDX #9:JSR CatPrSpc:PLA
5920 AND #31:JSR PrDec:JSR PrSlash :\ Day
5930 LDA &D1E:AND #15:JSR PrDec :\ Month
5940 JSR PrSlash:LDA &D1E:LSR A :\ Year b0-b3
5950 LSR A:LSR A:EOR &D1D:AND #&1E :\ Merge with year b4-b6
5960 EOR &D1D:LSR A:PHA:CMP #19
5970 LDA #20:SBC #0:JSR PrDec :\ Calculate century
5980 PLA:SEC:SBC #19:BCS PrDec :\ Calculate year
5990 ADC #100
6000 :
6010 .PrDec
6020 TAX:LDA #&99:SED:.PrDecLp
6030 CLC:ADC #1:DEX:BPL PrDecLp:CLD
6040 :
6050 .PrHex
6060 PHA:LSR A:LSR A:LSR A:LSR A
6070 JSR PrNyb:PLA:AND #15:.PrNyb
6080 SED:CLC:ADC #&90:ADC #&40
6090 CLD:JMP OSWRCH
6100 :
6110 .PrSpace:LDA #ASC" ":JMP OSWRCH
6120 .PrSlash:LDA #ASC"/":JMP OSWRCH
6130 :
6140 :
6150 \ ================
6160 \ OSWORD emulation
6170 \ ================
6180 .fdc
6190 LDA (&F2),Y:CMP #13:BEQ fdcstatus
6200 AND #&DF
6210 CMP #ASC"A":BEQ fdcAcorn
6220 CMP #ASC"W":BEQ fdcWatford
6230 LDA #3:BNE fdcSet
6240 .fdcWatford
6250 INY
6260 .fdcAcorn
6270 INY:PHA:LDA (&F2),Y:AND #7:STA &B0
6280 PLA:AND #16:LSR A:LSR A:ADC &B0
6290 :\ A=0/1/2/3 = A090/A120/A210/ALL
6300 :\ A=5/7/8/9 = W110/W130/W14x/W154
6310 .fdcSet
6320 ASL A:ASL A:ASL A
6330 CLC:ADC #Osw7FTable AND 255:STA Osw7FAddr+0
6340 LDA #0:ADC #Osw7FTable DIV 256:STA Osw7FAddr+1
6350 .fdcstEnd
6360 RTS
6370 :
6380 .fdcstatus
6390 JSR fdcFetchAddr:LDY #2
6400 .fdcstLp1
6410 LDA (&B0),Y:BEQ fdcstName
6420 JSR OSASCI:INY:BNE fdcstLp1
6430 .fdcstName
6440 JSR fdcFetchPtr
6450 LDA (&B0),Y:BEQ fdcstDone
6460 LDA #ASC":":JSR OSWRCH
6470 JMP fdcSpace
6480 .fdcstLp2
6490 LDA (&B0),Y:BEQ fdcstDone
6500 PHA:LDA #ASC"&":JSR OSWRCH
6510 LDA #&10:JSR PrHex
6520 PLA:JSR PrHex:INY
6530 .fdcSpace
6540 JSR PrSpace:JSR PrSpace:JSR PrSpace
6550 JMP fdcstLp2
6560 .fdcstDone
6570 JMP OSNEWL
6580 :
6590 .fdcFetchAddr
6600 LDA Osw7FAddr+0:STA &B0
6610 LDA Osw7FAddr+1:STA &B1
6620 RTS
6630 :
6640 .fdcFetchPtr
6650 LDY #0:LDA (&B0),Y:PHA
6660 INY:LDA (&B0),Y:STA &B1
6670 PLA:STA &B0:DEY
6680 RTS
6690 :
6700 .ServOsword
6710 LDA &EF:CMP #127 :\ Check OSWORD number
6720 BNE P%+5:JSR Osword7F :\ If FM disk access, play with memory
6730 PLA:TAY:PLA :\ Restore registers
6740 EQUB &03:EQUB &40 :\ Pass OSWORD call to emulator and return
6750 :
6760 \ -------------------------------------------------------------
6770 \ Corrupt bits of memory to simulate effects of real OSWORD &7F
6780 \ -------------------------------------------------------------
6790 .Osword7F
6800 LDA &B0:PHA:LDA &B1:PHA :\ Code calling Osword7F may be using &B0/1
6810 JSR fdcFetchAddr
6820 JSR fdcFetchPtr
6830 .Osw7FLp
6840 LDA (&B0),Y:BEQ Osw7FDone:TAX
6850 EOR &1000,X:ROL A:EOR #&23:STA &1000,X
6860 INY:BNE Osw7FLp
6870 .Osw7FDone
6880 PLA:STA &B1:PLA:STA &B0 :\ A,X,Y preserved outside here
6890 RTS
6900 :
6910 .Osw7FAddr
6920 EQUW Osw7FTableNone :\ Pointer to address table
6930 :
6940 .Osw7FTable
6950 EQUW Osw7FAcorn1:EQUS "A090":EQUB 0:EQUB 0
6960 EQUW Osw7FAcorn1:EQUS "A120":EQUB 0:EQUB 1
6970 EQUW Osw7FAcorn2:EQUS "A210":EQUB 0:EQUB 2
6980 .Osw7FTableNone
6990 EQUW Osw7FNone :EQUS "NONE":EQUB 0:EQUB 3
7000 EQUW Osw7FAll :EQUS "ALL ":EQUB 0:EQUB 4
7010 EQUW Osw7FWatf :EQUS "W110":EQUB 0:EQUB 5
7020 EQUW Osw7FWatf :EQUS "W120":EQUB 0:EQUB 6
7030 EQUW Osw7FWatf :EQUS "W130":EQUB 0:EQUB 7
7040 EQUW Osw7FWatf :EQUS "W14x":EQUB 0:EQUB 8
7050 EQUW Osw7FWat5 :EQUS "W15x":EQUB 0:EQUB 9
7060 .Osw7FNone
7070 EQUB 0
7080 :
7090 .Osw7FAcorn1:\ Locations corrupted by Acorn DFS 0.90/1.20
7100 EQUB &72:EQUB &73:EQUB &74:EQUB &75:EQUB &80:EQUB &82
7110 EQUB &83:EQUB &85:EQUB &C8:EQUB &C9:EQUB &D3:EQUB &D5
7120 EQUB &D6:EQUB 0
7130 :
7140 .Osw7FAcorn2:\ Locations corrupted by Acorn DFS 2.10/2.20
7150 EQUB &87:EQUB &88:EQUB &89:EQUB &8B:EQUB &8C:EQUB &8D
7160 EQUB &8E:EQUB &D3:EQUB &D6:EQUB &DE:EQUB &DF:EQUB &E0
7170 EQUB &E1:EQUB 0
7180 :
7190 .Osw7FWatf :\ Locations corrupted by Watford 1.00-1.44
7200 EQUB &42:EQUB &43:EQUB &4A:EQUB &78:EQUB &88:EQUB &89
7210 EQUB &8A:EQUB 0
7220 :
7230 .Osw7FWat5 :\ Locations corrupted by Watford 1.54
7240 EQUB &30:EQUB &36:EQUB &38:EQUB &3F:EQUB &42:EQUB &43
7250 EQUB &4A:EQUB &78:EQUB &88:EQUB &89:EQUB &8A:EQUB &A0
7260 EQUB &A1:EQUB &A2:EQUB &A3:EQUB &A4:EQUB &A5:EQUB &A6
7270 EQUB &A7:EQUB &A8:EQUB &A9:EQUB &AA:EQUB 0
7280 :
7290 .Osw7FAll :\ Composite of all locations
7300 EQUB &30:EQUB &33:EQUB &36:EQUB &38:EQUB &3F:EQUB &42
7310 EQUB &43:EQUB &44:EQUB &4A:EQUB &72:EQUB &73:EQUB &74
7320 EQUB &75:EQUB &78:EQUB &79:EQUB &7A:EQUB &7B:EQUB &80
7330 EQUB &82:EQUB &83:EQUB &85:EQUB &87:EQUB &88:EQUB &89
7340 EQUB &8A:EQUB &8B:EQUB &8C:EQUB &8D:EQUB &8E:EQUB &A0
7350 EQUB &A1:EQUB &A2:EQUB &A3:EQUB &A4:EQUB &A5:EQUB &A6
7360 EQUB &A7:EQUB &A8:EQUB &A9:EQUB &AA:EQUB &C8:EQUB &C9
7370 EQUB &D3:EQUB &D5:EQUB &D6:EQUB &DE:EQUB &DF:EQUB &E0
7380 EQUB &E1::EQUB 0
7390 :
7400 ]
7410 IF O%>L%:PRINT"Code overflow":END
7420 NEXT
7430 PRINT" *SAVE VDFS05/ROM ";~mcode%;" ";~O%;" 0 FFFBBC00"
7440
7450
7460
7470
7480
7490
7500
7510
7520 :
7530
7540
7550 :
7560
7570
7580
7590
7600 :
7610
7620
7630
7640
7650
7660
7670
7680 :
7690