10 REM > XLoad/src v0.10 18-Feb-2015 J.G.Harston
   20 REM Source for *XLOAD - load to page-wide extended RAM in JIM
   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)