10
20 :
30 IF HIMEM-LOMEM<&4200:MODE &87:IF HIMEM-LOMEM<&4200:VDU 28,0,24,39,19:HIMEM=&77C0
40 PRINT"Build fast ROMFS ROM"
50 DIM ctrl% 19, name% 255, mem% &3FFF:X%=ctrl%:Y%=X%DIV256
60 INPUT LINE "ROM title: "title$:IF title$="":title$="ROMFS"
70 INPUT LINE "ROM copyright: (C)"copy$
80 PROCcrc:PROCheader
90 PRINT "Enter files to add, end with RETURN"
100 REPEAT
110 INPUT LINE "File to add: "in$
120 IF in$<>"":INPUT LINE "Filename to use: "name$:IF name$="":name$=in$
130 IF in$<>"":PROCadd
140 UNTIL in$=""
150 ?O%=ASC"+":O%=O%+1
160 REPEAT:INPUT LINE "Save ROM as: "out$:IF out$="":VDU11
170 UNTIL out$<>"":A$="SAVE "+out$+" "+STR$~mem%+" "+STR$~O%+" 0 FFFBBC00"
180 PRINT"Saving ";out$;:OSCLIA$:PRINT
190 END
200 :
210 DEFPROCcrc
220 DIM crc16% 40:crc=&70:addr=&72:num=&74
230 FOR opt%=0 TO 2 STEP 2
240 P%=crc16%
250 [OPT opt%
260 .bytelp:LDX #8:LDA (addr-8 AND &FF,X):EOR crc+0
270 .rotlp:ASL crc+1:ROL A:BCC clear
280 TAY:LDA crc+1:EOR #&21:STA crc+1:TYA:EOR #&10
290 .clear:DEX:BNE rotlp:STA crc+0:INC addr+0:BNE next:INC addr+1
300 .next:DEC num:BNE bytelp:RTS
310 ]NEXT
320 ENDPROC
330 :
340 DEFPROCheader
350 FOR opt%=4 TO 6 STEP 2
360 P%=&8000:O%=mem%
370 [OPT opt%
380 BRK:BRK:BRK:JMP Service
390 EQUB &82:EQUB Copyright-&8000
400 EQUB &00:EQUS title$
410 .Copyright
420 EQUB &00:EQUS "(C)":EQUS copy$:EQUB &00
430 .Service
440 PHA:CMP #13:BEQ Serv13:CMP #14:BEQ Serv14
450 .ServQuit
460 PLA:RTS
470 .Serv13
480 TYA:EOR #15:CMP &F4:BCC ServQuit :\ Not this ROM
490 LDA &F4:EOR #15:STA &F5
500 LDA #Data AND 255:STA &F6 :\ Point to start of RFS data
510 LDA #Data DIV 256:STA &F7
520 BNE ServExit
530 .Serv14Slow
540 LDA (&F6),Y:TAY:LDA #1:JSR AddPTR :\ Get single byte
550 .ServExit
560 PLA:LDA #0:RTS
570 .Serv14
580 LDA &F5:EOR #15:CMP &F4:BNE ServQuit:\ Not this ROM
590 LDY #0 :\ Prepare offset
600 LDA &E2:AND #8:BNE Serv14Slow :\ Cataloging
610 LDA &C2:CMP #4:BNE Serv14Slow :\ Not fetching data block
620 LDA &27A:BPL Serv14lp0 :\ No Tube, with CS from previous CMP
630 LDA &B2:AND &B3:CMP #&FF:PHP :\ CC=Tube, CS=I/O
640 .Serv14lp
650 PLP :\ Get saved Tube/IO flag
660 .Serv14lp0
670 PHP:BCS Serv14io :\ Save Tube/IO flag, jump if I/O
680 .Serv14tube
690 LDA (&F6),Y:STA &FEE5 :\ Send data to Tube data FIFO
700 JSR Delay:JSR Delay :\ Inter-byte Tube delay
710 INY:CPY &3C8:BNE Serv14tube
720 BEQ Serv14Next
730 .Serv14io
740 LDA (&F6),Y:STA (&B0),Y :\ Copy data directly to memory
750 INY:CPY &3C8:BNE Serv14io
760 .Serv14Next
770 TYA:JSR AddPTR:LDA #2:JSR AddPTR :\ Step past data and CRC
780 LDA &3C9:BEQ Serv14Finished :\ Last block.hi=0, was last block
790 INC &B1:INC &F7 :\ Step to next data block
800 LDA (&F6),Y:CMP #ASC"#":BNE Serv14Last:\ Not short header, last block
810 LDA #1 :\ Step past single header byte
820 .Serv14Next2
830 JSR AddPTR:BCC Serv14lp :\ Do next data block
840 .Serv14Last
850 INY:LDA (&F6),Y:BNE Serv14Last :\ Step past filename
860 TYA:CLC:ADC #11:TAY:LDA (&F6),Y:STA &3C8:\ Get final block length
870 LDA #0:STA &3C9 :\ Set top byte=0 to flag last block
880 TYA:CLC:ADC #9 :\ Prepare to point to final data block
890 LDY #0:BEQ Serv14Next2 :\ Jump to update pointer and fetch last block
900 .Serv14Finished
910 PLP:STA &BE:STA &BF:STA &C2 :\ CRC=Ok, Progress=Done
920 LDA #&80:STA &BD:STA &3CA :\ b7=last block
930 JMP ServExit
940 .AddPTR
950 CLC:ADC &F6:STA &F6
960 LDA &F7:ADC #0:STA &F7
970 .Delay
980 RTS
990 .Data
1000 ]NEXT
1010 ENDPROC
1020 :
1030 DEFPROCadd
1040 in%=0:A%=FNfile(in$,5):Load%=X%!2:Exec%=X%!6:Size%=X%!10:Attr%=X%!14
1050 IF A%:IF O%-mem%+Size%>&3F00:PRINT"Not enough space":CLOSE#in%:in%=0:ENDPROC
1060 IF A%=1:in%=OPENIN(in$)
1070 IF in%=0:PRINT"File '"in$"' not found":ENDPROC
1080 name$=LEFT$(name$,8):
1090 hdr0%=O%:Block%=0
1100 REPEAT
1110 hdr%=O%:BlkLen%=Size%:IF BlkLen%>256:BlkLen%=256
1120 Flag%=0:IF Size%<257:Flag%=&80:IF Size%=0:Flag%=&C0
1130 $O%="*"+name$:O%=O%+1+LENname$:?O%=0
1140 O%!1=Load%:O%!5=Exec%:O%!9=Block%:O%!11=BlkLen%:O%?13=Flag%:O%!14=0:O%=O%+18
1150 IF Block%=0 OR Flag%<>0:!crc=0:!addr=hdr%+1:!num=O%-hdr%-1:CALL crc16%:!O%=!crc:O%=O%+2 ELSE ?hdr%=ASC"#":O%=hdr%+1
1160 PROCgbpb(4,in%,O%,BlkLen%,0)
1170 !crc=0:!addr=O%:!num=BlkLen%:CALL crc16%
1180 O%!BlkLen%=!crc:O%=O%+BlkLen%+2
1190 Size%=Size%-BlkLen%:Block%=Block%+1
1200 UNTIL Size%=0
1210 hdr0%!(15+LENname$)=O%-mem%+&8000
1220 !crc=0:!addr=hdr0%+1:!num=18+LENname$:CALL crc16%
1230 hdr0%?(19+LENname$)=crc?0:hdr0%?(20+LENname$)=crc?1
1240 hdr%!(15+LENname$)=O%-mem%+&8000
1250 !crc=0:!addr=hdr%+1:!num=18+LENname$:CALL crc16%
1260 hdr%?(19+LENname$)=crc?0:hdr%?(20+LENname$)=crc?1
1270 CLOSE#in%:in%=0
1280 ENDPROC
1290 :
1300 DEFFNfile(A$,A%):$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF
1310 DEFPROCgbpb(A%,chn%,addr%,num%,ptr%):?X%=chn%:X%!1=addr%:X%!5=num%:X%!9=ptr%:CALL&FFD1:ENDPROC