2012-03-11 1 views
0

私はTSR(DOS 16BIT)をコード化しようとしていますが、INT8のすべてのティックがアスタリスクを画面の周りに移動します。私はそれぞれの画面の境界線に対応する '*'位置の異なるインクリメントを持つ4つのサブルーチンを持っています。しかし、コードはハングアップし、割り込みに依存するので、デバッガで一度に実行することもできません。解決策を提案してください。DOS INT 8の動くアスタリスクが動かない

pos:  dw  158,3998,3838,0 
routine: dw  subrt1,subrt2,subrt3,subrt4 

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 

      mov ax,0xb800 
      mov es,ax 

      mov word[es:di],0x720 
      call [routine+bx]   
      mov word[es:di],0x742 

      mov al,0x20 
      out 0x20,al 
      pop ax 
      iret 

start:  xor ax,ax 
      xor bx,bx 
      mov es,ax 
      cli 
      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 
+0

コードを記述しようとしているプラ​​ットフォームを忘れないでください。しかしここで最も明白な問題は、私が見る限り、元のint 8hハンドラを連鎖していないということです。独自のコードを実行する前に、元の8hハンドラにチェーンする必要があります。 –

+1

TSR?あなたは1980年代初めにワームホールを通って落ちましたか? –

+0

私は第三世界の国出身です。あなたの質問に答える希望もありますが、私にも答えてください:) –

答えて

3

これは、レジスタの状態を正確に保存することに関する問題を解決する方法です。コメントを参照してください。

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 
+0

コードをコピーして貼り付ける間に誤植が導入されてしまって、ごめんなさい。その3838 –

1

私はTSRの専門家ではありませんが、ここではいくつかの問題があります。

まず、私はJames Youngmanのコメントに同意します。元の割り込みハンドラをどこにチェーンしているのかわかりません。あなたのフォローアップのコメントで引用したコードは、既存の割り込みハンドラを安全に置き換えるコードです(置き換え中の割り込みを無効にして競合状態はありません)。それでは十分じゃない。そのハンドラのセグメント:アドレスを保存し、ハンドラの終了時にハンドラを呼び出す必要があります。

第2に、私のコメントで示したように、私はその3T838値がposで理解できず、アセンブラがそれをどのように処理できるか理解していません。しかし、私は何かが欠けているかもしれません。

第3に、ハンドラを入力するときにコンテキストを予測できません。 bx( "call [routine + bx]")に基づいて分岐していますが、bxは "timer:"ラベルとその呼び出し命令の間に設定されていません。確かに、bxはここで何でもかまいません。 bxが割り込みから割り込みまで実行中の値になることを期待している場合は、その値を別の変数に保持し、その変数をハンドラの開始時にbxに移動し、退出前に退避する必要があります。これはdiレジスタのためにも行われますが、コードではどこでものように初期化されていません。

第4に、int 21h/ah = 31hに渡すパラメータについて完全には自信がありません。私が見つけることができるドキュメントは、dxがプログラムが使用する段落の数に設定されていることを示しています。あなたは "start:"のアドレスを読み込み、それに16を掛けます(実際に段落のサイズです)。これについてのドキュメントをもう一度確認したいかもしれません。私はここに何が来なければならないのか分からない。

幸運。私は、TSRを書くことは、彼らが普段の時代であっても、挑戦的な偉業であると理解しています。

関連する問題