I'm trying to write a TSR (Terminate and Stay Resident) program in DOS. I have an old machine running real DOS 6.2 mostly for nostalgic purposes that I'd like to write my own slowdown utility for.
My first step was to simply try use some example code to see if I could assemble and run a TSR, then try adapt that as I haven't written a TSR before.

The problem is that it simply locks up the system, locking the keyboard and the display simply prints the prompt after execution with apparently no control returned to DOS, or maybe it does return but has somehow mangled the system otherwise.

I don't remember where I got the code from, but the code is not mine, and I do not understand the "clean up the stack" part below the "Do something here" comment. I have tried to replace the entire "new" interrupt with a mere ret instruction, but the result was still a lock up.
Of interest is perhaps that I tried to change the interrupt hooked from the system timer to the keyboard (16h), and that yielded that the prompt was printed ad inf. with no control whatsoever of the keyboard, as if the enter key was pressed continuously by the user.

What is wrong with this program? I really am having a hard time trying to find some example code in assembly for a TSR in DOS. If anyone knows of some assembly code that works (or even if you don't know whether it works or not) please let me know where to find it.

Code:
.model tiny
.186
.code
           org  100h
start:     jmp  short Install

olddosint  dw 00h,00h

newDOSInt:
           pushf                        ; create our own descriptor
           push cs                      ;   (could be a  call far  instead)
           push offset Back             ;
           jmp  far cs:olddosint        ; jmp to old interrupt handler

Back:      
           pushf                        ; save flags returned by orig int 21h

; Do something here.
        
           cli                          ; clean up the stack
           push ax                      ; so that it will ret to the
           push bp                      ; correct place
           mov  bp,sp                   ; 
           mov  ax,[bp-6]               ;
           mov  [bp-8],ax               ;
           mov  ax,[bp-4]               ;
           mov  [bp-6],ax               ;
           pop  bp                      ;
           pop  ax                      ;
           popf                         ; restore flags ret'd by orig 21h
           sti                          ;
           retf 2                       ;

Install:   
           mov  ax,3508h                ; Save old interrupt vector 21h
           int  21h

           mov  [olddosint],bx
           mov  [olddosint+2],es

           push cs
           pop  ds
           mov  dx,offset cs:newdosint  ; set new interrupt vector 21h
           mov  ax,2508h                ; to newdosint
           int  21h

           mov  es,cs:[002Ch]           ; free environment block
           mov  ah,49h
           int  21h

           mov  dx,offset cs:Install     ; get paragraphs needed
           sub  dx,offset cs:Start
           shr  dx,04
           add  dx,17                   ; add 16 paras for PSP + 1 extra
           mov  ax,3100h                ; termination and stay resident
           int  21h

.end       start