> RSTROM/src A Implements *RESET and OSBYTE 163,253 to cause machine reset : (- OSBYTE 163,253,n causes a machine reset 2& n=reset type as for OSBYTE 253 ) calls OSBYTE 163,253,n n$ Defaults to n=0 for Soft Break x: #assem(0)::assem(2):sm_table FA$="*SAVE "+fname$+" "+~(mcode%+M%)+" "+~O%+" FFFF0000 FFFBBC00" A$;:A$:  : assem(pass%) DOSBYTE=&FFF4:OSFILE=&FFDD:OSARGS=&FFDA:OSNEWL=&FFE7:OSWRCH=&FFEE 6ver$="0.10":date$=" (16 Apr 2018)":fname$="RSTROM"  mcode% &1400, L%-1 :  pass%=pass% pass%+1 opt%=sm_pass(pass%)+8+16 [OPT opt%  .rombase EQUB &00:EQUW RelocTable JMP Service "#EQUB &82:EQUB copyright-rombase , .ROMTitle 6EQUB ver$*10:EQUS "RESET" @EQUB &00:EQUS ver$+date$ J.copyright T"EQUB &00:EQUS "(C)J.G.Harston" ^ EQUB &00 h: r .Service |)CMP #4:BEQ Serv4 :\ *command 'CMP #7:BEQ Serv7 :\ OSBYTE *CMP #9:BNE NotServ9 :\ Not *Help LDA (&F2),Y /CMP #13:BNE Serv9Skip :\ Not *Help JSR OSNEWL:LDX #0  .Serv9Lp 0LDA ROMTitle+1,X :\ Print ROM title 3BNE P%+4:LDA #" " :\ Convert &00 to )CMP #"(":BEQ Serv9Done :\ End at '(' JSR OSWRCH:INX:BNE Serv9Lp .Serv9Done JSR OSNEWL .Serv9Skip  LDA #9  .NotServ9 RTS &: 0 .Serv4 :TYA:PHA:DEY:LDX #&FF D .Serv4Lp NINX:INY:LDA (&F2),Y XCMP #".":BEQ Serv4Dot bCMP #"!":BCC Serv4End l8CMP ROMTitle+1,X:BEQ Serv4Lp :\ Match with ROM title v- #&20 :\ Change case 8CMP ROMTitle+1,X:BEQ Serv4Lp :\ Match with ROM title .Serv4Quit -PLA:TAY :\ Restore Y .Serv4Exit BLDA #4:RTS :\ Restore A and return unclaimed  .Serv4End "LDA ROMTitle+1,X:BNE Serv4Quit DEY  .Serv4Dot 1INY:LDA (&F2),Y :\ Step past '.' 1CMP #" ":BEQ Serv4Dot :\ Skip any spaces : /LDY #0:CMP #13:BEQ Serv4Reset:\ *RESET . #7:TAY :\ *RESET  .Serv4Reset 1LDX #253:LDA #163:JSR OSBYTE :\ Send the call  DPLA:TAY:PLA :\ If we get back, return unclaimed * .ServQuit 4RTS >: H .Serv7 R!LDA &EF:CMP #163:BNE ServQuit \!LDA &F0:CMP #253:BNE ServQuit f3LDA &F1 :\ *FX 163,253,n p: z.ForceReset \ A=RESET type \ 0=Soft Break \ 1=Power On \ 2=Hard Break : FSEI:CLD :\ Disable IRQs, ensure binary mode BLDX #&FF:TXS:PHA :\ Reset stack, save Break type LDA #&8F:LDX #&0C 0LDY #&FF:JSR OSBYTE :\ Claim NMIs 2LDX #&40:STX &0D00 :\ Disable NMIs 7LDA #0:JSR OSBYTE :\ Read machine type 7LDA &FFFC:STA &A8 :\ &A8/9=>RESET code LDA &FFFD:STA &A9 :TXA:BEQ ResetElk :\ Jump if &00=Electron : 4LDA #&C0:STA &FEA0 :\ Reset hardware $0LDA #&A0:STA &FEE0 :\ Tube Reset .8LDA #&20:STA &FEE0 :\ Release Tube Reset 80PLA:BEQ ResetJump :\ Soft Break B:LSR A:BCC ResetHard :\ Hard Reset is fiddly L6LDA #127:STA &FE4E :\ Reset system VIA V.ResetJump `6JMP (&FFFC) :\ Enter RESET code j: t .ResetElk ~=LDA #&C0:STA &FC28 :\ Reset Electron hardware 9LDA #&A0:STA &FCE0 :\ Electron Tube Reset ALDA #&20:STA &FCE0 :\ Release Electron Tube Reset 0PLA:BEQ ResetJump :\ Soft Break .LDY #24:LSR A:BCS ResetElkJump :\ Power On 0TAY:DEX :\ Y=0, X=&FF .ResetElkHard LDA (&A8),Y:INY 2CMP #&20:BNE ResetElkHard :\ Look for JSR INY:INY:LDA (&A8),Y 2CMP #&08:BNE ResetElkHard :\ Look for PHP .ResetElkJump GLDA &F4:A #&F0:STA &FE05 :\ Set up the ULA, set M=Ctrl Pressed HPHA:PHP :\ Push NotPowerOn, push CTRL pressed  DBMI ResetAddJump :\ Branch to jump into reset code : .ResetHard (;LDY #&0F:STY &FE42 :\ SysVIA PortB=iiiioooo 2 .ResetIO <8DEY:STY &FE40 :\ Write to I/O latch FACPY #&09:BCS ResetIO :\ Loop to set up internal I/O PCPX #&03:BCS ResetMaster Z: d\ Read BBC keyboard links n LDX #&09 x.ResetBBCLinks LDY #&03:STY &FE40 LDY #&7F:STY &FE43 STX &FE4F:LDX &FE4F GCPX #&80:ROR &FC :\ Rotate keystate in bit 7 into &FC DEX:BNE ResetBBCLinks :ROL &FC :\ &FC holds link state : 0LDY #0 :\ Y=0, X=&FF .ResetBBClp LDA (&A8),Y:INY 7CMP #&26:BNE ResetBBClp :\ Look for 'ROL zp' .ResetAddJump FTYA:ADC &A8:STA &A8 :\ Update (&A8) to next instruction LLDA #0:STA &028D:STA &FE00 :\ Initialise last BREAK flag and Elk ULA FADC &A9:STA &A9 :\ (A8)=>continuation of reset code ISEC:LDA #2:JMP (&A8) :\ CS=CTRL pressed, jump to RESET code ": ,.ResetMaster 6 LDY #0 @.ResetMasterLp1 J2LDA (&A8),Y:INY :\ Look for JSR TCMP #&20:BNE ResetMasterLp1 ^>INY:INY:LDA (&A8),Y :\ Check if followed by JMP hCMP #&4C:BNE ResetMasterLp1 r@INY:LDA (&A8),Y:STA &F6 :\ (F6)=>reset code in ROM 15 |INY:LDA (&A8),Y:STA &F7 .ResetMasterLp2 ;JSR ResetROMByte :\ Read byte from ROM 15 4CMP #&E0:BNE ResetMasterLp2 :\ Look for 'CPX' @JSR ResetROMByte :\ Read next byte from ROM 15 9CMP #&80:BNE ResetMasterLp2 :\ Look for 'CPX #&80' ,\ &F6/7 now points to rest of RESET code : ALDA #&53:STA &FE8E :\ Write to hardware I/O RESET  ;LDA #&DC:STA &DF05 :\ Point to command line EQUB &9C:EQUW &DF04:\ STZ 3EQUB &9C:EQUW &DFDD:\ STZ :\ Clear * flag )LDX #(ResetCodeEnd-ResetCode-1) &FF &.ResetLoop 0LDA ResetCode,X:STA &100,X :1DEX:BPL ResetLoop:TXS :\ Reset stack DGLDA &F7: #&40 :\ Test if code is in SROM or I/O area NESTA &FE34:STA &FC :\ Set memory map according to &F7 XNLDA #&0F:STA &028E :\ Set keypad SHIFT setting, prepare ROM=15 bKPHA:SEC:JMP &100 :\ Push <>0=Not PowerOn, CS=CTRL pressed l: v.ResetCode DSTA &FE30 :\ Page in MOS ROM (IRQs are off) 8JMP (&F6) :\ Jump to RESET code .ResetCodeEnd : .ResetROMByte 4LDA #&40:STA &FE34 :\ Set memory map 8EQUB &B2:EQUB &F6:\ LDA (&F6) :\ Read byte manually P%=&8100-128*(pass%2) HO%=mcode%+M%*(pass%2)2 R/pass%=1: O%+M%*2.125>L%:"Code overrun": \="4647",pass%+1,1) f: psm_table z>base80%=mcode%+M%:base81%=mcode%:byte%=0:count%=0:off%=0: Pbyte80%=base80%?off%:byte81%=base81%?off%: off%>=M%:byte80%=&80:byte81%=&80 ] ((byte81%-byte80%) &FE)<>0 "ERROR: Offset by more than one page at &";~&8000+off% M (byte80% &C0)=&80:byte%=byte%2+128*(byte81%-byte80%):count%=count%+1 1 count%=8:?O%=byte%:O%=O%+1:byte%=0:count%=0 $off%=off%+1:off%>=M% count%=0