10
20
30 :
40 OSARGS=&FFDA:OSFILE=&FFDD:OSGBPB=&FFD1:OSFIND=&FFCE
50 GSINIT=&FFC2:GSREAD=&FFC5
60 :
70 DIM mcode% &300:load%=&FFFF0900:ver$="v0.10"
80 :
90 gbpb=&2EE
100 addr=&A8:num=&AC:handle=&AF:lptr=&F2:latch=&FCFF:jim=&FD00
110 FOR P=0 TO 1
120 P%=load%:O%=mcode%
130 [OPT P*3+4
140 .CopyData
150 LDA #0:SEC:SBC addr+0 :\ Number of bytes to page boundary
160 PHA:STA gbpb+5 :\ count b0-b7
170 LDX #0:TAY:BNE P%+3:INX :\ &0xx or &100
180 STX gbpb+6:LDX #0
190 STX gbpb+7:STX gbpb+8 :\ count=&000000xx or &00000100
200 DEX
210 STX gbpb+4:STX gbpb+3 :\ addr=&FFFFxxxx
220 LDA #buffer DIV 256:STA gbpb+2
230 LDA #buffer AND 255:STA gbpb+1 :\ addr=&FFFFbuffer
240 LDA handle:STA gbpb+0 :\ handle
250 LDX #gbpb AND 255
260 LDY #gbpb DIV 256
270 LDA #4:JSR OSGBPB :\ Read from file
280 PLA:LDX gbpb+6:BNE Close :\ 256 bytes unread, end of file
290 PHA:STA num
300 :
310 LDA addr+1:STA latch-0 :\ Select bank
320 LDA addr+2:STA latch-1
330 LDA addr+3:STA latch-2
340 LDX #0:LDY addr+0
350 .CopyBytes
360 LDA buffer,X:STA jim,Y
370 INX:INY:DEC num:BNE CopyBytes
380 PLA:TAX :\ X=number written
390 :
400 CLC:ADC addr+0:STA addr+0:PHP :\ Update addr
410 LDA #0:CPX #1:BCS P%+4:LDA #1 :\ &100 or &0xx
420 PLP:ADC addr+1:STA addr+1
430 LDA #0:ADC addr+2:STA addr+2
440 LDA #0:ADC addr+3:STA addr+3
450 JMP CopyData
460 :
470 .Close
480 LDY handle:LDA #0:JMP OSFIND
490 :
500 \ Code used once, use as buffer area
510 .ctrl
520 .buffer
530 :
540 .start%
550 LDA #1:LDX #addr:LDY #0:JSR OSARGS
560 \ Can't read directly to &F2/3 'cos 4-byte address, would overwrite &F4 ROMNUM
570 LDA addr+0:STA lptr+0:STA ctrl+0 :\ =>filename
580 LDA addr+1:STA lptr+1:STA ctrl+1
590 CLC:JSR GSINIT:BEQ jmpSyntax
600 .SkipName
610 JSR GSREAD:BCC SkipName :\ Step past name
620 JSR SkipSpace:BNE ScanAddr :\ Load address
630 LDX #ctrl AND 255
640 LDY #ctrl DIV 256
650 LDA #5:JSR OSFILE:LDX #3 :\ Read file's info
660 .AddrLp
670 LDA ctrl+2,X:STA addr,X
680 DEX:BPL AddrLp:BMI LoadFile
690 .ScanAddr
700 JSR GetHexDigit:BCC errSyntax :\ Bad address
710 LDX #addr:JSR GetHex
720 .LoadFile
730 LDX ctrl+0:LDY ctrl+1 :\ XY=>filename
740 LDA #&40:JSR OSFIND:TAY:BEQ errNotFound
750 STY handle:JMP CopyData
760 .jmpSyntax
770 JMP errSyntax
780 :
790 .GetHexDigit
800 LDA (lptr),Y
810 CMP #ASC"0":BCC HexDigitBad
820 CMP #ASC"9"+1:BCC HexDigitOk
830 CMP #ASC"A":BCC HexDigitBad
840 AND #&DF
850 CMP #ASC"F"+1:BCS HexDigitBad
860 SBC #7
870 .HexDigitOk
880 SBC #ASC"0"-1:RTS
890 .HexDigitBad
900 CLC:RTS
910 :
920 .GetHex
930 LDA #0
940 STA 0,X:STA 1,X:STA 2,X:STA 3,X
950 .GetHexNext
960 JSR GetHexDigit:BCC SkipSpace
970 PHA:TYA:PHA:LDY #4
980 .GetHexMultiply
990 ASL 0,X:ROL 1,X:ROL 2,X:ROL 3,X
1000 DEY:BNE GetHexMultiply
1010 PLA:TAY:PLA:ORA 0,X:STA 0,X
1020 INY:BNE GetHexNext
1030 :
1040 .SkipSpace1
1050 INY
1060 .SkipSpace
1070 LDA (lptr),Y:CMP #ASC" ":BEQ SkipSpace1
1080 CMP #13:RTS
1090 :
1100 .errNotFound
1110 BRK:EQUB 214:EQUS "File not found"
1120 .errSyntax
1130 BRK:EQUB 220:EQUS "Syntax: XLoad <afsp> (<load>)":BRK
1140 :
1150 EQUS ver$
1160 :
1170 ]:NEXT
1180 IF (P%AND&FFFF)>&B00:PRINT"Code overrun":END
1190 IF buffer>&A00:PRINT"Buffer overrun":END
1200 PRINT"*SAVE XLoad "+STR$~mcode%+" "+STR$~O%+" "+STR$~(start%OR&FFFF0000)+" "+STR$~(load%OR&FFFF0000)