10
20
30 :
40 OSBYTE=&FFF4:OSFILE=&FFDD:OSARGS=&FFDA
50 DIM mcode% &200
60 load%=&FFFF0900
70 :
80 FOR P=0 TO 1
90 O%=mcode%:P%=load%
100 [OPT P*3+4+16
110 .go%
120 LDA #1:LDX #&A8:LDY #0:JSR OSARGS
130 LDA (&A8),Y:CMP #13:BEQ reset:TAY \ *RESET<cr> or *RESET <num>
140 .reset
150 TYA:AND #7:PHA \ Reduce to 0-7
160 LDX #253:LDA #163:JSR OSBYTE \ Initially try OSBYTE call
170 PLA \ Otherwise, do manually
180 :
190 .ForceReset
200 \ A=RESET type
210 \ 0=Soft Break
220 \ 1=Power On
230 \ 2=Hard Break
240 :
250 SEI:CLD :\ Disable IRQs, ensure binary mode
260 LDX #&FF:TXS:PHA :\ Reset stack, save Break type
270 LDA #&8F:LDX #&0C
280 LDY #&FF:JSR OSBYTE :\ Claim NMIs
290 LDX #&40:STX &0D00 :\ Disable NMIs
300 LDA #0:JSR OSBYTE :\ Read machine type
310 LDA &FFFC:STA &A8 :\ &A8/9=>RESET code
320 LDA &FFFD:STA &A9
330 TXA:BEQ ResetElk :\ Jump if &00=Electron
340 :
350 LDA #&C0:STA &FEA0 :\ Reset hardware
360 LDA #&A0:STA &FEE0 :\ Tube Reset
370 LDA #&20:STA &FEE0 :\ Release Tube Reset
380 PLA:BEQ ResetJump :\ Soft Break
390 LSR A:BCC ResetHard :\ Hard Reset is fiddly
400 LDA #127:STA &FE4E :\ Reset system VIA
410 .ResetJump
420 JMP (&FFFC) :\ Enter RESET code
430 :
440 .ResetElk
450 LDA #&C0:STA &FC28 :\ Reset Electron hardware
460 LDA #&A0:STA &FCE0 :\ Electron Tube Reset
470 LDA #&20:STA &FCE0 :\ Release Electron Tube Reset
480 PLA:BEQ ResetJump :\ Soft Break
490 LDY #24:LSR A:BCS ResetElkJump :\ Power On
500 TAY:DEX :\ Y=0, X=&FF
510 .ResetElkHard
520 LDA (&A8),Y:INY
530 CMP #&20:BNE ResetElkHard :\ Look for JSR
540 INY:INY:LDA (&A8),Y
550 CMP #&08:BNE ResetElkHard :\ Look for PHP
560 .ResetElkJump
570 LDA &F4:ORA #&F0:STA &FE05 :\ Set up the ULA, set M=Ctrl Pressed
580 PHA:PHP :\ Push NotPowerOn, push CTRL pressed
590 BMI ResetAddJump :\ Branch to jump into reset code
600 :
610 .ResetHard
620 LDY #&0F:STY &FE42 :\ SysVIA PortB=iiiioooo
630 .ResetIO
640 DEY:STY &FE40 :\ Write to I/O latch
650 CPY #&09:BCS ResetIO :\ Loop to set up internal I/O
660 CPX #&03:BCS ResetMaster
670 :
680 \ Read BBC keyboard links
690 LDX #&09
700 .ResetBBCLinks
710 LDY #&03:STY &FE40
720 LDY #&7F:STY &FE43
730 STX &FE4F:LDX &FE4F
740 CPX #&80:ROR &FC :\ Rotate keystate in bit 7 into &FC
750 DEX:BNE ResetBBCLinks
760 ROL &FC :\ &FC holds link state
770 :
780 LDY #0 :\ Y=0, X=&FF
790 .ResetBBClp
800 LDA (&A8),Y:INY
810 CMP #&26:BNE ResetBBClp :\ Look for 'ROL zp'
820 .ResetAddJump
830 TYA:ADC &A8:STA &A8 :\ Update (&A8) to next instruction
840 LDA #0:STA &028D:STA &FE00 :\ Initialise last BREAK flag and Elk ULA
850 ADC &A9:STA &A9 :\ (A8)=>continuation of reset code
860 SEC:LDA #2:JMP (&A8) :\ CS=CTRL pressed, jump to RESET code
870 :
880 .ResetMaster
890 LDY #0
900 .ResetMasterLp1
910 LDA (&A8),Y:INY :\ Look for JSR
920 CMP #&20:BNE ResetMasterLp1
930 INY:INY:LDA (&A8),Y :\ Check if followed by JMP
940 CMP #&4C:BNE ResetMasterLp1
950 INY:LDA (&A8),Y:STA &F6 :\ (F6)=>reset code in ROM 15
960 INY:LDA (&A8),Y:STA &F7
970 .ResetMasterLp2
980 JSR ResetROMByte :\ Read byte from ROM 15
990 CMP #&E0:BNE ResetMasterLp2 :\ Look for 'CPX'
1000 JSR ResetROMByte :\ Read next byte from ROM 15
1010 CMP #&80:BNE ResetMasterLp2 :\ Look for 'CPX #&80'
1020 \ &F6/7 now points to rest of RESET code
1030 :
1040 LDA #&53:STA &FE8E :\ Write to hardware I/O RESET
1050 TRB &0366 :\ Reset VDU 23,16 settings
1060 LDX #&FF:STX &FE63 :\ User VIA Port A=output
1070 LDA #&CF:STA &FE42 :\ System VIA Port B=ooiioooo
1080 LDA #&0D:STA &DC00 :\ Command line = <cr>
1090 LDA #&DC:STA &DF05:STZ &DF04 :\ Point to command line
1100 STZ &DFDD :\ Clear *MOVE flag
1110 LDX #(ResetCodeEnd-ResetCode-1) AND &FF
1120 .ResetLoop
1130 LDA ResetCode,X:STA &100,X
1140 DEX:BPL ResetLoop:TXS :\ Reset stack
1150 LDA &F7:AND #&40 :\ Test if code is in SROM or I/O area
1160 STA &FE34:STA &FC :\ Set memory map according to &F7
1170 LDA #&0F:STA &028E :\ Set keypad SHIFT setting, prepare ROM=15
1180 PHA:SEC:JMP &100 :\ Push <>0=Not PowerOn, CS=CTRL pressed
1190 :
1200 .ResetCode
1210 STA &FE30 :\ Page in MOS ROM (IRQs are off)
1220 JMP (&F6) :\ Jump to RESET code
1230 .ResetCodeEnd
1240 :
1250 .ResetROMByte
1260 LDA #&40:STA &FE34 :\ Set memory map
1270 LDA (&F6) :\ Read byte manually
1280 BIT &F7:BVS ResetByte :\ Exit if in high memory
1290 LDY #&0F:JSR &FFB9 :\ Read byte from ROM 15
1300 .ResetByte
1310 INC &F6:BNE P%+4:INC &F7 :\ Increment address
1320 RTS
1330 :
1340 EQUS "0.10"
1350 ]NEXT
1360 PRINT"*SAVE RESET ";~mcode%;" ";~O%;" ";~go% OR &FFFF0000;" ";~load%'