;**********************************************************; ;* Self High-Loading TSR Program -- 32 bytes resident!! *; ;* By Tenie Remmel *; ;**********************************************************; Ideal Model Tiny P186 Codeseg Org 100h Proc Prog mov dx,offset RName ;Only leaves 32 bytes! mov si,offset RName ;also name offset mov cx,0 ;No int. vectors jmp TSRHi ;TSR procedure RName db 'Test',0 ;This is the resident name EndP Prog Proc TSRHi ;Registers on entry: ; ; DX = last byte of program ; CS = segment of program ; CS:SI = resident name (8 bytes) ; CX = Number of vectors to set ; CS:BX = Vector list ; ; Vector list format: ... ; -word- -byte- pusha ;Save all registers push cs ;DS = CS pop ds mov ah,4Ah ;Reallocate Memory mov bx,1000h ;BX = 64K push cs ;ES = code segment pop es int 21h ;DOS services mov ah,49h ;Free memory mov es,[2Ch] ;Environment block int 21h ;DOS services mov ax,5800h ;Get Alloc. Strategy int 21h ;DOS services push ax ;Save value mov ax,5802h ;Get UMB Link int 21h ;DOS services push ax ;Save value mov ax,5803h ;Set UMB Link mov bx,1 ;1 = Link ON int 21h ;DOS services mov ax,5801h ;Set Alloc. Strategy mov bx,82h ;Last Fit, UMBs First int 21h ;DOS services mov ah,48h ;Allocate Memory mov bx,dx ;BX = last byte sub bx,0F1h ;BX - 100h + 0Fh shr bx,4 ;BX = size in paras int 21h ;DOS services jc _NoMem ;Jump if error dec ax ;AX = MCB seg. mov es,ax ;ES = AX inc ax ;AX = memory block mov [es:1],ax ;Set owner to itself mov di,8 ;Move name to MCB:8 mov cx,4 ;8 bytes = 4 words rep movsw ;Move by words mov ax,5803h ;Set UMB Link pop bx ;to old value int 21h ;DOS services mov ax,5801h ;Set Alloc. Strategy pop bx ;to old value xor bh,bh int 21h ;DOS services mov ax,es ;AX = new CS segment sub ax,0Fh mov es,ax ;ES = AX popa ;Restore original regs mov si,100h ;SI = 100h mov di,si ;DI = 100h push cx ;Save CX mov cx,dx ;CX = last byte sub cx,100h ;CX = length rep movsb ;Move data pop cx ;Restore CX jcxz _NoVects ;No vectors to set? mov ah,25h ;Set Interrupt Vector push es ;DS = ES pop ds _SetIVect: lodsw ;Load offset mov dx,ax ;into DX lodsb ;Load int. number int 21h ;Set vector loop _SetIVect ;Loop back _NoVects: mov ax,4C00h ;Return with code 0 int 21h ;DOS services _NoMem: mov ax,5803h ;Set UMB Link pop bx ;to old value int 21h ;DOS services mov ax,5801h ;Set Alloc. Strategy pop bx ;to old value xor bh,bh int 21h ;DOS services mov ax,cs ;ES = MCB segment dec ax mov es,ax mov di,8 ;Move name to MCB:8 mov cx,4 ;8 bytes = 4 words rep movsw ;Move by words popa ;Restore original regs push dx ;Save DX jcxz _NoVects1 ;No vectors to set? mov ah,25h ;Set Interrupt Vector _SetIVect1: lodsw ;Load offset mov dx,ax ;into DX lodsb ;Load int. number int 21h ;Set vector loop _SetIVect1 ;Loop back _NoVects1: mov ax,3100h ;TSR service, code 0 pop dx ;Restore DX add dx,0Fh ;DX = size in paras, shr dx,4 ;rounded up int 21h ;DOS services EndP TSRHi End Prog