  .MACRO $MESSL MESS, TEXT
    .EMITL <MESS>
    .EMIT <.ASCII TEXT>
    .EMIT <'MESS'.L =: .-'MESS'>
  .ENDM $MESSL

  .MACRO $SHMESS MESS
    .EMIT <MOV  #MESS,R0>
    .EMIT <MOV  #'MESS'.L,R4>
    .EMIT <CALL SHSTR>
  .ENDM $SHMESS

  .MACRO $ERMSC MESS, ?L
L:
    .EMIT <.ASCII MESS>
    .IIF NE .-L-ERMC.L .ERROR ; Message length must be ERMT.L chars!
  .ENDM $ERMSC    

  .MACRO $ERMST CODE, MESS, ?L
    ER.NUM=ER.NUM+1
    CODE=ER.NUM
L:
    .EMIT <.ASCII MESS>
    .IIF NE .-L-ERMT.L .ERROR ; Message length must be ERMT.L chars!
  .ENDM $ERMST

  ER.NUM = 0

  .MACRO DV.BOT NAME, CSR, BOOT, PARAM
    .EMIT <.ASCII ^NAME^>	; Name
    .EMIT <.WORD  CSR>		; CSR
    .EMIT <.WORD  BOOT>		; Entry point
    .EMIT <.WORD  PARAM>	; ??
  .ENDM DV.BOT

  .MACRO DV.END
    .EMIT <.WORD 0>
  .ENDM DV.END

  ERMC.L =: ^D<18>		;        
  ERMT.L =: ^D<32>		;      

...............................................................................

  .MACRO HMCALL
    MOV  #112345, R0
    MOV  #123456, R1
    MOV  #134567, R2
    MOV  #145671, R3
    MOV  #156712, R4
    MOV  #167123, R5
    HALT
    BR   .
    BR   .
  .ENDM HMCALL

  .MACRO HMRETURN
    MOV @#SP.SAV, SP
    MOV @#SU.PSW, @#U.PSW
    MOV @#SU.PC, @#U.PC
    RTT
  .ENDM HMRETURN

  .MACRO .MESS TEXT, ?L1, ?L2
    .EMITL <L1>
    .EMIT  <.=.+1>

    .EMIT  <.ASCII TEXT>
    .EMITL <L2>

    .EMIT  <.=L1>
    .EMIT <.BYTE L2-L1-1>
    .EMIT  <.=L2>
  .ENDM .MESS

  .MACRO .SHMESS MESS
    .EMIT <MOV  PC,R0>
    .EMIT <ADD  #MESS-.,R0>
    .EMIT <CALL SHSTR>
  .ENDM .SHMESS
