Это то, как вы исправляете свои проблемы, которые в основном связаны с правильным сохранением состояния реестра.Смотрите комментарии.
org 0x100 ;; missing?
jmp start ;; missing?
pos: dw 158,3998,3840,0 ;; what is 3T838?
routine: dw subrt1,subrt2,subrt3,subrt4
state dw 0 ;; storage for bx
curpos dw 0 ;; storage for di
oldisr dd 0 ;; address of old timer interrupt ISR
subrt1:
add di,2
cmp di,[pos]
jnz exit
add bx,2
exit: ret
subrt2: add di,160
cmp di,[pos+2]
jnz exit
add bx,2
ret
subrt3: sub di,2
cmp di,[pos+4]
jnz exit
add bx,2
ret
subrt4: sub di,160
cmp di,[pos+6]
jnz exit
mov bx,0
ret
timer: push ax
push bx ;; must preserve bx
push di ;; must preserve di
push ds ;; must preserve ds
push es ;; must preserve es
push cs ;; must load cs into ds to access pos,routine,state,curpos
pop ds
mov ax,0xb800
mov es,ax
mov di, [curpos] ;; must retrieve di from storage
mov bx, [state] ;; must retrieve bx from storage
mov word[es:di],0x720
call [routine+bx]
mov word[es:di],0x72A ;; you need 42 decimal (2A hex), not 42 hex
mov [curpos], di ;; must preserve di between ints
mov [state], bx ;; must preserve bx between ints
;mov al,0x20 ;; remove int acknowledge as the old ISR will do it for us
;out 0x20,al
pop es ;; must restore es
pop ds ;; must restore ds
pop di ;; must restore di
pop bx ;; must restore bx
pop ax
;iret ;; instead of direct iret continue in the old ISR
jmp far [cs:oldisr] ;; to prevent undesired effects (hangs/crashes)
start: xor ax,ax
; xor bx,bx ;; unnecessary
mov es,ax
cli
push word[es:8*4] ;; remember old ISR address
push word[es:8*4+2]
pop word[oldisr+2]
pop word[oldisr]
mov word[es:8*4],timer
mov word[es:8*4+2],cs
sti
mov dx,start
add dx,15
mov cl,4
shr dx,cl
mov ax,0x3100
int 0x21