10
20
30
40 :
50 DIM S% 500:T%=S%
60 INPUT "6502 code file: "in$
70 INPUT "Output ROM file: "fname$
80 INPUT "Command name: "cmd$
90 INPUT "Version string: "ver$
100 INPUT "Copyright string: (C)"cpy$
110 PROCp(in$):PROCp(fname$):PROCp(cmd$):PROCp(ver$):PROCp(cpy$)
120 CLEAR:DIM S% T%-S%:PROCassem(0):CLEAR:DIM S% T%-S%:PROCassem(2):PROCsm_table
130 A$="*SAVE "+fname$+" "+STR$~(mcode%+M%)+" "+STR$~O%+" FFFF0000 FFFBBC00"
140 PRINTA$;:OSCLIA$:PRINT
150 END
160 :
170 DEFPROCp(A$):$T%=A$:T%=T%+LEN$T%+1:ENDPROC
180 DEFFNg:B%=T%:T%=T%+LEN$T%+1:=$B%
190 DEFPROCassem(pass%)
200 T%=S%:in$=FNg:fname$=FNg:cmd$=FNg:ver$=FNg:cpy$=FNg
210 ver%=VALver$:IFMID$(ver$,2,1)=".":ver%=16*VALLEFT$(ver$,1)+VALMID$(ver$,3,1)
220 DIM ctrl% 31,name% 31:X%=ctrl%:Y%=X%DIV256
230 A%=FNfile(in$,5):IF A%=0:PRINT"File '"in$"' not found":END
240 IF (X%!4 AND X%!8 AND &FFFF)<>&FFFF:PRINT"File '"in$"' is not I/O code":END
250 load%=X%!2:exec%=X%!6:size%=X%!10
260 DIM mcode% size%*2.5+300, L% -1
270 OSWRCH=&FFE3:OSNEWL=&FFE7:OSBYTE=&FFF4:OS_CLI=&FFF7
280 FOR pass%=pass% TO pass%+1
290 opt%=FNsm_pass(pass%)+8+16
300 [OPT opt%
310 .RomStart
320 BRK:EQUW RelocTable
330 JMP Service
340 EQUB &82:EQUB Copyright-RomStart
350 .RomTitle
360 EQUB ver%:EQUS cmd$
370 EQUB &00 :EQUS ver$
380 .Copyright
390 EQUB &00:EQUS "(C)"+cpy$:EQUB 0
400 :
410 .Service
420 CMP #4:BEQ Serv4 :\ *command
430 CMP #9:BNE NotServ9 :\ Not *Help
440 LDA (&F2),Y
450 CMP #13:BNE Serv9Skip :\ Not *Help <cr>
460 JSR OSNEWL:LDX #0
470 .Serv9Lp
480 LDA RomTitle+1,X :\ Print ROM title
490 BNE P%+4:LDA #ASC" " :\ Convert &00 to <spc>
500 CMP #ASC"(":BEQ Serv9Done :\ End at '('
510 JSR OSWRCH:INX:BNE Serv9Lp
520 .Serv9Done
530 JSR OSNEWL
540 .Serv9Skip
550 LDA #9
560 .NotServ9
570 RTS
580 :
590 .Serv4
600 TYA:PHA:DEY:LDX #&FF
610 .Serv4Lp
620 INX:INY:LDA (&F2),Y
630 CMP #ASC".":BEQ Serv4Dot
640 CMP #ASC"!":BCC Serv4End
650 CMP RomTitle+1,X:BEQ Serv4Lp :\ Match with ROM title
660 EOR #&20 :\ Change case
670 CMP RomTitle+1,X:BEQ Serv4Lp :\ Match with ROM title
680 .Serv4Quit
690 PLA:TAY:LDA #4:RTS :\ Restore Y, A and return unclaimed
700 .Serv4End
710 LDA RomTitle+1,X:BNE Serv4Quit
720 DEY
730 .Serv4Dot
740 INY:PLA :\ Step past '.', balance stack
750 JSR Serv4Call
760 LDA #0:RTS :\ Return claimed
770 :
780 .Serv4Call
790 LDA #(load% AND &00FF):STA &A8
800 LDA #(load% AND &FF00) DIV 256:STA &A9
810 LDY #0
820 .TreeLp3
830 LDA src,Y:STA &AA,Y
840 INY:CPY #4:BCC TreeLp3
850 TAY:BEQ TreeLp5:LDY #0
860 .TreeLp4
870 LDA (&AA),Y:STA (&A8),Y
880 INY:BNE TreeLp4
890 INC &A9:INC &AB
900 DEC &AD:BNE TreeLp4
910 .TreeLp5
920 LDA (&AA),Y:STA (&A8),Y
930 INY:CPY &AC:BCC TreeLp5
940 JMP exec%
950 :
960 .src
970 EQUW src+4:EQUW size%
980 .file
990 ]
1000 IF O%+size%<L%:OSCLI"Load "+in$+" "+STR$~O% ELSE PRINT"Data overrun"
1010 P%=P%+size%:O%=O%+size%:RelocTable=P%
1020 NEXT:ENDPROC
1030 :
1040 DEFFNsm_pass(pass%)
1050 IFpass%=0:M%=0
1060 IFpass%=1:M%=O%-mcode%
1070 P%=&8100-128*(pass%AND2)
1080 O%=mcode%+M%*(pass%AND2)DIV2
1090 IFpass%=1:IF O%+M%*2.125>L%:PRINT"Code overrun":END
1100 =VALMID$("4646",pass%+1,1)
1110 :
1120 DEFPROCsm_table
1130 base80%=mcode%+M%:base81%=mcode%:byte%=0:count%=0:off%=0:REPEAT
1140 byte80%=base80%?off%:byte81%=base81%?off%:IF off%>=M%:byte80%=&80:byte81%=&80
1150 IF ((byte81%-byte80%) AND &FE)<>0:PRINT "ERROR: Offset by more than one page at &";~&8000+off%
1160 IF (byte80% AND &C0)=&80:byte%=byte%DIV2+128*(byte81%-byte80%):count%=count%+1
1170 IF count%=8:?O%=byte%:O%=O%+1:byte%=0:count%=0
1180 off%=off%+1:UNTILoff%>=M% AND count%=0
1190 ENDPROC
1200 :
1210 DEFFNfile(A$,A%):$name%=A$:?X%=name%:X%?1=name%DIV256:=(USR&FFDD)AND&FF