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