Difference between revisions of "Reset from software"

From BeebWiki
Jump to: navigation, search
(Reset 2 - Hard Reset)
m (Tweeked layout for updated stylesheet.)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
===Causing a Reset in software===
+
__TOC__
 +
Pressing the BREAK key causes a 6502 RESET which jumps via the 6502's RESET
 +
vector to the BBC's startup code. Sometimes a program wants to cause a
 +
reset to restart the computer.
 +
 
 +
It is not actually possible to cause a reset without physically pressing the
 +
BREAK key or otherwise activating the hardware RESET line. Programs often
 +
just jump through the RESET vector to call the startup code, typically with
 +
CALL !-4 (or worse, jump directly to the absolute address of the startup code
 +
in one particular operating system).
 +
 
 +
However, this has limitations.
 +
 
 +
It does not actually reset the computer, as hardware is only reset by the
 +
actual hardware RESET line. It leaves hardware in an un-reset state which
 +
can cause problems with the startup code that expects to find the hardware
 +
already reset by the hardware RESET line.
 +
 
 +
It hangs second processors as it leaves the two processors out of sync with
 +
each other. One has entered its startup code, while the other is still
 +
executing its program code.
  
*** STILL BEING EDITED ***
+
Also, as the startup code reads the physical state of the CTRL key, just
 +
jumping through the RESET vector won't cause a Hard Break unless the user
 +
happens to be pressing the CTRL key. A memory-wipe reset can be done by
 +
using <code>'''*FX200,2'''</code> or <code>'''*FX200,3'''</code> or a
 +
Power-On reset can be performed by resetting the System VIA, but that is
 +
more destructive than a Hard Reset as it wipes all memory - not something
 +
that may be wanted.
  
 +
To perform a clean reset:
 +
* The NMIs must be claimed and disabled
 +
* Hardware must be manually reset
 +
* The Tube must be reset
 +
* Any startup state needs to be set up
 +
* The appropriate part of the MOS RESET code needs to be entered
  
Note that this code has to run in the I/O processor.
+
==Reset routines==
 +
The following routines will generate a machine reset of the three types defined
 +
by [[OSBYTE &FD]]. Note that this code has to run in the I/O processor.
  
==Reset 0 - Soft Reset==
+
===Reset 0 - Soft Reset===
 
A Soft Reset is the simplest to perform. Claim the NMIs, reset the Tube and
 
A Soft Reset is the simplest to perform. Claim the NMIs, reset the Tube and
 
enter the RESET code. This code will cause a Soft Reset resulting in
 
enter the RESET code. This code will cause a Soft Reset resulting in
OSBYTE 253 being set to 0.
+
[[OSBYTE &FD]] being set to 0.
  
 
     .ResetSoft
 
     .ResetSoft
Line 17: Line 51:
 
     LDA #0:LDX #1:JSR OSBYTE      :\ Read machine type
 
     LDA #0:LDX #1:JSR OSBYTE      :\ Read machine type
 
     TXA:BEQ ResetElk              :\ Jump if &00=Electron
 
     TXA:BEQ ResetElk              :\ Jump if &00=Electron
 +
    LDA #&C0:STA &FEA0            :\ Reset hardware
 
     LDA #&A0:STA &FEE0            :\ Tube Reset
 
     LDA #&A0:STA &FEE0            :\ Tube Reset
 
     LDA #&20:STA &FEE0            :\ Release Tube Reset
 
     LDA #&20:STA &FEE0            :\ Release Tube Reset
Line 22: Line 57:
 
     :
 
     :
 
     .ResetElk
 
     .ResetElk
 +
    LDA #&C0:STA &FCA0            :\ Electron Reset hardware
 
     LDA #&A0:STA &FCE0            :\ Electron Tube Reset
 
     LDA #&A0:STA &FCE0            :\ Electron Tube Reset
 
     LDA #&20:STA &FCE0            :\ Release Electron Tube Reset
 
     LDA #&20:STA &FCE0            :\ Release Electron Tube Reset
 
     JMP (&FFFC)                    :\ Jump to RESET
 
     JMP (&FFFC)                    :\ Jump to RESET
  
==Reset 1 - PowerOn Reset==
+
===Reset 1 - PowerOn Reset===
 
A Power-On Reset is only slightly different. Normally, the MOS checks
 
A Power-On Reset is only slightly different. Normally, the MOS checks
 
the System VIA interupt bit to test if a RESET is from a power on, so
 
the System VIA interupt bit to test if a RESET is from a power on, so
Line 37: Line 73:
 
though the ULA power-on bit has been read.
 
though the ULA power-on bit has been read.
  
This code will cause a Power-On Reset resulting in OSBYTE 253 being
+
This code will cause a Power-On Reset resulting in [[OSBYTE &FD]] being
 
set to 1.
 
set to 1.
  
Line 46: Line 82:
 
     LDA #0:LDX #1:JSR OSBYTE      :\ Read machine type
 
     LDA #0:LDX #1:JSR OSBYTE      :\ Read machine type
 
     TXA:BEQ ResetElk              :\ Jump if &00=Electron
 
     TXA:BEQ ResetElk              :\ Jump if &00=Electron
 +
    LDA #&C0:STA &FEA0            :\ Reset hardware
 
     LDA #&A0:STA &FEE0            :\ Tube Reset
 
     LDA #&A0:STA &FEE0            :\ Tube Reset
 
     LDA #&20:STA &FEE0            :\ Release Tube Reset
 
     LDA #&20:STA &FEE0            :\ Release Tube Reset
Line 51: Line 88:
 
     :
 
     :
 
     .ResetElk
 
     .ResetElk
 +
    LDA #&C0:STA &FCA0            :\ Electron Reset hardware
 
     LDA #&A0:STA &FCE0            :\ Electron Tube Reset
 
     LDA #&A0:STA &FCE0            :\ Electron Tube Reset
 
     LDA #&20:STA &FCE0            :\ Release Electron Tube Reset
 
     LDA #&20:STA &FCE0            :\ Release Electron Tube Reset
     LDA &FFFC:ADC #24:STA &A8     :\ Find RESET+25, note CS from CMP earlier
+
     SEC:LDA &FFFC:ADC #24:STA &A8 :\ Find RESET+25
 
     LDA &FFFD:ADC #0:STA &A9
 
     LDA &FFFD:ADC #0:STA &A9
 
     :
 
     :
 
     \ The following is a copy of the first 22 bytes of the Electron RESET code
 
     \ The following is a copy of the first 22 bytes of the Electron RESET code
 
     LDA #&40:STA &0D00            :\ Set null NMI routine
 
     LDA #&40:STA &0D00            :\ Set null NMI routine
     SEI:CLD:LDX #&FF:TXS           :\ Disable IRQs, set to Binary, clear the stack
+
     SEI:CLD                       :\ Disable IRQs, set to Binary,
     INX:STX &FE00:STX &028D        :\ Reset the ULA, set ResetType=PowerOn
+
    LDX #&FF:TXS                   :\ Clear the stack
 +
     INX:STX &FE00:STX &028D        :\ Reset the ULA, initialise ResetType=0
 
     LDA #&F8:STA LFE05            :\ Set up the ULA
 
     LDA #&F8:STA LFE05            :\ Set up the ULA
 
     :
 
     :
Line 65: Line 104:
 
     LDA #2:JMP (&A8)              :\ A='ULA power on', jump into startup code
 
     LDA #2:JMP (&A8)              :\ A='ULA power on', jump into startup code
  
==Reset 2 - Hard Reset==
+
===Reset 2 - Hard Reset===
 
A Hard Reset is the hardest to cause, as it is caused by a test for the physical
 
A Hard Reset is the hardest to cause, as it is caused by a test for the physical
 
CTRL key being held down. In a similar way to the Electron Power-On Reset the
 
CTRL key being held down. In a similar way to the Electron Power-On Reset the
Line 74: Line 113:
 
underneath the I/O area, so the memory has to be read indirectly.
 
underneath the I/O area, so the memory has to be read indirectly.
  
This code will cause a Hard Reset resulting in OSBYTE 253 being set to 2.
+
This code will cause a Hard Reset resulting in [[OSBYTE &FD]] being set to 2.
  
 
     .ResetHard
 
     .ResetHard
 +
    SEI:CLD                        :\ Disable IRQs, ensure binary mode
 
     LDA #143
 
     LDA #143
 
     LDX #12:LDY #255:JSR OSBYTE    :\ Claim NMIs
 
     LDX #12:LDY #255:JSR OSBYTE    :\ Claim NMIs
 
     LDA #&40:STA &D00              :\ Disable NMIs
 
     LDA #&40:STA &D00              :\ Disable NMIs
     LDA #0:LDX #1:JSR OSBYTE       :\ Read machine type
+
    :
     LDY #0:TXA:BEQ ResetElk       :\ Jump if &00=Electron
+
    LDX #&FF:TXS                  :\ Reset stack
 +
     LDA #0:JSR OSBYTE             :\ Read machine type
 +
     LDA &FFFC:STA &A8              :\ &A8/9=>RESET code
 +
    LDA &FFFD:STA &A9
 +
    TXA:BEQ ResetElk               :\ Jump if &00=Electron
 +
    :
 +
    LDA #&C0:STA &FEA0            :\ Reset hardware
 
     LDA #&A0:STA &FEE0            :\ Tube Reset
 
     LDA #&A0:STA &FEE0            :\ Tube Reset
 
     LDA #&20:STA &FEE0            :\ Release Tube Reset
 
     LDA #&20:STA &FEE0            :\ Release Tube Reset
     LDX #&FF:TXS                  :\ Reset stack
+
     LDY #&0F:STY &FE42            :\ SysVIA PortB=iiiioooo
    LDX #&0F:STX &FE42            :\ SysVIA PortB=iiiioooo
 
 
     .ResetIO
 
     .ResetIO
     DEX:STX &FE40                  :\ Write to I/O latch
+
     DEY:STY &FE40                  :\ Write to I/O latch
     CPX #&09:BCS ResetIO          :\ Loop to set up internal I/O
+
     CPY #&09:BCS ResetIO          :\ Loop to set up internal I/O
     LDA &FFFC:STA &A8              :\ &A8/9=>RESET code
+
     CPX #&03:BCS ResetMaster
    LDA &FFFD:STA &A9
 
    LDA &FFDD
 
    CMP #&5C:BCC ResetMaster
 
    .ResetBBClp
 
    LDA (&A8),Y:INY                :\ Look for 'ROL zp'
 
    CMP #&26:BNE ResetBBClp
 
    TYA:ADC &A8:STA &A8            :\ (A8)=>continuation of reset code
 
    LDA #0:STA &028D              :\ Initialise last BREAK flag
 
    ADC &A9:STA &A9
 
 
     :
 
     :
     \ Read keyboard links
+
     \ Read BBC keyboard links
     LDX #&F6
+
     LDX #&09
 
     .ResetBBCLinks
 
     .ResetBBCLinks
     TXA:PHA
+
     LDY #&03:STY &FE40
     LDY #&FF:JSR OSBYTE            :\ INKEY-10 to INKEY-2
+
     LDY #&7F:STY &FE43
 +
    STX &FE4F:LDX &FE4F
 
     CPX #&80:ROR &FC              :\ Rotate keystate in bit 7 into &FC
 
     CPX #&80:ROR &FC              :\ Rotate keystate in bit 7 into &FC
     PLA:TAX:INX:CPX #&FE
+
     DEX:BNE ResetBBCLinks
     BNE ResetBBCLinks              :\ &FC holds link state, Carry set
+
    ROL &FC                        :\ &FC holds link state
     JMP (&A8)                     :\ CS=CTRL pressed, jump to RESET code
+
    :
 +
    LDY #0
 +
    .ResetBBClp
 +
    LDA (&A8),Y:INY                :\ Look for 'ROL zp'
 +
     CMP #&26:BNE ResetBBClp        :\ Ends with CS
 +
    .ResetJump
 +
    TYA:ADC &A8:STA &A8            :\ Update (&A8) to CS=next or CC=this byte
 +
    LDA #0:STA &028D:STA &FE00    :\ Initialise last BREAK flag and Elk ULA
 +
    ADC &A9:STA &A9                :\ (A8)=>continuation of reset code
 +
     SEC:JMP (&A8)                 :\ CS=CTRL pressed, jump to RESET code
 
     :
 
     :
 
     .ResetElk
 
     .ResetElk
 +
    LDA #&C0:STA &FCA0            :\ Electron Reset hardware
 +
    LDA #&A0:STA &FCE0            :\ Electron Tube Reset
 +
    LDA #&20:STA &FCE0            :\ Release Electron Tube Reset
 +
    LDY #0
 +
    .ResetElkLp
 
     LDA (&A8),Y:INY
 
     LDA (&A8),Y:INY
     CMP #&20:BNE ResetElk          :\ Look for JSR
+
     CMP #&20:BNE ResetElkLp        :\ Look for JSR
 
     INY:INY:LDA (&A8),Y
 
     INY:INY:LDA (&A8),Y
     CMP #&08:BNE ResetElk          :\ Look for PHP
+
     CMP #&08:BNE ResetElkLp        :\ Look for PHP
    STX &FE00:STX &028D            :\ Reset the ULA, set ResetType=0
+
     LDA #&F8:STA LFE05             :\ Set up the ULA, set M=Ctrl Pressed
     LDA #&F8:STA LFE05:PHA        :\ Set up the ULA, set M=Ctrl Pressed, push NotPowerOn
+
    PHA                            :\ Push A<>0 for 'NotPowerOn'
     JMP (&A8)                      :\ CS=CTRL pressed, jump to RESET code
+
     CLC:BCC ResetJump              :\ Branch to jump into reset code
 
     :
 
     :
 
     .ResetMaster
 
     .ResetMaster
 +
    LDY #0
 +
    .ResetMasterLp1
 
     LDA (&A8),Y:INY                :\ Look for JSR
 
     LDA (&A8),Y:INY                :\ Look for JSR
     CMP #&20:BNE ResetMaster
+
     CMP #&20:BNE ResetMasterLp1
 
     INY:INY:LDA (&A8),Y            :\ Check if followed by JMP
 
     INY:INY:LDA (&A8),Y            :\ Check if followed by JMP
     CMP #&4C:BNE ResetMaster
+
     CMP #&4C:BNE ResetMasterLp1
 
     INY:LDA (&A8),Y:STA &F6        :\ (F6)=>reset code in ROM 15
 
     INY:LDA (&A8),Y:STA &F6        :\ (F6)=>reset code in ROM 15
 
     INY:LDA (&A8),Y:STA &F7
 
     INY:LDA (&A8),Y:STA &F7
Line 164: Line 217:
 
     RTS
 
     RTS
  
<!--
+
==Implementation==
===Testing===
+
The three routines can be combined into a single routine that is passed the
 +
[[OSBYTE &FD]] RESET type and selects the appropriate action to perform. This
 +
is done by [[OSBYTE &A3]],&FD implemented by
 +
[http://mdfs.net/Software/BBC/SROM/Tools/ RSTROM]
 +
and the RSTROM's <code>'''*RESET'''</code> command, and by the
 +
[http://mdfs.net/Software/CommandSrc/Utils/ RESET.src]
 +
<code>'''*RESET'''</code> transient command. The routines listed here have been
 +
extracted from RSTROM and RESET.src.
 +
 
 
This code has been tested on:
 
This code has been tested on:
* BBC MOS 1.20
+
* BBC MOS 1.00, 1.20, 1.23, 2.00
* BBC MOS 1.23
+
* Master MOS 3.20, 3.50
* BBC MOS 2.00
+
* Compact MOS 5.00, 5.10, 5.11
* Master MOS 3.20
+
* Electron MOS 1.00, 64K MOS 3.00
* Master MOS 3.50
 
* Compact MOS 5.00
 
* Compact MOS 5.10
 
* Compact MOS 5.11
 
* Electron MOS 1.00
 
* Electron 64K MOS 1.00
 
-->
 
  
===See also===
+
==See also==
 
* [[OSBYTE &FD]]
 
* [[OSBYTE &FD]]
 
* [[OSBYTE &A3]],&FD
 
* [[OSBYTE &A3]],&FD
* [[http://mdfs.net/Software/BBC/SROM/Tools/ RSTROM]] provides OSBYTE 163,253 and *RESET.
+
* [http://mdfs.net/Software/BBC/SROM/Tools/ RSTROM] provides OSBYTE &A3,&FD and <code>'''*RESET'''</code>.
* [[http://mdfs.net/Software/CommandSrc/Utils/ RESET.src]] provides *RESET
+
* [http://mdfs.net/Software/CommandSrc/Utils/ RESET.src] provides <code>'''*RESET'''</code>.
 
 
 
 
 
 
 
 
 
 
Pressing the BREAK key causes a 6502 RESET which jumps via the 6502's RESET
 
vector to the BBC's startup code. Sometimes a program wants to cause a
 
reset to restart the computer.
 
 
 
It is not actually possible to cause a reset without physically pressing the
 
BREAK key or otherwise activating the hardware RESET line. Programs often just
 
jump through the RESET vector to call the startup code, typically with
 
CALL !-4 (or worse, jump directly to the absolute address of the startup code
 
in one particular operating system).
 
 
 
However, this has limitations.
 
 
 
It does not actually reset the computer, as hardware is only reset by the
 
actual hardware RESET line. It leaves hardware in an un-reset state which
 
can cause problems with the startup code that expects to find the hardware
 
already reset by the hardware RESET line.
 
 
 
It hangs second processors as it leaves the two processors out of sync with
 
each other. One has entered its startup code, while the other is still
 
executing its program code.
 
 
 
Also, as the startup code reads the physical state of the CTRL key, just
 
jumping through the RESET vector won't cause a Hard Break unless the user
 
happens to be pressing the CTRL key. A memory-wipe reset can be done by
 
using *FX200,2 or *FX200,3 or a Power-On reset can be performed by resetting
 
the System VIA, but that is more destructive than a Hard Reset as it wipes
 
all memory - not something that may be wanted.
 
 
 
To perform a clean reset, the NMIs must be claimed and the Tube must be reset.
 
  
OSBYTE 253
+
----
Three types, 0, 1, 2
+
[[User:Jgharston|Jgharston]] ([[User talk:Jgharston|talk]]) 02:19, 24 November 2020 (CET)

Latest revision as of 19:24, 22 January 2021

Pressing the BREAK key causes a 6502 RESET which jumps via the 6502's RESET vector to the BBC's startup code. Sometimes a program wants to cause a reset to restart the computer.

It is not actually possible to cause a reset without physically pressing the BREAK key or otherwise activating the hardware RESET line. Programs often just jump through the RESET vector to call the startup code, typically with CALL !-4 (or worse, jump directly to the absolute address of the startup code in one particular operating system).

However, this has limitations.

It does not actually reset the computer, as hardware is only reset by the actual hardware RESET line. It leaves hardware in an un-reset state which can cause problems with the startup code that expects to find the hardware already reset by the hardware RESET line.

It hangs second processors as it leaves the two processors out of sync with each other. One has entered its startup code, while the other is still executing its program code.

Also, as the startup code reads the physical state of the CTRL key, just jumping through the RESET vector won't cause a Hard Break unless the user happens to be pressing the CTRL key. A memory-wipe reset can be done by using *FX200,2 or *FX200,3 or a Power-On reset can be performed by resetting the System VIA, but that is more destructive than a Hard Reset as it wipes all memory - not something that may be wanted.

To perform a clean reset:

  • The NMIs must be claimed and disabled
  • Hardware must be manually reset
  • The Tube must be reset
  • Any startup state needs to be set up
  • The appropriate part of the MOS RESET code needs to be entered

Reset routines

The following routines will generate a machine reset of the three types defined by OSBYTE &FD. Note that this code has to run in the I/O processor.

Reset 0 - Soft Reset

A Soft Reset is the simplest to perform. Claim the NMIs, reset the Tube and enter the RESET code. This code will cause a Soft Reset resulting in OSBYTE &FD being set to 0.

   .ResetSoft
   LDA #143
   LDX #12:LDY #255:JSR OSBYTE    :\ Claim NMIs
   LDA #&40:STA &D00              :\ Disable NMIs
   LDA #0:LDX #1:JSR OSBYTE       :\ Read machine type
   TXA:BEQ ResetElk               :\ Jump if &00=Electron
   LDA #&C0:STA &FEA0             :\ Reset hardware
   LDA #&A0:STA &FEE0             :\ Tube Reset
   LDA #&20:STA &FEE0             :\ Release Tube Reset
   JMP (&FFFC)                    :\ Jump to RESET
   :
   .ResetElk
   LDA #&C0:STA &FCA0             :\ Electron Reset hardware
   LDA #&A0:STA &FCE0             :\ Electron Tube Reset
   LDA #&20:STA &FCE0             :\ Release Electron Tube Reset
   JMP (&FFFC)                    :\ Jump to RESET

Reset 1 - PowerOn Reset

A Power-On Reset is only slightly different. Normally, the MOS checks the System VIA interupt bit to test if a RESET is from a power on, so the VIA is reset into a Power-On state.

However, the Electron does not have a System VIA, there is a flag in the System ULA that indicates a power-on state. This causes a problem as this flag read-only, so the only way to cause a Power-On Reset is to do the initial RESET code manually and jump to the rest of it as though the ULA power-on bit has been read.

This code will cause a Power-On Reset resulting in OSBYTE &FD being set to 1.

   .ResetPowerOn
   LDA #143
   LDX #12:LDY #255:JSR OSBYTE    :\ Claim NMIs
   LDA #&40:STA &D00              :\ Disable NMIs
   LDA #0:LDX #1:JSR OSBYTE       :\ Read machine type
   TXA:BEQ ResetElk               :\ Jump if &00=Electron
   LDA #&C0:STA &FEA0             :\ Reset hardware
   LDA #&A0:STA &FEE0             :\ Tube Reset
   LDA #&20:STA &FEE0             :\ Release Tube Reset
   LDA #&7F:STA &FE4E:JMP (&FFFC) :\ Turn off SysVIA, jump to RESET
   :
   .ResetElk
   LDA #&C0:STA &FCA0             :\ Electron Reset hardware
   LDA #&A0:STA &FCE0             :\ Electron Tube Reset
   LDA #&20:STA &FCE0             :\ Release Electron Tube Reset
   SEC:LDA &FFFC:ADC #24:STA &A8  :\ Find RESET+25
   LDA &FFFD:ADC #0:STA &A9
   :
   \ The following is a copy of the first 22 bytes of the Electron RESET code
   LDA #&40:STA &0D00             :\ Set null NMI routine
   SEI:CLD                        :\ Disable IRQs, set to Binary,
   LDX #&FF:TXS                   :\ Clear the stack
   INX:STX &FE00:STX &028D        :\ Reset the ULA, initialise ResetType=0
   LDA #&F8:STA LFE05             :\ Set up the ULA
   :
   \ Now fake that the ULA is in power-on state
   LDA #2:JMP (&A8)               :\ A='ULA power on', jump into startup code

Reset 2 - Hard Reset

A Hard Reset is the hardest to cause, as it is caused by a test for the physical CTRL key being held down. In a similar way to the Electron Power-On Reset the RESET code has to be threaded through until the CTRL key test, and then entered there in a state as though the CTRL key has been read.

Additional problems are that the Master RESET code is in a sideways ROM and hidden underneath the I/O area, so the memory has to be read indirectly.

This code will cause a Hard Reset resulting in OSBYTE &FD being set to 2.

   .ResetHard
   SEI:CLD                        :\ Disable IRQs, ensure binary mode
   LDA #143
   LDX #12:LDY #255:JSR OSBYTE    :\ Claim NMIs
   LDA #&40:STA &D00              :\ Disable NMIs
   :
   LDX #&FF:TXS                   :\ Reset stack
   LDA #0:JSR OSBYTE              :\ Read machine type
   LDA &FFFC:STA &A8              :\ &A8/9=>RESET code
   LDA &FFFD:STA &A9
   TXA:BEQ ResetElk               :\ Jump if &00=Electron
   :
   LDA #&C0:STA &FEA0             :\ Reset hardware
   LDA #&A0:STA &FEE0             :\ Tube Reset
   LDA #&20:STA &FEE0             :\ Release Tube Reset
   LDY #&0F:STY &FE42             :\ SysVIA PortB=iiiioooo
   .ResetIO
   DEY:STY &FE40                  :\ Write to I/O latch
   CPY #&09:BCS ResetIO           :\ Loop to set up internal I/O
   CPX #&03:BCS ResetMaster
   :
   \ Read BBC keyboard links
   LDX #&09
   .ResetBBCLinks
   LDY #&03:STY &FE40
   LDY #&7F:STY &FE43
   STX &FE4F:LDX &FE4F
   CPX #&80:ROR &FC               :\ Rotate keystate in bit 7 into &FC
   DEX:BNE ResetBBCLinks
   ROL &FC                        :\ &FC holds link state
   :
   LDY #0
   .ResetBBClp
   LDA (&A8),Y:INY                :\ Look for 'ROL zp'
   CMP #&26:BNE ResetBBClp        :\ Ends with CS
   .ResetJump
   TYA:ADC &A8:STA &A8            :\ Update (&A8) to CS=next or CC=this byte
   LDA #0:STA &028D:STA &FE00     :\ Initialise last BREAK flag and Elk ULA
   ADC &A9:STA &A9                :\ (A8)=>continuation of reset code
   SEC:JMP (&A8)                  :\ CS=CTRL pressed, jump to RESET code
   :
   .ResetElk
   LDA #&C0:STA &FCA0             :\ Electron Reset hardware
   LDA #&A0:STA &FCE0             :\ Electron Tube Reset
   LDA #&20:STA &FCE0             :\ Release Electron Tube Reset
   LDY #0
   .ResetElkLp
   LDA (&A8),Y:INY
   CMP #&20:BNE ResetElkLp        :\ Look for JSR
   INY:INY:LDA (&A8),Y
   CMP #&08:BNE ResetElkLp        :\ Look for PHP
   LDA #&F8:STA LFE05             :\ Set up the ULA, set M=Ctrl Pressed
   PHA                            :\ Push A<>0 for 'NotPowerOn'
   CLC:BCC ResetJump              :\ Branch to jump into reset code
   :
   .ResetMaster
   LDY #0
   .ResetMasterLp1
   LDA (&A8),Y:INY                :\ Look for JSR
   CMP #&20:BNE ResetMasterLp1
   INY:INY:LDA (&A8),Y            :\ Check if followed by JMP
   CMP #&4C:BNE ResetMasterLp1
   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
   CMP #&E0:BNE ResetMasterLp2    :\ Look for 'CPX'
   JSR ResetROMByte               :\ Read next byte from ROM 15
   CMP #&80:BNE ResetMasterLp2    :\ Look for 'CPX #&80'
   \ &F6/7 now points to rest of RESET code
   :
   LDA #&53:STA &FE8E             :\ Write to hardware I/O RESET
   TRB &0366                      :\ Reset VDU 23,16 settings
   LDX #&FF:STX &FE63             :\ User VIA Port A=output
   LDA #&CF:STA &FE42             :\ System VIA Port B=ooiioooo
   LDA #&0D:STA &DC00             :\ Command line = <cr>
   LDA #&DC:STA &DF05             :\ Point to command line
   STZ &DF04
   STZ &DFDD
   LDX #(ResetCodeEnd-ResetCode-1) AND &FF
   .ResetLoop
   LDA ResetCode,X:STA &100,X
   DEX:BPL ResetLoop
   LDA &F7:AND #&40               :\ Test if code is in SROM or I/O area
   STA &FE34:STA &FC              :\ Set memory map according to &F7
   LDA #&0F:STA &028E             :\ Set keypad SHIFT setting, prepare ROM=15
   PHA:SEC:JMP &100               :\ <>0=Not PowerOn, CS=CTRL pressed
   :
   .ResetCode
   STA &FE30                      :\ Page in MOS ROM (IRQs are off)
   JMP (&F6)                      :\ Jump to RESET code
   .ResetCodeEnd
   :
   .ResetROMByte
   LDA #&40:STA &FE34             :\ Set memory map
   LDA (&F6)                      :\ Read byte manually
   BIT &F7:BVS ResetByte          :\ Exit if in high memory
   LDY #&0F:JSR &FFB9             :\ Read byte from ROM 15
   .ResetByte
   INC &F6:BNE P%+4:INC &F7       :\ Increment address
   RTS

Implementation

The three routines can be combined into a single routine that is passed the OSBYTE &FD RESET type and selects the appropriate action to perform. This is done by OSBYTE &A3,&FD implemented by RSTROM and the RSTROM's *RESET command, and by the RESET.src *RESET transient command. The routines listed here have been extracted from RSTROM and RESET.src.

This code has been tested on:

  • BBC MOS 1.00, 1.20, 1.23, 2.00
  • Master MOS 3.20, 3.50
  • Compact MOS 5.00, 5.10, 5.11
  • Electron MOS 1.00, 64K MOS 3.00

See also


Jgharston (talk) 02:19, 24 November 2020 (CET)