       SUBT     Useful procedure entry/exit macros => &.Hdr.Proc

OldOpt SETA     {OPT}
       OPT      OptNoList+OptNoP1List

       GBLS     Proc_RegList    ; Which registers to preserve
       GBLA     Proc_LocalStack ; And any ADJSP on entry/exit for local vars

       GBLL     Proc_Debug      ; Whether to dump procedure name in image
Proc_Debug SETL False

; *****************************************************************************
; *** Keep a note of local stack and register use at the routine entry      ***
; *** point so that an exit may be effected anywhere in the body without    ***
; *** remembering how many (and which) registers to destack and ADJSP.      ***
; *** Also ensures that the code entry label is word-aligned.               ***
; *****************************************************************************
        MACRO
$label  ENTRY   $reglist,$framesize
        ALIGN
Proc_RegList SETS "$reglist"
 [ "$framesize" = ""
Proc_LocalStack SETA 0
 |
Proc_LocalStack SETA $framesize
 ]
 [ "$label" <> ""
  [ Proc_Debug
        B       $label
        DCB     "$label", 0
        ALIGN
  ]
$label  ROUT
 ]
 [ "$Proc_RegList" = ""
        Push    lr
 |
        Push    "$Proc_RegList, lr"
 ]
 [ Proc_LocalStack <> 0
        SUB     sp, sp, #Proc_LocalStack
 ]
        MEND

; *****************************************************************************
; *** Another entry point so we can use the same routine body. NOROUT also  ***
; *** Stacks the same registers as does the corresponding ENTRY macro       ***
; *****************************************************************************
        MACRO
$label  ALTENTRY
        ALIGN
 [ "$label" <> ""
  [ Proc_Debug
        B       $label
        DCB     "$label", 0
        ALIGN
  ]
$label ; NOROUT
 ]
 [ "$Proc_RegList" = ""
        Push    lr
 |
        Push    "$Proc_RegList, lr"
 ]
 [ Proc_LocalStack <> 0
        SUB     sp, sp, #Proc_LocalStack
 ]
        MEND

; *****************************************************************************
; *** Exit procedure, restore stack and saved registers to values on entry  ***
; *****************************************************************************
        MACRO
$label  EXIT    $cond
$label
 [ Proc_LocalStack <> 0
        ADD$cond sp, sp, #Proc_LocalStack
 ]
 [ "$Proc_RegList" = ""
        Pull    pc,$cond
 |
        Pull    "$Proc_RegList, pc",$cond
 ]
        MEND

; *****************************************************************************
; *** Exit procedure : restore stack and saved registers + psr to values on ***
; *** entry. No longer copes with 3um ARM bug fix (world is 2um'ised)       ***
; *****************************************************************************
        MACRO
$label  EXITS   $cond
$label
 [ Proc_LocalStack <> 0
        ADD$cond sp, sp, #Proc_LocalStack
 ]
 [ "$Proc_RegList" = ""
        Pull    pc,$cond,^
 |
        Pull    "$Proc_RegList, pc",$cond,^
 ]
        MEND

; *****************************************************************************
; *** Restore stack and saved registers, lr to values on entry to procedure ***
; *****************************************************************************
        MACRO
$label  PullEnv $cond
$label
 [ Proc_LocalStack <> 0
        ADD$cond sp, sp, #Proc_LocalStack
 ]
 [ "$Proc_RegList" = ""
        Pull    lr, $cond
 |
        Pull    "$Proc_RegList, lr", $cond
 ]
        MEND

; *****************************************************************************

        OPT     OldOpt
        END
