10
20
30
40 :
50
60
70
80
90
100
110 :
120 DIM mcode% &200:load%=&FFFF0900
130 OSARGS=&FFDA:OSFILE=&FFDD:OSBYTE=&FFF4:OSWRCH=&FFEE
140 lptr=&A8:buf=&A8:dst=&AA
150 rambuf=&2000 :
160 nbytes=64 :
170 ver$="2.11"
180 :
190 FOR P=0 TO 1
200 P%=load%:O%=mcode%
210 [OPT P*2+4
220 .errSyntax
230 BRK:EQUB 220:EQUS "Syntax: EELOAD <afsp>|@ <rom>":BRK
240 :
250 .exec%
260 LDA #0:LDX #1:JSR OSBYTE :\ Read machine type
270 TXA:BNE InitNotElectron
280 LDA #&05:STA ROMSEL+1 :\ Use Electron ROMSEL
290 DEC ROMTABLE+1 :\ Use Electrom ROM table
300 .InitNotElectron
310 :
320 LDA #1:LDX #lptr:JSR OSARGS :\ Get command line, Y=0 from above
330 LDA (lptr),Y:CMP #13:BEQ errSyntax :\ No parameters
340 :
350 \ (lptr),Y => filename, skip past to <rom>
360 \ ----------------------------------------
370 DEY :\ Prepare for next INY
380 .SkipToSpace
390 INY:LDA (lptr),Y
400 CMP #ASC"!":BCS SkipToSpace :\ Step past filename
410 DEY :\ Prepare for next INY
420 .SkipSpace
430 INY:LDA (lptr),Y
440 CMP #ASC" ":BEQ SkipSpace :\ Step past spaces
450 CMP #13:BEQ errSyntax :\ Only one parameter
460 :
470 \ (lptr),Y now => <rom>
480 \ ---------------------
490 LDA (lptr),Y :\ Get <rom>
500 CMP #ASC"0":BCC errSyntax :\ <'0' - error
510 CMP #ASC"9"+1:BCC decnum :\ '0'-'9' - decimal digit
520 CMP #ASC"A":BCC errSyntax :\ >'9' <'A' - error
530 AND #&DF
540 CMP #ASC"G":BCS errSyntax :\ >'F' - error
550 SBC #6 :\ Convert hex digit to offset from '9'
560 .decnum
570 AND #15:TAX :\ Convert to binary
580 CMP #1:BNE romnumber :\ Not 1, don't check for 1x
590 INY:LDA (lptr),Y :\ Look for a second digit
600 CMP #ASC"!":BCC romnumber :\ Single digit, use as decimal number
610 CMP #ASC"0":BCC errSyntax :\ Can only be '10'-'15'
620 CMP #ASC"6":BCS errSyntax
630 AND #15:ADC #10:TAX :\ Convert to binary
640 .romnumber
650 :\ X=ROM number to write to
660 :
670 \ First, test the device is writable before we overwrite memory
680 \ -------------------------------------------------------------
690 LDA &F4:PHA :\ Save current ROM
700 PHP:SEI :\ Prevent accidently calling EEPROM
710 JSR SelectRom :\ Page in the requested ROM
720 LDA &8008:EOR #&AA:TAX:STA &8008 :\ Try toggling version byte
730 NOP:CMP &8008:BEQ testOK :\ Written immediately, it must be RAM
740 LDA &8008:CMP &8008 :\ Try two successive reads
750 BNE testEEP :\ If not the same, probably EEPROM
760 BRK:EQUB 135:EQUS "Device is ROM":BRK :\ Error 135='Not SRAM'
770 .testEEP
780 LDA &8008:CMP &8008:BNE testEEP :\ Loop until two identical reads
790 CPX &8008:BEQ testOK :\ Settled at correct data, it's ok
800 BRK:EQUB 134:EQUS "Device is locked":BRK :\ Error 134='ROM in use'
810 .testOK
820 TXA:EOR #&AA:STA &8008 :\ Restore original value
830 .testOKlp
840 LDA &8008:CMP &8008:BNE testOKlp :\ Loop until two identical reads
850 \ Need to wait until data settles as while it is settling the EEPROM
860 \ returns status data instead of its actual contents. Need to avoid
870 \ accidently trying to execute that status data via a sideways ROM call.
880 :
890 \ Now load the file
900 \ -----------------
910 LDY #0:LDA (lptr),Y :\ Check first character of filename
920 CMP #ASC"@":BNE loadfile :\ Not *EELOAD @...
930 INY:LDA (lptr),Y :\ Check for following space
940 CMP #ASC" ":BEQ copyimage :\ *EELOAD @ <rom>, use image in RAM
950 .loadfile
960 LDA lptr+0:STA file+0 :\ Copy filename pointer to OSFILE block
970 LDA lptr+1:STA file+1
980 LDA ROMSEL+1
990 CMP #&05:BNE loadfile2 :\ Not Electron, continue
1000 LDA #132:JSR OSBYTE :\ Read top of user memory
1010 CPY #&60:BCS loadfile2 :\ Small screen MODE, continue
1020 LDA #22:JSR OSWRCH :\ Change to a small screen MODE
1030 LDA #7:JSR OSWRCH
1040 .loadfile2
1050 LDX #file AND 255:LDY #file DIV 256
1060 LDA #255:JSR OSFILE :\ Load the file
1070 :
1080 \ Now program the device from the image in memory
1090 \ -----------------------------------------------
1100 .copyimage
1110 LDA #0:LDX &F4
1120 .ROMTABLE
1130 STA &2A1,X :\ Remove ROM from ROM table
1140 STA buf+0:STA dst+0
1150 LDA #rambuf DIV 256:STA buf+1 :\ buf=>rambuf at &2000
1160 LDA #&80:STA dst+1 :\ dst=&8000
1170 .proglp1
1180 LDY #0
1190 .proglp2
1200 LDA (buf),Y:STA (dst),Y :\ Copy to EEPROM
1210 INY:CPY #nbytes:BNE proglp2 :\ Loop for 'nbytes'
1220 :
1230 \ Now check the data has written correctly
1240 \ ----------------------------------------
1250 LDX #0:LDY #0
1260 .proglp3
1270 LDA (dst),Y:CMP (dst),Y :\ Read twice to see if matches
1280 BNE proglp3 :\ Keep testing until it matches
1290 CMP (buf),Y :\ Has it settled to correct value?
1300 BEQ progmatch:INX :\ If it doesn't match, inc. X
1310 .progmatch
1320 INY:CPY #nbytes:BNE proglp3 :\ X now holds number of differences
1330 TXA:BEQ write_ok
1340 BRK:EQUB 132:EQUS "Write error":BRK :\ Error 132='Bad bank' (not usable somehow)
1350 :
1360 .write_ok
1370 CLC
1380 LDA #nbytes:ADC buf+0:STA buf+0 :\ Update buffer address
1390 LDA #0:ADC buf+1:STA buf+1
1400 LDA #nbytes:ADC dst+0:STA dst+0 :\ Update dest. address
1410 LDA #0:ADC dst+1:STA dst+1
1420 CMP #&C0:BNE proglp1 :\ Keep going until end of ROM space
1430 :
1440 \ All done, restore and return
1450 \ ----------------------------
1460 PLP :\ Restore IRQs
1470 PLA:TAX :\ Restore ROM
1480 :
1490 .SelectRom
1500 LDA #12:JSR SelectRom2:TXA :\ Electron ROM pre-select
1510 .SelectRom2
1520 STA &F4
1530 .ROMSEL
1540 STA &FE30:RTS
1550 :
1560 .file
1570 EQUW 0 :\ Filename
1580 EQUD &FFFF0000+rambuf :\ Address to load to
1590 EQUD 0:EQUD 0:EQUD 0 :\ 0=use specified address
1600 EQUS ver$
1610 ]:NEXT
1620 PRINT" *SAVE EELOAD ";~mcode%;" ";~O%;" ";~exec%OR&FFFF0000;" ";~load%