アトメルのAVRマイコン用アセンブラ・
AVRASMに関するトラブル

2004-07-08

 もう、ずいぶん前の話しになるのですが、アトメルのAVRマイコンを
使いだしてすぐのころ(2001年くらい)、アトメルが提供するMS−
DOS版のアセンブラ「AVRASM」のバグに遭遇しました。

 すでに「トランジスタ技術」2002年6月号の166ページに
「アセンブラがディスクを破壊する!」
という内容でレポートしておりますが、あらためて現象と対策を示しておきたい
とおもいます。

トラブルが発生するのは、
 「AVRASM  EXE    106,578 99-01-27  1:30」
 「AVRASM: AVR macro assembler version 1.30 (Jan 27 1999 01:30:00)
  Copyright (C) 1995-1999 ATMEL Corporation」
です。
 トラ技・2000年7月号付属のCD−ROMの中にも入っていたAVR
マイコン用の開発ツールです。

 アトメルが提供する開発環境、現在はウインドウズに移行しておりMS-DOS版
のは捨てられているような状態です。
しかし、軽い・早い・こけないというMS-DOSの環境は捨てがたいものがあり、
私自身、いまだに愛用しております。


※症状

 エラーのあるアセンブラソースをアセンブルすると、アセンブル完了と
ともに、MS−DOSのディスク構造がおかしくなってしまいます。
 直後に、そのドライブに対し「CHKDSK」をかけると、
「 1 個の破損アロケーションユニットが 1 チェインに見つかりました.」
となってしまいます。
そして、エラーの出るソースを続けてアセンブルすると、1個が2個にと
どんどん増えていきます。
エラーのないソースをアセンブルする限りは、この現象は出ません。
例えば、こんな具合です。

  G:\>AVRASM LED1.ASM LED1.LST LED1.HEX
  AVRASM: AVR macro assembler version 1.30 (Jan 27 1999 01:30:00)
  Copyright (C) 1995-1999 ATMEL Corporation

  Creating  'LED1.eep'
  Creating  'LED1.HEX'
  Creating  'LED1.obj'
  Creating  'LED1.LST'

  Assembling 'LED1.ASM'
  Including '1200def.inc'
  LED1.ASM(226) : error : Undefined variable referenced

  Assembly complete with 1 error  <−・・・・・・・エラーあり

  Deleting  'LED1.eep'
  Deleting  'LED1.obj'
  Deleting  'LED1.HEX'

  G:\>chkdsk <−・・・・・・・すぐCHKDSKしてみる

  ボリューム DISK_G  は 2001-08-22 16:48 に作成されました.
  エラーがありました. F パラメータが指定されていないので,
  ディスクは修復されません.

    1 個の破損アロケーションユニットが 1 チェインに見つかりました.
      2,048 バイトのディスク領域が空きます.
        :
        :

 「CHKDSK /F」でできあがる「FILE0000.CHK」ファイルを見ると、
そのファイルの先頭に、
:060000000921240612187C
:00000001FF
  :
てなコード(エラーの出るアセンブラソース内で指定したEEPROMデータ)
が必ず入っているので「.EEP」ファイルのオープン、クローズ、デリート
あたりに失敗しているのかなと推測できます。
 試しに、ソース内でEEPROMデータを指定している部分を抜いてやると
この不具合は起きなくなります。
 いやはや、エラーのあるソースをアセンブルするとディスクにエラーが起きる
というなかなか強烈な「仕様」です。


※対策

 ファイルをクローズしないままファイルを消去しているのではないかと
推測して、ファイル消去を行なっている場所を探してみました。
 実行ファイルの先頭からのオフセット2804(16進)に「ファイルの消去」
を行なっているMS-DOSのシステムコール「INT 21H」が見つかります。
このシステムコール「INT 21H」を消してしまおうということで対策します。
 「INT 21H」を「CLC NOP」の2命令に置き換えて、ファイルの消去
が実行されないようにします。
これで「.EEP」ファイルに対する、アセンブルエラー時の不正な処理手順
(クローズする前に消す)がなくなって、FATの破壊がおきなくなります。
 ただしこのことにより、AVRASMが作っている一時ファイルが消されなく
なってしまい、アセンブル終了後に「UASM.TMP」と「MACROS.TMP」という
2つのファイルができたままになってしまいます。
それと「.OBJ」というファイルも残ってしまいます。
 FATがつぶれるよりマシということで、とりあえずDOS版のAVRASMを使い続
けることができます。


※パッチの手順

 バイナリエディタを使ってもかまいませんが、MS-DOSの標準ツールであります
SYMDEB.EXEを使ってのパッチあてを説明します。

(1)「AVRASM.EXE」をリネーム

     SYMDEBでバイナリーイメージとしてロードするため、「.EXE」から
    「.BIN」にリネームします。
    その前に、オリジナルを保存しておきましょう。

    C:\>COPY AVRASM.EXE AVR_ORG.EXE ・・・・名前を変えて保存。
    C:\>REN AVRASM.EXE A1.BIN    ・・・・仮にA1.BINとします。

(2)SYMDEBでロード (IBM-PCではDEBUGですね)

    ファイルはメモリーの0100Hからロードされます。

    C:\>SYMDEB A1.BIN        ・・・・A1.BINをロード
    Microsoft Symbolic Debug Utility
    Version 3.01
    (C)Copyright Microsoft Corp 1984, 1985
    Processor is [80286]
    -U 2904             ・・・・0100Hを+して逆アセンブル
    1C62:2904 CD21      INT  21   これがそのシステムコール
    1C62:2906 1F       POP  DS
    1C62:2907 7204      JB   290D
    1C62:2909 33C0      XOR  AX,AX
    1C62:290B EB04      JMP  2911
    1C62:290D 50       PUSH  AX
    1C62:290E E806FF     CALL  2817
    1C62:2911 5F       POP  DI
    -A2904
    1C62:2904 CLC          ・・・・実行しないようにパッチあて
    1C62:2905 NOP
    1C62:2906 .
    -U2904
    1C62:2904 F8       CLC     ・・・パッチ確認
    1C62:2905 90       NOP  
    1C62:2906 1F       POP  DS
    1C62:2907 7204      JB   290D
    1C62:2909 33C0      XOR  AX,AX
    1C62:290B EB04      JMP  2911
    1C62:290D 50       PUSH  AX
    1C62:290E E806FF     CALL  2817
    -W               ・・・・ファイルに書き戻し
    Writing 1A052 bytes
    -Q               ・・・・終了

(3)「.EXE」に戻す

    C:\>REN A1.BIN AVRASM.EXE    ・・・・AVRASM.EXEにリネーム

(4)パッチあての確認

    C:\>FC AVRASM.EXE AVR_ORG.EXE  ・・・・ファイルをコンペア

    00002804: F8 CD
    00002805: 90 21
         ↑ ↑
         新 旧


 なお、EEPROMエリアの指定をしていない場合は、エラーがあってもこのトラ
ブルは出ません。
EEPROMエリアのデータをソースファイルで指定している場合が問題なのです。

 まぁ、ウィンドウズ版のアセンブラを使ったらという声が聞こえてき
そうですが、ほんのちっぽけなマイコンプログラムに対してウィンドウズ
パソコンを持ち出してくるのは、「鰯を料理するのにごっつい出刃包丁を
持ち出してくる」ような気がしまして、あまり好きではありません。

※AVRXSのPC-9801対応

 AVRマイコンのインサーキット書き込みには、「chanさん」作の「AVRXS.COM」を
利用させていただいています。
 パソコンのプリンターポートで制御するAVRマイコンの書き込みツールです。
ただ・・・、私のわがままで、いまだにPC-9801を使いたい・・・ということで、
AVRXSのソースをいじらしてもらい、PC-9801のプリンタポートでも書き込みで
きるようにして便利に使っています。
 ・プリンタポートのアドレスを変更。
 ・BUSY入力ビット位置の変更。
 ・タイマー待ちルーチンの変更。
 ・ケーブル接続チェックルーチンの固定化。
の4点を処理すれば、DOS/Vマシンだけでなく、PC-9801でも使えるように
改造できます。

PC-9801対応AVRXSの改造方法の紹介、必要ですか?
いまだにPC-9801を使っている人って、少ないだろうな〜。
リクエストがあれば、紹介したいと思います。