Mastering Sideways ROM & RAM - Module 20 - RFS * commands --------------------------------------------------------- The RFS formatting programs used in the previous modules of the course have allowed you to store BASIC and machine code programs in the RFS and to run them in user memory by selecting the RFS and then either chaining or *RUNning the programs. It is usually more convenient to run programs from SWR with * commands. In this module I will demonstrate how to do this using the familiar one command interpreter in an RFS ROM image with a service entry point. You can adapt the technique and use it with the multiple command interpreter introduced in Module 15. When an unrecognised * command is matched with the ROM title string the one command interpreter usually passes control to a new routine which is executed in SWR and followed by a return to the MOS. It is not possible to run programs stored in the RFS in this way. Files are stored in the RFS in a format similar to cassette files and, like cassette files, they must be loaded into user memory before they can run. Files can not run in the RFS memory even if they are sideways RAM programs. If you want to store SWR files in the RFS they will have to be loaded from the RFS into another SWR bank and initialised before they will run. To run programs from the RFS with a new * command it is necessary for the interpreter to recognise the command and then pass control to a routine which will select the RFS, load the program into user memory and run the program. If you have the program DEMO stored in the RFS you could achieve this same objective by typing: >*BASIC >*ROM >CHAIN "DEMO" The interpreter in the program RFSERV runs the program DEMO by passing control to a routine which does just what you would do but in a different order. It first selects the RFS with Osbyte &8D. It then flushes the keyboard buffer and inserts the string CHAIN "DEMO" into the buffer and finally it uses Osbyte &BB to find BASIC and Osbyte &8E to enter BASIC. When BASIC is entered in this way it executes the command in the keyboard buffer and, in this example, it will chain the program DEMO from the active filing system, the RFS. The coding executed when the new command is recognised is shown in figure 20.1. The command stored in the string starting at the label ".rfscomm" can be replaced with whatever command, or series of commands, you need to run your program. .found LDA #&8D \ Osbyte &8D JSR &FFF4 \ *ROM LDA #&0F \ Osbyte &0F LDX #0 JSR &FFF4 \ flush all buffers LDA #&FF \ initialise offset PHA \ store offset .keyboard PLA \ load A with offset TAX \ offset in X INX \ increment offset TXA \ copy offset into A PHA \ and store LDY rfscomm,X \ load character BEQ endkey \ branch if end of text marker LDA #&8A \ Osbyte &8A LDX #&0 \ keyboard buffer JSR &FFF4 \ load character into buffer JMP keyboard \ go for next character .endkey PLA \ balance stack LDA #&BB \ Osbyte &BB LDX #0 LDY #&FF JSR &FFF4 \ find BASIC LDA #&8E \ Osbyte &8E JMP &FFF4 \ enter BASIC, no return .rfscomm EQUS "CHAIN""DEMO""" EQUB &0D \ BRK \ end of text marker Figure 20.1 Inserting CHAIN "DEMO" into the keyboard buffer. ----------- ------------------------------------------------ The program RFSERV uses the RFS interpreter (lines 540-880) introduced in Module 18 and the unrecognised * command interpreter (lines 290-530) first used in Module 3. When this interpreter matches an unrecognised command with the ROM title string it passes control to the label ".found" (line 890). It uses the routine in figure 20.1 to insert the command CHAIN "DEMO" into the keyboard buffer and exits the ROM image by entering BASIC (lines 1150-1200). There is no need to balance the stack before entering BASIC in this way because, as you should know by now, BASIC will reset the stack when it is initialised. If you want to use this program to run any other program from the RFS you will obviously have to alter the command string in lines 1220 to 1240 and the ROM title in line 230. As with all the RFS header programs used to illustrate this course RFSERV is used to create RFS ROM images with RFSGEN and DEMO. Chain RFSERV from a disc or tape which also contains both these programs. Load the ROM image they create into SWR and press the Break key. Type *DEMO and press Return and the demonstration program will load into user memory and run. Module 18 has more detailed instructions on using the RFS formatting programs if you need them. 10 REM: RFSERV 20 MODE7 30 HIMEM=&3C00 40 diff=&8000-HIMEM 50 H%=HIMEM 60 comvec=&F2 70 ROMnumber=&F4 80 phROM=&F5 90 ROMpoint=&F6 100 gsread=&FFC5 110 osbyte=&FFF4 120 FOR pass = 0 TO 2 STEP 2 130 P%=HIMEM 140 [ OPT pass 150 BRK 160 BRK 170 BRK 180 JMP service+diff 190 OPT FNequb(&82) 200 OPT FNequb((copyright+diff) MOD 256) 210 BRK 220 .title 230 OPT FNequs("DEMO") 240 .copyright 250 BRK 260 OPT FNequs("(C)1987 Gordon Horsington") 270 BRK 280 .service 290 PHA 300 CMP #4 310 BNE trythirteen 320 TXA 330 PHA 340 TYA 350 PHA 360 LDX #&FF 370 .comloop 380 INX 390 LDA title+diff,X 400 BEQ found 410 LDA (comvec),Y 420 INY 430 CMP #ASC(".") 440 BEQ found 450 AND #&DF 460 CMP title+diff,X 470 BEQ comloop 480 PLA 490 TAY 500 PLA 510 TAX 520 PLA 530 RTS 540 .trythirteen 550 CMP #13 560 BNE fourteen 570 TYA 580 EOR #&F 590 CMP ROMnumber 600 BCC out 610 LDA #(lastbyte+diff) MOD 256 620 STA ROMpoint 630 LDA #(lastbyte+diff) DIV 256 640 STA ROMpoint+1 650 LDA ROMnumber 660 EOR #&F 670 STA phROM 680 .exit 690 PLA 700 LDA #0 710 RTS 720 .fourteen 730 CMP #14 740 BNE out 750 LDA phROM 760 EOR #&F 770 CMP ROMnumber 780 BNE out 790 LDY #0 800 LDA (ROMpoint),Y 810 TAY 820 INC ROMpoint 830 BNE exit 840 INC ROMpoint+1 850 JMP exit+diff 860 .out 870 PLA 880 RTS 890 .found 900 LDA #&8D 910 JSR osbyte \ *ROM 920 LDA #&8B 930 LDX #1 940 LDY #0 950 JSR osbyte \ *OPT1,0 960 LDA #&0F 970 LDX #0 980 JSR osbyte \ Flush all buffers 990 LDA #&FF 1000 PHA 1010 .keyboard 1020 PLA 1030 TAX 1040 INX 1050 TXA 1060 PHA 1070 LDY rfscomm+diff,X 1080 BEQ endkey 1090 LDA #&8A 1100 LDX #0 1110 JSR osbyte 1120 JMP keyboard+diff 1130 .endkey 1140 PLA 1150 LDA #&BB 1160 LDX #0 1170 LDY #&FF 1180 JSR osbyte \ Find BASIC 1190 LDA #&8E 1200 JMP osbyte \ Enter BASIC 1210 .rfscomm 1220 OPT FNequs("CHAIN""DEMO""") 1230 OPT FNequb(&0D) 1240 BRK 1250 .lastbyte 1260 ] 1270 NEXT 1280 O%=lastbyte 1290 CHAIN"RFSGEN" 1300 DEFFNequb(byte) 1310 ?P%=byte 1320 P%=P%+1 1330 =pass 1340 DEFFNequw(word) 1350 ?P%=word 1360 P%?1=word DIV 256 1370 P%=P%+2 1380 =pass 1390 DEFFNequd(double) 1400 !P%=double 1410 P%=P%+4 1420 =pass 1430 DEFFNequs(string$) 1440 $P%=string$ 1450 P%=P%+LEN(string$) 1460 =pass