10 REM Generate an RFS image 20 DIM block% 18 30 DIM name% &10 40 DIM crc% 128 50 oswc=&FFEE:osnl=&FFE7:osas=&FFE3 60 osfi=&FFDD:osgbpb=&FFD1 70 tL%=&F2:tH%=&F3:vL%=&E8:vH%=&E9 80 length%=name%:REM Dual purpose! 90 REM Memory for oscall blocks,crc calculator & some zp pointer addresses 100 : 110 MODE7:PRINT"RFS image generator"' 120 PRINTTAB(0,2);"ROM size is & 000 bytes":VDU31,13,2:romsize%=GET-48 130 IFromsize%<>1 ANDromsize%<>2 ANDromsize%<>4 THENGOTO120 ELSEPRINTTAB(13,2);romsize%:romsize%=romsize%*&1000 140 DIM image% romsize% 150 : 160 INPUT"Copyright string (C)"copy$:copy$="(C)"+copy$ 170 INPUT"Today's date in DDMMYY format: "title%:title$="RFS id:"+STR$~title% 180 : 190 VDU28,0,20,39,6:REM Text window 200 : 210 PRINT"Help text to be shown by *HELP RFS"'"(Upto 255 bytes long)"'"(Press Escape when finished)"' 220 help$="":ONERRORGOTO280 230 REPEAT:key%=GET 240 IFLEN(help$)<255 THENVDUkey% ELSEVDU7 250 IF(key%>31 ANDkey%<127)ORkey%=13 THENhelp$=help$+CHR$key% 260 IF(key%=127 ORkey%=8)ANDLENhelp$>0 THENhelp$=LEFT$(help$,LENhelp$-1):REM Delete function 261 IFkey%=13 THENVDU10:REM Force LF 270 UNTILLENhelp$=255 280 PRINT:ONERROROFF 290 IFASC(RIGHT$(help$,1))<>13 ANDLEN(help$)<255 THENhelp$=help$+CHR$13:REM Always end on a CRLF 300 : 310 PROCassm:F=0:CLS:REM Make the header and set the file handle to null 320 : 330 REPEAT 340 CLOSE#F:INPUT"Filename to add: "source$ 350 IFLEN(source$)=0 THENGOTO560 360 INPUT"Write to RFS as: "dest$ 370 IFLEN(dest$)=0 THENPRINT'"Bad filename":F=0:GOTO340 380 PRINT"Lock file (Y/N)?"; 390 REPEAT:key%=GET AND&DF:UNTILkey%=ASC"N" ORkey%=ASC"Y" 400 protect%=key% AND1:PRINT;" ";CHR$(key%):REM Results in a 1 for 'Y' and 0 for 'N' and show results 410 F=OPENINsource$ 420 IFF=0 THENPRINT'"File not found":GOTO340 430 lof%=EXT#F:chunk%=0:REM Keep copy of EXT#F & reset chunk number 440 IFlof%=0 THENPRINT'"File contains no data":GOTO340 450 : 460 header=21+LEN(dest$):REM That's how long a header block is 470 top=((lof% MOD256)*(1-SGN(lof% DIV256)))+(256*(SGN(lof% DIV256)))+header+2:REM There's always a top bit,but its length is 1 512 490 bottom=((lof% MOD256)+(256*(1-SGN(lof% MOD256)))+header+2)*SGN(lof% DIV257):REM Bottom bits only occur if lof%>256 and can be of length 1(&8000+romsize%) THENPRINT'"File too large to add":GOTO340 510 : 520 next%=next%+top+middle+bottom:REM Work out where the next will start 530 PROCosfile:REM Get attributes 540 REPEAT:UNTILFNnextblock=FALSE 550 : 560 UNTILLENsource$=0 570 : 580 CLS:PRINT"Saving as 'OUTPUT'" 590 ?eoi%=ASC"+":REM End of ROM marker is a plus 600 OSCLI("SAVE OUTPUT "+STR$~(image%)+" +"+STR$~(romsize%)+" FFE7 8000") 610 END 620 : 630 DEFPROCassm 640 FORX=4 TO6 STEP2 650 P%=&8000:O%=image% 660 [OPTX 670 EQUB0:EQUB0:EQUB0 680 JMPserv 690 EQUB&82:EQUBcopy MOD256:EQUB1 700 .title 710 EQUStitle$ 720 .copy 730 EQUB0:EQUScopy$:EQUB0 740 : 750 .serv 760 PHA:TYA:PHA:TSX:LDA&102,X:LDX#255:\Call details saved on stack 770 .call 780 INX:CMPhlpT,X:BEQmine:CPXhlpN:BEQrest:BNEcall 790 .mine 800 LDAhlpH,X:PHA:\Use the stack then RTS to store the jump addr 810 LDAhlpL,X:PHA:RTS 820 : 830 .mosquery 840 TYA:EOR#15:\Perform 15-y 850 CMP&F4:BCCrest 860 LDX#next% MOD256:STX&F6 870 LDY#next% DIV256:STY&F7 880 LDA&F4:EOR#15:STA&F5 890 : 900 .dest 910 PLA:PLA:LDA#0:RTS 920 .rest 930 PLA:TAY:PLA:RTS 940 : 950 .getbyte 960 LDA&F5:EOR#15:\Perform reverse of 15-y 970 CMP&F4:BNErest 980 LDY#0:LDA(&F6),Y:TAY 990 INC&F6:BNEdest:\Leave with Y containing the byte read 1000 INC&F7:JMPdest 1010 : 1020 .help 1030 LDA(tL%),Y:CMP#13:BNEextendhelp 1040 .plainhelp 1050 JSRhelpgeneric:JMPrest 1060 .helpgeneric 1070 JSRosnl:LDX#title MOD256:LDY#title DIV256:JSRprint:JMPosnl:\Show title with space top and bottom 1080 .extendhelp 1090 LDX#255:DEY:\Ready for INX,INY 1100 .compare 1110 INX:INY:LDA(tL%),Y:AND#&DF:CMPname,X:BEQcompare:\Make upper case and check against 'name' 1120 LDAname,X:BPLrest:\Get mismatched byte 1130 .rfstyped 1140 JSRhelpgeneric 1150 LDX#helptext MOD256:LDY#helptext DIV256:JSRprint:JMPrest:\Show extended help text 1160 : 1170 .print 1180 STXvL%:STYvH%:LDY#255 1190 .getchr 1200 INY:LDA(vL%),Y:JSRosas:CMP#0:BNEgetchr:RTS:\Print out until a 0 is found 1210 : 1220 .hlpN 1230 EQUB hlpL-hlpT-1:\Number of calls being watched for 1240 .hlpT 1250 EQUB14:EQUB13:EQUB9 1260 .hlpL 1270 EQUB(getbyte-1)MOD256 1280 EQUB(mosquery-1)MOD256 1290 EQUB(help-1)MOD256 1300 .hlpH 1310 EQUB(getbyte-1)DIV256 1320 EQUB(mosquery-1)DIV256 1330 EQUB(help-1)DIV256 1340 .name 1350 EQUS"RFS"+CHR$255 1360 .helptext 1370 EQUShelp$:EQUB0 1380 .next% 1390 ] 1400 NEXT:eoi%=O% 1410 : 1420 FORX=0TO2STEP2 1430 P%=crc% 1440 [OPTX 1450 .calccrc 1460 LDA#0:STAcrcH:STAcrcL:TAY 1470 .next 1480 LDAcrcH:EOR(vL%),Y:STAcrcH 1490 LDX#8 1500 .again 1510 LDAcrcH:ROLA:BCCover 1520 LDAcrcH:EOR#8:STAcrcH 1530 LDAcrcL:EOR#16:STAcrcL 1540 .over 1550 ROLcrcL:ROLcrcH:DEX:BNEagain 1560 INY 1570 CPYlength%:BNEnext 1580 LDXcrcH:LDYcrcL:RTS 1590 .crcL 1600 EQUB0 1610 .crcH 1620 EQUB0 1630 ] 1640 NEXT 1650 ENDPROC 1660 : 1670 DEFFNnextblock 1680 IFchunk%=0 ANDlof%>256 THENPROCmakeblock("FIRST"):chunk%=chunk%+1:=TRUE 1690 IFchunk%=0 ANDlof%<=256 THENPROCmakeblock("LAST"):=FALSE 1700 IF(lof%-PTR#F)>256 THENPROCmakeblock("MIDDLE"):chunk%=chunk%+1:=TRUE 1710 PROCmakeblock("LAST"):=FALSE 1720 : 1730 DEFPROCosfile 1740 $name%=source$:?(name%+LEN(source$))=13:REM Build name block 1750 P%=block% 1760 [OPT2 1770 EQUBname% MOD256:EQUBname% DIV256:\This points to the name 1780 ] 1790 A%=5:X%=block% MOD256:Y%=block% DIV256:CALLosfi 1800 load%=!(block%+2):exec%=!(block%+6):REM Transfer attribs into variables 1810 ENDPROC 1820 : 1830 DEFPROCmakeblock(state$) 1840 REM A shorthand of # is used 1850 IFstate$="MIDDLE" THEN?eoi%=ASC"#":eoi%=eoi%+1:eoi%=eoi%+FNloaddata(eoi%):ENDPROC:REM eoi% is the end of image ptr in main RAM,whereas next% is the eoi ptr in paged RAM 1860 : 1870 IFstate$="LAST" THENflag%=(128 ORprotect%) ELSEflag%=(0 ORprotect%) 1880 : 1890 REM Build a non shorthand block 1900 !length%=FNloaddata(eoi%+LEN(dest$)+21) 1910 P%=eoi% 1920 [OPT2 1930 EQUB ASC"*":EQUSdest$ 1940 EQUB0:EQUDload%:EQUDexec% 1950 EQUWchunk%:EQUW(!length%-2) 1960 EQUBflag%:EQUDnext% 1970 ] 1980 ?vL%=(eoi%+1)MOD256:?vH%=(eoi%+1)DIV256 1990 eoi%=P%+!length%+2:!length%=21+LEN(dest$)-3:REM Don't include CRC or * in the CRC calculation! 2000 cycle%=((USRcalccrc)AND&FFFF00)DIV&100 2010 [OPT2:EQUWcycle%:] 2020 2030 ENDPROC 2040 : 2050 DEFFNloaddata(dest%) 2060 P%=block% 2070 [OPT2 2080 EQUB F:EQUDdest%:EQUD256 2090 EQUD(256*chunk%):] 2100 A%=3:X%=block% MOD256:Y%=block% DIV256:CALLosgbpb 2110 ?vL%=dest% MOD256:?vH%=dest% DIV256:!length%=256-!(block%+5):REM Setup call for data CRC 2120 cycle%=((USRcalccrc)AND&FFFF00)DIV&100 2130 P%=dest%+!length% 2140 [OPT2:EQUWcycle%:]:REM Place the data CRC and return with the amount of data read from disk +2 for the CRC 2150 =(!length%)+2